live_recorder/README.md

9.6 KiB
Raw Permalink Blame History

Live Recorder

Live Recorder 是一个多平台直播录制系统,支持自动检测开播、实时录制、弹幕采集、通知推送与事件脚本编排。

  • 后端:.NET 8 Web API + EF Core + SQLite
  • 前端:Vue 3 + TypeScript + Element Plus

当前已适配 抖音DouyinBilibili(部分),架构将平台特有逻辑隔离在 Platforms 目录下,新增虎牙、斗鱼、快手等平台无需改动应用层服务。

目录结构

.
├─ src
│  ├─ LiveRecorder.Domain          # 实体与枚举
│  ├─ LiveRecorder.Application     # 接口、DTO、应用服务
│  ├─ LiveRecorder.Infrastructure  # 持久层、平台适配器、后台服务
│  └─ LiveRecorder.WebApi          # REST API 与中间件
├─ frontend                        # Vue 3 SPA
│  └─ src
│     ├─ api / components / composables / router / stores / styles / views
├─ docker-compose.yml
├─ Jenkinsfile
└─ README.md

核心功能

直播录制

  • 支持分享链接与短链解析,自动提取真实房间号
  • 后台轮询检测直播状态,可配置轮询间隔与自动录制开关
  • 支持 MP4(单文件)与 TS(分段)两种输出格式
  • 内置三种录制模板:StreamCopyBalancedMp4ArchiveTs
  • 断线重连:可配置重连开关、最大重连延迟、读写超时
  • 存储守护:启动前检查磁盘剩余空间,不足时拒绝录制

弹幕采集

弹幕通过 WebSocket 实时连接各平台的弹幕服务器,以 XML 格式分段写入文件。

  • 抖音弹幕:通过 webcast/im/fetch/ 获取连接信息,建立 WSS 长连接,使用 a_bogus 签名算法(基于 dycast 开源项目的 abogus.js),支持 Protobuf 解码
  • Bilibili 弹幕:通过 Bilibili 直播 WebSocket 协议连接弹幕服务器,支持聊天、进入、关注、礼物等事件
  • 弹幕事件类型聊天chat、礼物gift、点赞like、进入enter、关注member
  • 弹幕录制可按设置只保留聊天弹幕或包含所有事件类型
  • 弹幕文件与视频文件同目录、同名(.xml 扩展名),内部以结构化 XML 保存

通知推送

  • 邮件通知:支持 SMTP 配置、SSL、自定义发件人与 HTML 模板
    • 开播提醒:直播间上线时发送
    • 异常提醒:录制异常时发送
    • 模板变量:{{appName}}{{anchor}}{{title}}{{summary}}{{detail}}
  • Webhook 通知:支持自定义 URL、请求头、超时配置
    • 开播事件与异常事件分别可独立开关
    • 支持测试发送验证连通性
    • 负载包含直播间信息、录制任务信息等完整上下文

事件脚本

支持在关键生命周期节点执行自定义脚本Shell / PowerShell 内联或外部脚本文件):

事件 说明
live_started 检测到直播上线时触发
live_ended 检测到直播下线时触发
segment_completed 一个录制分片完成时触发

脚本通过环境变量获取上下文信息:

LIVE_RECORDER_EVENT            # 事件类型
LIVE_RECORDER_PLATFORM         # 平台名称
LIVE_RECORDER_LIVE_ROOM_ID     # 直播间内部 ID
LIVE_RECORDER_ROOM_ID          # 平台房间号
LIVE_RECORDER_TITLE            # 直播间标题
LIVE_RECORDER_ANCHOR           # 主播昵称
LIVE_RECORDER_SOURCE_URL       # 源 URL
LIVE_RECORDER_OCCURRED_AT_UTC  # 事件发生时间(北京时间)
LIVE_RECORDER_SEGMENT_FILE_PATH  # 分片文件路径(仅 segment_completed
LIVE_RECORDER_DANMAKU_FILE_PATH  # 弹幕文件路径(仅 segment_completed
LIVE_RECORDER_DURATION_SECONDS   # 分片时长(仅 segment_completed

支持超时控制与自定义日志输出。

异常恢复Recovery

  • 自动检测处于 Live 状态但未在录制的直播间
  • 自动检测录制完成但未做最终化MP4 remux的任务
  • 支持一键重试录制或逐一恢复
  • 后台轮询调度器同时兼具恢复层功能:当 ffmpeg 异常退出而直播间仍在直播时自动重新创建录制任务

数据保留清理Retention

  • 可配置保留天数,超期自动清理录制记录、弹幕文件、视频文件与系统日志
  • 支持后台定时清理(每 24 小时执行一次)

每日回顾Daily Review

  • 按日期查看当天所有录制会话的汇总信息
  • 亮点卡片:最长录制、最多弹幕、最多异常等
  • 时间线视图展示会话与分片时间段
  • 弹幕数量随时间分布的可视化数据

系统日志

  • 持久化系统日志,支持按类别、时间筛选
  • 日志关联直播间、录制会话、录制任务
  • 可在前端日志页面实时查看

前端界面

  • 登录页
  • 直播间管理(添加、编辑、删除、状态查看、快速录制)
  • 录制任务列表与详情
  • 录制会话列表与详情
  • 日志查看器
  • 每日回顾
  • 异常恢复页面
  • 系统设置(录制、通知、弹幕、事件脚本、保留策略、平台配置)
  • 路由懒加载Vite vendor chunk 拆分

适配器架构

平台适配器接口

ILivePlatformAdapter
├─ ParseRoomAsync(input)       # 解析分享链接、提取房间 ID
├─ GetLiveStatusAsync(roomId)  # 获取直播状态、标题、主播名、封面
└─ GetStreamUrlAsync(roomId)   # 获取推流地址

ILiveDanmakuAdapter
├─ CanHandle(platformType)     # 判断是否支持该平台
└─ ConnectAsync(context)       # 建立弹幕 WebSocket 连接

ILiveDanmakuConnection
└─ StartAsync(onEvent)         # 开始接收弹幕,通过回调推送事件

抖音适配器

  • DouyinHttpClient:封装 User-Agent、Referer、Cookie、ttwid 管理
    • 分享链接解析、重定向跟随
    • 从 HTML 中提取 roomIduser_unique_id、主播名、标题(支持新版 __pace_f 数据结构)
    • 调用 webcast/room/web/enter/ 获取直播间元信息
    • 调用 webcast/im/fetch/ 获取弹幕 WebSocket 连接参数
    • a_bogus 签名:通过 Node.js 子进程调用 abogus.js 计算请求签名
  • DouyinLivePlatformAdapter:解析推流地址,选择画质
  • DouyinDanmakuAdapterWebSocket 弹幕连接管理、心跳保活、自动重连

Bilibili 适配器

  • BilibiliHttpClientWbi 签名、分享链接解析
  • BilibiliLivePlatformAdapter:直播状态查询,推流地址获取
  • BilibiliDanmakuAdapter:弹幕 WebSocket 协议解析

设置项速览

录制设置

设置 说明
FFmpeg 路径 ffmpeg 可执行文件路径
输出根目录 录制文件输出根目录
输出模板 路径模板,支持 {platform} {roomId} {anchor} {title} {yyyy} {MM} {dd} {HHmmss} 等变量
默认画质 优先选择的流画质
保存格式 MP4 / TS
保存模式 单文件 / 分段
分段时长 分段模式下的每段时长(秒)
录制模板 StreamCopy / BalancedMp4 / ArchiveTs
重连开关 断线后是否自动重连
最大重连延迟 重连退避最大秒数
读写超时 网络读写超时秒数
存储守护 启用磁盘空间检查
最低剩余空间 存储守护的最低空间阈值GB

弹幕设置

设置 说明
启用弹幕录制 录制时是否同时采集弹幕
包含非聊天事件 是否记录进入、关注、礼物等非聊天弹幕
最小轮询间隔 弹幕连接重试的最小间隔(毫秒)
最大重试延迟 弹幕连接重试退避最大秒数

通知设置

设置 说明
启用邮件通知 SMTP 邮件通知总开关
SMTP 服务器 / 端口 / SSL / 账号 邮件服务器配置
开播提醒 / 异常提醒 分别控制是否发送
HTML 模板 可自定义邮件 HTML 模板,支持变量占位
启用 Webhook Webhook 推送总开关
Webhook URL / 请求头 / 超时 Webhook 配置
开播通知 / 异常通知 分别控制是否推送

事件脚本设置

设置 说明
启用事件脚本 总开关
开播脚本 / 下播脚本 / 分片完成脚本 分别控制与配置
脚本模式 内联脚本 / 外部文件
超时(秒) 脚本执行超时限制

保留策略

设置 说明
启用保留清理 是否开启自动清理
保留天数 超过此天数的记录将被清理
同时删除文件 是否删除对应的视频与弹幕文件

运行

后端

dotnet restore LiveRecorder.sln
dotnet build LiveRecorder.sln --no-restore -m:1
dotnet run --project src/LiveRecorder.WebApi/LiveRecorder.WebApi.csproj --urls http://localhost:5000

默认账号:

  • 用户名:admin
  • 密码:Admin@123

Swagger

前端

cd frontend
npm install
npm run dev

前端开发服务器:

Docker 部署

docker compose up -d
  • API 服务运行在容器内 :8080
  • Nginx 反向代理将 /api 转发到 API其余请求由前端 SPA 处理
  • 默认暴露端口 HTTP_PORT(默认 8080
  • 数据目录 ./data 与录制目录 ./records 映射到宿主机
  • 支持多架构构建(linux/amd64, linux/arm64

验证

  • dotnet build LiveRecorder.sln --no-restore -m:1
  • npm run buildfrontend 目录)
  • Docker Compose 完整部署验证通过

后续规划

  1. 完善 Bilibili 全功能适配,新增虎牙、斗鱼、快手适配器
  2. 按直播间独立配置录制参数
  3. 日志全文搜索与时间范围过滤
  4. 基于 JWT 或外部 SSO 替换轻量 Token 会话
  5. 弹幕回放播放器集成
  6. 录制文件自动上传至 S3/OSS 等对象存储