Files
Live-streaming/README.md
T

250 lines
13 KiB
Markdown
Raw 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.
# BetterGI 直播联动
监听 B 站直播间弹幕,管理观众排队、积分、扫码上号、BetterGI 配置组与自动每日一条龙、队伍管理、点歌和 TTS 播报。
## 环境
- **Python**: 项目虚拟环境 `.venv` 或 `.venv-tts`(Python 3.11+)
- **Node.js**: 构建前端用
- **BetterGI**: 自动化脚本引擎,路径在 `config/config.json` 中配置
```powershell
# 安装 Python 依赖
.venv\Scripts\python.exe -m pip install -r requirements.txt
# 下载 TTS 模型(约 1.2GB,仅需一次)
.venv-tts\Scripts\python.exe -c "from huggingface_hub import snapshot_download; snapshot_download('Qwen/Qwen3-TTS-12Hz-0.6B-Base')"
# 安装前端依赖并构建
cd frontend\admin
npm install
npm run build
```
## 启动
```powershell
.venv\Scripts\python.exe app\main.py --role all --host 0.0.0.0 --port 5191
```
| 参数 | 默认值 | 说明 |
|------|--------|------|
| `--role` | `all` | `queue` 仅排队/Web / `tts` TTS 状态窗口 / `all` 启动排队/Web 和内置 mpv 点歌(推荐) |
| `--host` | `0.0.0.0` | 绑定地址 |
| `--port` | `8086` | 端口 |
启动后日志会打印本机和局域网访问地址,例如 `http://192.168.31.80:5191/admin`。
## 配置文件
配置文件统一为 `config/config.json`,支持热加载,保存后无需重启。
### bilibili — 直播间连接
| 字段 | 说明 |
|------|------|
| `room_id` | 直播间号(短号也可) |
| `sessdata` | B 站 Cookie SESSDATA,用于监听弹幕和发送回复 |
| `bili_jct` | CSRF token,发弹幕必须。和 SESSDATA 配套获取 |
获取方式:浏览器登录 B 站 → F12 → Application → Cookies → bilibili.com → 复制 `SESSDATA` 和 `bili_jct`。
> **注意**:`sessdata` 和 `bili_jct` 属于敏感登录凭证,不要分享本文件。缺少 `bili_jct` 时只能收弹幕不能回复。
### queue — 排队积分
| 字段 | 默认值 | 说明 |
|------|--------|------|
| `initial_points` | 10 | 新用户初始积分 |
| `signin_points` | 10 | 每日签到获得积分 |
| `max_points` | 30 | 积分上限 |
| `points_per_minute` | 1 | 队首每分钟扣除积分 |
| `admin_window_seconds` | 180 | 队首上号窗口(超时过号) |
| `default_group` | 薄荷 | 队列空时默认运行的 BetterGI 配置组 |
### global — 全局
| 字段 | 说明 |
|------|------|
| `admin_uids` | 管理员 UID 列表(一级用户,可用重置等特权指令) |
| `log_level` | 日志级别:`DEBUG` / `INFO` / `WARNING` |
### daily — 自动每日
| 字段 | 默认值 | 说明 |
|------|--------|------|
| `one_dragon_template` | 默认配置 | BGI 一条龙模板名称 |
| `managed_one_dragon_name` | 直播系统自动每日 | 每次覆盖生成并启动的托管配置名称 |
| `ley_line_craft_resin_before` | true | 地脉模式执行前是否合成树脂 |
| `commission_use_current_party` | true | 委托前读取游戏当前队伍名并写入 AutoCommissionNova 的战斗与元素采集队伍配置 |
| `current_party_read_timeout_sec` | 45 | 当前队伍 OCR 读取超时秒数 |
自动每日流程为“领取邮件 → 合成树脂 → 可选其他任务 → 领取尘歌壶奖励 → 领取每日奖励”。秘境俗称维护在 `config/domain_aliases.json`,修改后无需重启。
完整的 BGI 模板、战斗策略和三个配置组配置方法见 [自动每日与队伍管理](docs/自动每日.md)。
### broadcast — 弹幕播报与 TTS
| 字段 | 默认值 | 说明 |
|------|--------|------|
| `enable_danmu_reply` | true | 指令回复发到直播间 |
| `enable_system_danmu` | true | 系统通知发到直播间 |
| `enable_tts` | false | TTS 语音播报(需先下载模型) |
| `danmu_interval_sec` | 5 | 弹幕发送间隔 |
| `tts_provider` | none | `none` / `faster-qwen3-tts` / `dots-tts` |
### commands — 内置指令别名
14 个内置指令,每个可单独启用/禁用、自定义别名和允许角色:
| key | 默认别名 | 功能 |
|-----|----------|------|
| `queue` | 排队 | 加入排队队列 |
| `signin` | 签到 | 每日签到 |
| `login` | 上号 | 队首触发扫码上号 |
| `confirm_yes` | 是 | 确认账号正确 |
| `confirm_no` | 不是 | 确认账号不正确,重新扫码 |
| `run` | 执行, 跑, 开始 | 执行配置组(需带参数) |
| `daily` | 自动每日, 每日, 日常, 做每日, 做日常 | 启动托管的一条龙每日任务,可选秘境、地脉或委托模式 |
| `switch_party` | 切换队伍, 更换队伍, 换队伍, 换队 | 修改并执行配置组“切换队伍” |
| `edit_party` | 修改队员, 更换队员, 换队员, 换角色 | 校验四名角色后修改并执行配置组“修改队员” |
| `leave` | 退出 | 退出队列 |
| `reset` | 重置 | 一级用户重启原神和 BGI |
| `points` | 积分 | 查询积分 |
| `queue_list` | 队列 | 查看排队情况 |
| `help` | 帮助 | 显示帮助 |
### rules — 弹幕触发规则
```json
{
"keyword": "开始",
"match_type": "exact",
"groups": ["子探测单元"],
"cooldown": 60,
"admin_only": false,
"reply": "收到,开始执行子探测单元任务"
}
```
- `match_type`:`contains` / `exact` / `startswith` / `regex`
- 匹配后直接启动 `groups` 指定的 BetterGI 配置组
### music_monitor — 音乐监听与点歌
观众可通过弹幕点歌,内置 mpv 播放器负责播放、续播和状态维护;旧版 `music_monitor.py` 仍保留用于兼容历史配置,但不再作为独立进程启动。
`request_player.commands`:点歌触发词,默认 `["点歌", "dg"]`。
### llm_reply — AI 弹幕回复(默认关闭)
把观众弹幕交给 LLM 自动回复,回复同时走弹幕+TTS 通道(后台「AI回复」页可配置,支持测试)。
直播前台 `/` 现显示绮良良像素桌宠。`web/uploads/kirara_walk_front.png`、`kirara_walk_back.png`、`kirara_walk_left.png`、`kirara_walk_right.png` 分别提供正面、背面、左侧、右侧四帧无尾巴走路动画;桌宠只沿水平或垂直方向游走,步态帧随移动距离切换,停下时切回正面静止帧。每隔 60–90 秒开始一次移动,持续 10–15 秒,移动速度为 21–35 像素/秒。旁边的黄、蓝、红进度环按体力、清洁、心情从外到内套叠,尺寸为 40×40 像素,以方格绘制阶梯状轮廓,不显示文字。角色与状态环一起沿游戏镂空区外的上、右、下区域游走。体力、清洁和心情均为 0–100,首次为 100;每 15 秒查询一次 B 站直播间状态,只有确认直播中才累计时间,每累计一小时体力和清洁各减 10。查询短暂失败时沿用最近状态最多 60 秒;服务停机期间不补扣。两项同时低于 40 时心情每小时减 5,同时高于 80 时每小时加 3。AI 回复应以 `[开心]`、`[很开心]`、`[平静]`、`[生气]` 或 `[很生气]` 开头,分别令心情 +1、+3、0、-1、-3;标签不会发到弹幕或 TTS。状态保存在 `data/kirara_pet.json`(若 `queue.data_dir` 被修改,则保存在对应数据目录)。
走路结束后绮良良转为正面静止姿势。每隔 120–150 秒随机触发一次送快递、看书或看手机待机动作,持续 15–20 秒。三种待机和睡觉动作各使用一套由 ImageGen 生成的独立四帧完整角色 PNG 素材(`web/uploads/kirara_idle_*.png`)。心情低于 50 时立即停止行走和普通待机并进入睡眠;进食和洗澡礼物动画优先于睡觉,播放完再回到睡觉姿势,心情恢复后重新安排游走和待机。
体力或清洁降到 60 及以下时,桌宠每 60 秒显示一次跟随角色的像素气泡。体力从饭团、薯条提示中随机选一句,清洁从人气票、粉丝团灯牌提示中随机选一句;两项都低时轮流提示,数值为 0 的需求优先。气泡在数值 60/40/20 时分别显示 5/10/30 秒,中间线性过渡,数值 0 时常驻,恢复到 60 以上即停止该项提示。
礼物恢复规则固定为:每个饭团或薯条增加 5 点体力(桌宠的饱食度);每个人气票或粉丝团灯牌增加 5 点清洁。直播事件中的“灯牌”简写也按粉丝团灯牌处理。其他礼物不改变这两项数值。礼物数量乘以每个礼物的 5 点恢复量;数值仍限制在 0–100。
进食和洗澡动画按礼物的名义恢复量排播,每 1 点播放 5 秒;即使数值已达 100,单个上述礼物仍完整播放 25 秒。进食有饭团和团子两种素材,洗澡有海绵擦洗和花洒冲洗两种素材,播放时各自轮流使用。动画期间桌宠暂停游走,结束后重新安排下一次移动;刷新前台不会重放已有礼物,但打开页面后的首件新礼物会正常播放。四组透明像素素材位于 `web/uploads/kirara_eat_rice.png`、`kirara_eat_dango.png`、`kirara_bath_sponge.png` 和 `kirara_bath_shower.png`。
- **协议抽象**(`app/llm_client.py`):`provider` 支持
- `openai` — OpenAI `/chat/completions` 兼容协议,覆盖 DeepSeek、通义千问(DashScope 兼容模式)、Kimi、智谱 GLM、硅基流动、OpenRouter、vLLM、LM Studio 及 Ollama 的 OpenAI 兼容端点
- `ollama` — Ollama 原生 `/api/chat`(本地部署免鉴权)
- `anthropic` — Anthropic `/v1/messages`(Claude 系列)
- 新增协议:继承 `BaseLLMProvider` 实现 `chat()` 后在 `PROVIDERS` 注册即可
- **指令自动忽略**:排队/上号/点歌/自定义规则等会触发指令的弹幕在指令分发层被识别,不会发送给 LLM;`ignore_prefixes`(默认 `//`)开头的弹幕同样忽略
- **安全与限流**:`replies_per_minute` 全局每分钟上限、`per_user_cooldown_sec` 单人冷却、`blacklist_uids` 黑名单、`max_reply_chars` 回复截断、并发保护(在途请求未完成时新弹幕直接跳过)
主要字段:`enabled`(开关)、`base_url`/`api_key`/`model`、`system_prompt`(人设)、`context_turns`(上下文轮数)。
### system — 系统定时任务
| 字段 | 说明 |
|------|------|
| `enable_startup_shortcut` | 开机自启 |
| `auto_reboot_time` | 每日自动重启时间 |
| `launch_bilibili_live_time` | 定时启动直播姬 |
| `launch_genshin_time` | 定时启动原神 |
## 后台管理
```
http://127.0.0.1:5191/admin
```
| 页面 | 功能 |
|------|------|
| 总览 | 运行状态、排队人数、服务健康、快捷操作 |
| 配置 | B 站连接、BetterGI 路径、队列参数、前台视觉 |
| 规则 | 弹幕触发规则 + 内置指令别名管理 |
| 队列 | 当前排队列表,支持移出、加减分、清空 |
| 用户 | 所有用户积分管理,支持加减分、踢出、删除 |
| 媒体 | 弹幕播报开关、TTS 配置与测试、音乐监听 |
| 日志 | 系统日志 + BetterGI 日志 |
| JSON | 原始 JSON 编辑 |
后台每 3 秒自动刷新,数据实时同步。
## 开发
### 前端
```powershell
cd frontend\admin
npm run build # 构建到 web/admin/
```
源码:`frontend/admin/src/main.js`(Vue3 单文件组件),`styles.css`。
### 后端
```powershell
# 编译检查
.venv-tts\Scripts\python.exe -m py_compile app/danmu_queue.py
```
核心文件:
| 文件 | 功能 |
|------|------|
| `app/main.py` | 入口,启动 Web 服务和子模块 |
| `app/danmu_queue.py` | 弹幕监听、指令处理、队列管理、BGI 控制、TTS、Web API |
| `app/bettergi_daily.py` | 自动每日配置生成、秘境别名和队伍参数更新 |
| `app/bettergi_current_party.py` | 当前队伍读取托管配置组、状态协议和防串读校验 |
| `app/music_monitor.py` | 旧版 SMTC 音乐监听兼容模块;当前点歌由 `app/mpv_player.py` 和排队调度负责 |
| `app/core/runtime_paths.py` | 运行时路径解析 |
## 打包
```powershell
# 轻量包(不含 TTS)
.\build.bat
# 完整包(含 TTS/GPU 依赖)
.\build.bat -FullTts
```
输出:`dist/LiveStreaming/LiveStreaming.exe`。
## 数据文件
| 路径 | 内容 |
|------|------|
| `data/users.json` | 用户账号与积分 |
| `data/queue_state.json` | 排队状态(启动时清空) |
| `data/ref_audio.wav` | TTS 参考音频 |
| `data/music_state.json` | 音乐播放状态 |
| `data/song_requests.json` | 点歌队列 |
| `logs/danmu_queue.log` | 主程序日志 |
## 弹幕链路排查
1. 确认 `config.json` 中 `room_id` 正确(浏览器打开直播间,URL 中数字)
2. 确认 `sessdata` 有效:看日志是否有 `SESSDATA有效, 账号=xxx`
3. 确认 WebSocket 连接:看日志是否有 `认证成功,开始监听弹幕`
4. 发弹幕测试:在直播间发 `帮助`,日志应出现 `[弹幕] 用户(uid): 帮助`
5. 如连接断线(`WinError 10013`),用管理员权限启动程序
6. DEBUG 统计:日志每 60 秒输出 `[弹幕统计] 收到N个raw | 解析N个包 | OP_MESSAGE=N | 提取弹幕=N`