Files
eric d61526698d 重构无人直播助手:内嵌 youLIVE、摄像头直推、推流诊断与 UI 焕新
将 README 改写为产品文档;移除微信/EasyTier/工作台等遗留模块;新增 youLIVE 目标端监控、摄像头推流、质量守卫与转播历史能力。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 20:50:44 -05:00

405 lines
17 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 无人直播助手
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 及相关依赖的许可证条款。使用第三方平台直播服务请遵守各平台服务条款。