我把直播间监控、自动录制、分段保存、TS 转 MP4、磁盘保护和服务自愈整理成了一个可以长期值守的项目。它保留了 DouyinLiveRecorder 的完整多平台录制内核,又加入了我在线上环境里实际使用的优雅停机、异常分片保护、库存背压、systemd 和失败通知。
下载后只要准备好 Python、FFmpeg 和自己的直播间配置,就能直接运行。账号、Cookie、代理和通知密钥都放在本机配置里,仓库内没有真实账号数据。
录制内核来自 ihmily/DouyinLiveRecorder,本仓库基于其 MIT 许可版本
v4.0.6(commit271a536)继续完善。上游归属和我增加的部分见第三方声明。
- 循环检查多个直播间,开播后自动调用 FFmpeg 录制;
- 保留上游的 50 多个平台解析与录制适配器;
- 按主播、时间或标题组织文件,支持 TS、MKV、FLV、MP4、MP3 和 M4A;
- 按固定时长切分视频,录制完成后自动封装为 MP4;
- 收到
SIGTERM后停止接收新任务,等待正在录制的任务正常收尾; - FFmpeg 异常退出时保留已完成分片,跳过最后一个可能未写完的 TS,再转换其余分片;
- 同时检查磁盘剩余空间和下游成片库存,达到阈值自动暂停,恢复后自动拉起;
- 通过 systemd 长期运行、失败重启、定时巡检,并可把失败单元和最近日志发到通知服务;
- 原生运行和 Docker Compose 两种部署方式都已准备好。
我的实际环境里曾同时运行 6 个直播间,除了断电可以长期运行。这是我的实际运行记录,不等同于公开仓库的压测结果。
| 方向 | 实际使用的技术 |
|---|---|
| 录制内核 | Python 3.11、FFmpeg、HLS/FLV、分段录制、TS→MP4 |
| 并发调度 | asyncio、threading、Semaphore、多直播间循环监控 |
| 网络与解析 | HTTPX、Requests、HTTP/2、代理检测、平台直播源解析 |
| 平台签名 | Node.js、PyExecJS、JavaScript 签名脚本、PyCryptodome |
| 配置与状态 | configparser、环境变量、本地 INI、JSON 原子写入 |
| 可靠性 | SIGTERM 优雅停机、异常分片保护、磁盘/库存背压、失败恢复 |
| 服务化 | systemd user service、timer、OnFailure、journalctl |
| 通知 | 上游多渠道开播/关播通知、可选 HTTP 通知 Hub |
| 容器化 | Docker、Docker Compose、非 root 用户运行 |
| 测试与检查 | pytest、合成 fixture、Ruff、Secret Scan、GitHub Actions |
flowchart LR
A["URL_config.local.ini<br/>多个直播间"] --> B["平台解析器<br/>获取直播状态和流地址"]
B --> C{"是否开播"}
C -- "否" --> D["等待下一轮检查"]
D --> B
C -- "是" --> E["FFmpeg 录制"]
E --> F["按时间切分 TS"]
F --> G["完整分片转 MP4"]
H["磁盘与库存 Guard"] --> I{"容量是否安全"}
I -- "否" --> J["停止录制服务<br/>保留状态并通知"]
I -- "是" --> K["恢复已启用服务"]
J --> H
K --> H
下面这些适配器来自上游录制内核,本仓库都保留了:
- 国内及中文平台:抖音、快手、虎牙、斗鱼、YY、B站、小红书、网易 CC、千度热播、猫耳 FM、Look、百度直播、微博、酷狗、花椒、流星、AcFun、畅聊、映客、音播、知乎、嗨秀、VV 星球、17Live、浪 Live、飘飘、六间房、乐嗨、花猫、淘宝、京东、咪咕、连接直播、来秀;
- 海外平台:TikTok、Bigo、Blued、SOOP、PandaTV、WinkTV、TTingLive/FlexTV、PopkonTV、TwitCasting、Twitch、LiveMe、ShowRoom、CHZZK、Shopee、YouTube、Faceit、Picarto。
平台页面和接口会变化。某个平台能否直接录制,取决于当前平台接口、地区、网络和登录状态;需要 Cookie 的平台请把 Cookie 只放在本机的 config.local.ini。
.
├── main.py # 完整录制入口和生产增强
├── src/ # 上游平台解析、直播流和网络实现
│ └── javascript/ # 平台签名脚本
├── recorder_ops/
│ ├── recorder_disk_guard.py # 磁盘与成片库存背压
│ ├── service_failure_notify.py # systemd 失败通知
│ ├── notify.py # 可选 HTTP 通知 Hub
│ └── segments.py # 完整分片识别和排序
├── config/
│ ├── config.example.ini # 已脱敏的完整录制配置
│ ├── URL_config.example.ini # 不含真实主播的地址模板
│ └── runtime.env.example # Guard/systemd 环境变量
├── deploy/systemd/ # service、timer、OnFailure 单元
├── tests/ # 离线测试和合成数据
├── Dockerfile
└── docker-compose.yaml
需要 Python 3.11、FFmpeg 和 Node.js 20。Ubuntu/Debian 可以这样安装基础工具:
sudo apt-get update
sudo apt-get install -y ffmpeg nodejs python3.11 python3.11-venvgit clone https://github.com/whichmen/commerce-live-recorder.git
cd commerce-live-recorder
python3.11 -m venv .venv
. .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -r requirements.txtcp config/config.example.ini config/config.local.ini
cp config/URL_config.example.ini config/URL_config.local.ini在 config/URL_config.local.ini 里一行放一个直播间地址。需要单独指定画质时,在地址前写 原画,、超清,、高清,、标清, 或 流畅,。
Cookie、代理和消息推送都在 config/config.local.ini 里设置。这两个 *.local.ini 已加入 .gitignore,不会被正常提交。
python main.py默认录制文件在 downloads/。按 Ctrl+C 可以直接退出;systemd 或容器发送 SIGTERM 时,程序会先停止新任务并等待当前录制正常结束。
先准备宿主机目录和配置:
mkdir -p local-config downloads logs .runtime
cp config/config.example.ini local-config/config.ini
cp config/URL_config.example.ini local-config/URL_config.ini编辑 local-config/URL_config.ini 后启动:
RECORDER_UID="$(id -u)" RECORDER_GID="$(id -g)" docker compose up -d --build
docker compose logs -f recorderCompose 已设置 20 分钟的停止宽限期,给正在录制的分片足够时间收尾。
录制服务不仅看磁盘,还能看下游成片目录。如果磁盘低于阈值,或者待处理 MP4 数量达到上限,Guard 会暂停配置好的服务;容量恢复后再拉起已启用的服务。
关键变量在 config/runtime.env.example:
RECORDER_MIN_FREE_GB=20
RECORDER_PRODUCED_STOCK_LIMIT=50
RECORDER_MANAGED_SERVICES=commerce-live-recorder.service先用只检查模式确认路径和阈值:
.venv/bin/python -m recorder_ops.recorder_disk_guard --dry-run
cat .runtime/state/recorder_disk_guard_state.json如果还要联动下游生产服务,可以把多个 systemd 单元用逗号分开写进 RECORDER_MANAGED_SERVICES,不用改 Guard 代码。
仓库里的 user unit 默认项目路径是 $HOME/commerce-live-recorder,Python 环境是项目下的 .venv。如果目录不同,先修改 unit 中的路径。
mkdir -p ~/.config/systemd/user ~/.config/commerce-live-recorder
cp deploy/systemd/* ~/.config/systemd/user/
cp config/runtime.env.example ~/.config/commerce-live-recorder/env
systemctl --user daemon-reload
systemctl --user enable --now commerce-live-recorder.service
systemctl --user enable --now commerce-live-recorder-disk-guard.timer查看状态和日志:
systemctl --user status commerce-live-recorder.service
journalctl --user -u commerce-live-recorder.service -f如果需要开机后即使没有登录也继续运行,可以执行:
loginctl enable-linger "$USER"OnFailure 会调用 recorder_ops.service_failure_notify,整理失败单元、机器名、时间和最近几行 journal。通知接口没配置时它只打印一条 disabled 日志,不会影响录制服务。
要接入自己的 HTTP 通知 Hub,在本机 env 文件里填写:
RECORDER_NOTIFY_URL=https://notify.example.invalid/v1/send
RECORDER_NOTIFY_API_KEY=replace-locally
RECORDER_NOTIFY_APP_KEY=commerce-live-recorder
RECORDER_NOTIFY_TOUSER=@all请求体格式为:
{
"app_key": "commerce-live-recorder",
"touser": "@all",
"content": "通知正文"
}所有测试都用合成文件和假的 systemd 返回值,不需要真实直播间、Cookie 或通知服务:
python -m pip install -r requirements-dev.txt
python -m pytest
ruff check recorder_ops tests scripts
python scripts/secret_scan.py
python -m py_compile main.py recorder_ops/*.py| 部分 | 上游 v4.0.6 |
本仓库增加 |
|---|---|---|
| 多平台直播源解析 | 有 | 完整保留,并补充淘宝活动页长链接识别 |
| FFmpeg 录制与切片 | 有 | 异常退出时只转换确定完整的分片 |
| 停止方式 | 直接退出 | SIGTERM 停止接新任务,等待当前录制收尾 |
| 容量保护 | 单次录制空间阈值 | 磁盘 + 下游库存双重背压,可停启多个服务 |
| 长期运行 | Docker 基础文件 | systemd、timer、OnFailure、Docker Compose 停止宽限期 |
| 运维通知 | 开播/关播多渠道通知 | 服务失败通知和 Guard 状态切换通知 |
| 测试与安全 | 上游实现 | 离线测试、合成 fixture、密钥扫描和 CI |
完整版权和许可信息见 LICENSE 与 THIRD_PARTY_NOTICES.md。
- commerce-video-pipeline:直播切片、Demucs、FunASR、LLM 标题、多模态生成与 Eval;
- commerce-multi-platform-publisher:视频号、抖音、淘宝、快手、拼多多和小红书发布编排。
技术交流或其他问题联系我,微信:whichmen。