# 无人直播助手 Windows 桌面端 **抖音 → YouTube 无人转播** 控制台:内置 Electron 客户端、FastAPI 控制面(`web2`)、FFmpeg 推流 worker、多频道 Pro、推流诊断。 [![Python](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/) [![Electron](https://img.shields.io/badge/electron-33-blue.svg)](https://www.electronjs.org/) [![Platform](https://img.shields.io/badge/platform-Windows-blue.svg)]() > 录制核心基于 [DouyinLiveRecorder](https://github.com/ihmily/DouyinLiveRecorder) 生态;Linux 全功能服务端可参考同级项目 **sh2**(`d2ypp2`)。本仓库侧重 **Windows 懒人包 + Electron 控制台**。 --- ## 目录 - [快速开始](#快速开始) - [产品定位](#产品定位) - [系统架构](#系统架构) - [仓库结构](#仓库结构) - [界面与功能](#界面与功能) - [web2 API](#web2-api) - [配置与数据路径](#配置与数据路径) - [单频道与多频道 Pro](#单频道与多频道-pro) - [推流诊断 / 质量守卫 / 转播历史](#推流诊断--质量守卫--转播历史) - [youLIVE 目标端监控](#youlive-目标端监控) - [摄像头直推](#摄像头直推) - [会员登录门禁(可选)](#会员登录门禁可选) - [开发与构建](#开发与构建) - [打包发布](#打包发布) - [环境变量](#环境变量) - [故障排查](#故障排查) - [相关文档](#相关文档) - [许可证](#许可证) --- ## 快速开始 ### 最终用户(便携包) 1. 运行发布包中的 **无人直播助手** 可执行文件。 2. 打开 **直播** 页,在界面中填写: - YouTube **串流密钥**(Studio → 直播 → 串流设置); - **源站地址**(抖音直播间 URL,每行一个)。 3. 点击 **开始直播**;在 **当前直播日志** 中查看业务状态与 FFmpeg 输出。 ### 开发者 ```bash cd electron pnpm install pnpm dev ``` 首次开发若缺少离线 Python/FFmpeg,可在 `electron/` 下执行 `pnpm prepare:runtime`。 仅调试后端 API(仓库根目录): ```bash pip install -r requirements.txt uvicorn web2:app --host 127.0.0.1 --port 8001 --reload ``` --- ## 产品定位 | 场景 | 说明 | |------|------| | **无人转播** | 从抖音等源站拉流,经本机 FFmpeg 推送到 YouTube RTMPS。 | | **值守运行** | 通过内置 `BuiltinSupervisor`(或可选 PM2)管理 `youtube2.py`、`douyin_youtube_ffplay.py` 等 worker。 | | **桌面控制台** | Electron 提供直播、网络、系统等页面。 | | **多路 Pro** | 多组「一个抖音直播间 ↔ 一个 YouTube 串流密钥」并行,进程名 `youtube2__{channelId}`。 | **配对原则(强制)** - 一个抖音直播间地址只对应 **一个** YouTube 串流密钥; - **禁止** 同一抖音向多个 YouTube 推流; - **禁止** 多个抖音共用同一密钥。 --- ## 系统架构 ``` ┌─────────────────────────────────────────────────────────────────┐ │ Electron 渲染进程 (React + Vite) │ │ 直播 / 摄像头 / 网络 / 系统 │ └───────────────────────────┬─────────────────────────────────────┘ │ preload (contextBridge) ┌───────────────────────────▼─────────────────────────────────────┐ │ Electron 主进程 │ │ · 启动 uvicorn (web2:app) │ │ · sql.js → client-data.sqlite │ │ · 托盘、深链 --nav= │ │ · YouTube Studio 系统浏览器侧车 │ │ · youLIVE 服务(监听 / 弹幕 / 桌面通知 / 本地 SQLite) │ └───────────────────────────┬─────────────────────────────────────┘ │ http://127.0.0.1:8001(可 0.0.0.0) ┌───────────────────────────▼─────────────────────────────────────┐ │ web2.py (FastAPI) │ │ 进程启停 / 状态诊断 / 配置读写 / Pro / 质量守卫 / 会话历史 │ └───────────────────────────┬─────────────────────────────────────┘ │ ┌───────────────────┼───────────────────┐ ▼ ▼ ▼ youtube2.py douyin_youtube_ffplay.py tiktok*.py │ │ └──────── FFmpeg + Supervisor / PM2 ────────────────┘ ``` | 模块 | 文件 | 职责 | |------|------|------| | Worker | `youtube2.py`, `douyin_youtube_ffplay.py`, `main.py` | 拉流、转码、推流 | | 控制面 | `web2.py` | HTTP API | | 运行时诊断 | `web2_process_runtime.py` | `business_status`、FFmpeg 速度/帧数 | | 质量守卫 | `web2_quality_guard.py` | 推流质量评分 | | 转播历史 | `web2_relay_log.py` | 会话 SQLite、日志导入 | | 配置治理 | `web2_config_governance.py` | 保存前备份、恢复 | | 多频道 | `web2_relay_pro.py` | `youtube_channels.json`、`config/relay_pro/` | | 摄像头 | `web2_camera.py`, `camera_youtube.py` | DirectShow 采集、NVENC 推流 | | youLIVE | `electron/src/youlive/` | YouTube 监听、弹幕、账号、桌面通知 | | 主进程 | `electron/src/main/` | 运行时打包、IPC、本地 DB | | 界面 | `electron/src/renderer/` | React SPA | --- ## 仓库结构 ``` . ├── electron/ # 无人直播助手(Electron + React) │ ├── src/main/ # 主进程 │ ├── src/preload/ # contextBridge │ ├── src/renderer/ # UI(直播 / 摄像头 / 网络 / 系统) │ ├── src/youlive/ # 内嵌 youLIVE(主进程服务 + 共享类型) │ └── scripts/ # 离线运行时、图标 ├── web2.py # FastAPI 入口 ├── web2_*.py # 后端子模块 ├── config/ # 运行配置 ├── backup_config/__web__/ # 配置自动备份 ├── runtime/youtube_relay/ # 转播会话 sessions.sqlite ├── src/ # 录制核心(spider、stream、room…) ├── camera_youtube.py # 摄像头→YouTube worker ├── douyin_youtube_ffplay.py # 抖音→YouTube 转播 ├── youtube2.py # YouTube worker ├── docs/ # 补充文档 └── requirements.txt ``` --- ## 界面与功能 | 页面 | 说明 | |------|------| | **直播** | 单频道 / Pro:抖音源站转播、密钥、监听、启停、链路诊断、转播历史 | | **摄像头** | 物理摄像头 + 麦克风 → FFmpeg → YouTube(`camera_youtube` 进程) | | **网络** | 测速、代理 | | **系统** | 负载、开机启动、路径、会员登录限制开关 | 直播页能力摘要: - **自适应轮询**:推流中 ~0.8s,空闲 ~4s,后台标签 ~30s - **链路诊断**:源站 / 推流 / 目标三层检查(`GET /youtube/diagnostics`) - **YouTube 目标端监控**:监听地址写入 `youtube_channels.json`,与转播线路绑定 - **桌面通知**:推流未到达 YouTube、目标端下播、弹幕关键词(需 youLIVE 桌面通知开启) - **转播历史**:PM2 状态自动记会话;支持从 PM2 日志导入 - **配置历史备份**:保存前自动备份,界面可恢复 - **YouTube Studio**:系统浏览器打开,便于核对密钥 - **源站预览**:解析抖音 URL 并尝试显示主播昵称 - **配对校验**:Pro 多线路保存时检测抖音地址 / YouTube 密钥跨频道重复,冲突时展示横幅并阻止启动 --- ## web2 API 默认:`http://127.0.0.1:8001`(`WEB2_PORT` 可改)。 | 分类 | 路径 | 说明 | |------|------|------| | 健康 | `GET /health` | 存活(无需鉴权) | | 进程 | `GET /process_monitor` | 任务列表(含 Pro 频道) | | 进程 | `GET /start` `/stop` `/restart` | 参数 `process=` | | 状态 | `GET /status?process=` | 进程状态 + 业务诊断 + FFmpeg 指标 | | 配置 | `GET/POST /youtube/ini_model` | 结构化 `youtube.ini` | | 配置 | `GET/POST /get_url_config` `save_url_config` | `URL_config.ini` | | 配置 | `GET /config/backups?file=` | 历史备份列表 | | 配置 | `POST /config/restore` | 恢复(`file`, `backupId`) | | Pro | `/relay_pro/*` | 多频道 CRUD、密钥、URL、YouTube 监听地址、live_status | | 诊断 | `GET /youtube/diagnostics` | 源站 / FFmpeg / 目标三层诊断 | | 诊断 | `GET /youtube/quality_guard` | 质量评分(诊断内部复用) | | 摄像头 | `GET /camera/devices` | FFmpeg 枚举音视频采集设备 | | 摄像头 | `GET/POST /camera/config` | 读写 `camera_live.ini` | | 历史 | `GET /youtube/relay/sessions` | 转播会话 | | 历史 | `POST /youtube/relay/sessions/import` | 从 PM2 日志导入 | | 网络 | `GET /network_status` `GET/POST /proxy_config` | 测速与代理 | | 系统 | `GET /system_metrics` `GET /host/gpu_status` | 主机与 NVENC | | OAuth | `GET /youtube/oauth/*` | Google 拉取串流密钥(UI 可关) | **可选鉴权**:`config/web2_api_token.txt` 或 `WEB2_API_TOKEN` 存在时,除 `/health` 外需: ```http Authorization: Bearer <密钥> ``` Electron 主进程自动注入 API 鉴权头。 --- ## 配置与数据路径 | 路径 | 用途 | |------|------| | `config/youtube.ini` | 单路密钥与 `[youtube]` 选项(GPU、分辨率、RTMPS) | | `config/URL_config.ini` | 单路源站 URL 列表 | | `config/youtube_channels.json` | Pro 频道元数据(见 `youtube_channels.example.json`) | | `config/relay_pro/url_config.ch_*.ini` | 每频道源站地址 | | `config/relay_pro/youtube.ch_*.ini` | 每频道密钥(后端物化) | | `config/web2_api_token.txt` | API 鉴权密钥 | | `config/web2_bind_host.txt` | 监听地址(懒人包默认 `127.0.0.1`;局域网访问可设 `0.0.0.0` 并配置 token) | | `config/google_oauth.example.json` | YouTube OAuth 模板 | | `config/ffmpeg_proxy.ini` | FFmpeg 代理 | | `config/camera_live.ini` | 摄像头采集参数(见 `camera_live.example.ini`) | | `backup_config/__web__/` | 配置版本备份 | | `runtime/youtube_relay/sessions.sqlite` | 转播会话库 | | 用户数据目录 `client-data.sqlite` | Electron 本地事件与快照 | 示例 `config/youtube_channels.json`: ```json { "version": 1, "channels": [ { "id": "ch_a", "name": "路线A", "douyinUrl": "https://live.douyin.com/123456789", "youtubeKey": "xxxx-xxxx-xxxx-xxxx" } ] } ``` --- ## 单频道与多频道 Pro ### 单频道 1. 填写 `config/youtube.ini` 中的串流密钥。 2. 填写 `config/URL_config.ini` 中的抖音直播间地址。 3. **直播** 页选择 `youtube2` → **开始直播**。 ### 多频道 Pro 1. 直播页打开 **Pro** 开关。 2. 界面新增频道,或编辑 `config/youtube_channels.json`。 3. 每频道进程:`youtube2__{channelId}`,独立密钥与 URL 文件。 4. 网格内按频道启停;预检要求密钥与源站均已配置。 --- ## 推流诊断 / 质量守卫 / 转播历史 `GET /status` 的 `business_status` 示例: | 状态 | 含义 | |------|------| | `streaming` | 正在推流 | | `relay_slow` | 推流速度低于实时 | | `source_stalled` | FFmpeg 进度停滞 | | `youtube_key_rejected` | YouTube 拒绝 RTMPS | | `waiting_source` | 等待源站开播 | | `misconfigured` | 配置不完整 | | `monitoring` | 在线监测中 | **链路诊断**:`GET /youtube/diagnostics` → 源站 / FFmpeg / 目标三层检查与综合评分。 **质量守卫**:`GET /youtube/quality_guard` → FFmpeg 指标与告警(诊断层内部复用)。 **转播历史**:`runtime/youtube_relay/sessions.sqlite` - PM2 `online` / 停止时自动开闭会话; - `/status` 轮询时从日志同步主播与时长; - 界面 **从日志导入** 可解析历史 PM2 输出。 --- ## youLIVE 目标端监控 内嵌于 Electron 主进程的 **youLIVE** 模块(`electron/src/youlive/`),通过 preload 暴露 `window.youlive` API,为直播页提供 YouTube **目标端**能力,与 `web2` 控制的 **源站推流** 互补。 | 能力 | 说明 | |------|------| | **监听列表** | 按 YouTube 频道 / 直播页 URL 轮询开播状态、观众数 | | **转播绑定** | 将监听地址写入 `youtube_channels.json` 的 `youtubeWatchUrl`,与 Pro 线路一一对应 | | **弹幕抓取** | 直播进行中拉取聊天消息,支持关键词告警 | | **桌面通知** | 推流未到达 YouTube、目标端下播、弹幕关键词命中时通知(需在 youLIVE 设置中开启) | | **本地存储** | `youlive` SQLite 保存监听项、会话、告警历史 | 直播页 **YouTube 目标端监控** 面板在 Pro / 单路模式下自动同步监听地址;摄像头页亦可绑定 `youtube_watch_url` 做目标端校验。 --- ## 摄像头直推 **摄像头** 页将本机物理摄像头 + 麦克风经 FFmpeg 直推 YouTube RTMPS,进程名 `camera_youtube`(与抖音转播 `youtube2` 独立)。 1. 在界面选择 **视频设备** / **音频设备**(后端 `GET /camera/devices` 枚举 DirectShow 设备)。 2. 设置分辨率、帧率、码率;可选 NVENC 硬件编码。 3. 填写 YouTube **串流密钥**(复用 `config/youtube.ini`)。 4. 可选填写 **YouTube 直播页地址** 供目标端监听。 5. 点击 **开始直播**。 配置持久化于 `config/camera_live.ini`(模板见 `config/camera_live.example.ini`)。 --- ## 会员登录门禁(可选) 默认 **关闭**(无登录 UI,启动直播无账号要求)。 开启:**系统** → **客户端与系统集成** → **会员登录限制** - 侧栏显示登录/注册; - 开始/重启前需 PocketBase 会员(`X-PB-Token`); - 状态键:`localStorage` → `pb_auth_gate_enabled`。 --- ## 开发与构建 | 组件 | 版本 | |------|------| | Node.js | 18+ | | pnpm | 10+ | | Python | 3.10+(开发机;发布包自带运行时) | | 命令(在 `electron/`) | 说明 | |------------------------|------| | `pnpm dev` | 开发模式 | | `pnpm build` | 编译到 `out/` | | `pnpm prepare:runtime` | 准备离线 Python/FFmpeg | | `pnpm verify:runtime` | 校验运行时 | | `pnpm dist` | Windows 便携包 | --- ## 打包发布 ```bash cd electron pnpm install pnpm dist ``` 产物:`electron/dist/` 便携版。仓库根(除 `electron/`)打入 `resources/backend/`,用户机无需单独安装 Python。 --- ## 环境变量 | 变量 | 说明 | |------|------| | `WEB2_PORT` | API 端口,默认 `8001` | | `WEB2_HOST` | 监听地址(优先于 `web2_bind_host.txt`) | | `WEB2_API_TOKEN` | API 密钥 | | `WEB2_SUPERVISOR` | 进程后端;Pro 多频道勿强制 PM2 | | `VITE_API_BASE` | 渲染进程 API 根(非 Electron 调试) | | `VITE_WEB2_API_TOKEN` | 开发用 Bearer | --- ## 故障排查 | 现象 | 处理 | |------|------| | 无法启动 / 服务未就绪 | 查 uvicorn 日志;确认 8001 未被占用;`pnpm verify:runtime` | | YouTube 无画面 | 看 `youtube_key_rejected`;核对 Studio 密钥;检查 RTMPS 与代理 | | `relay_slow` / 掉帧 | 查 NVENC;降分辨率;关占用 CPU 的程序 | | Pro 无法启动 | 勿 `WEB2_SUPERVISOR=pm2`;每频道密钥与 URL 已保存;检查配对冲突横幅 | | 摄像头无画面 | 确认 DirectShow 设备名与 `camera_live.ini` 一致;尝试关闭 GPU 编码 | | 目标端监听无数据 | 确认 `youtubeWatchUrl` / `youtube_watch_url` 已填写;youLIVE 桌面通知已开启 | | 配置误改 | 直播页 **历史备份** 或 `POST /config/restore` | 日志: - Worker:`.pm2/logs/` 或界面「当前直播日志」 - 客户端:系统页打开「客户端日志」目录 --- ## 相关文档 | 文档 | 说明 | |------|------| | [docs/YOUTUBE_LIVE_SEO.md](docs/YOUTUBE_LIVE_SEO.md) | YouTube 直播 SEO | | [docs/REALTIME_AUDIO_DEMUCS.md](docs/REALTIME_AUDIO_DEMUCS.md) | 实时音频 Demucs | --- ## 许可证 本项目继承上游 DouyinLiveRecorder 及相关依赖的许可证条款。使用第三方平台直播服务请遵守各平台服务条款。