在 Linux 上把游戏画面推到 B 站:OBS 搭建步骤与一次 AI 主播实验的复盘

游戏能运行、网页能看到桌面、OBS 显示正在推流,是三件不同的事。观众最终看到的,必须是正在玩的那个游戏窗口;音乐、字幕和角色动画,都不能替代这件事。

这篇文章来自一次 Linux 游戏直播实验。实验曾完成 B 站收流、直播布局、背景音乐和弹幕回复的接入,后来也暴露出一个很直接的问题:采集链路还活着,游戏却停在“欢迎回来”页,观众持续看到的是入口页。这个问题在项目关闭前没有完成最终验收。

状态说明:实验服务、游戏、存档和专属网站入口已于 2026 年 10 月 17 日删除。本文于 10 月 23 日整理,未恢复任何服务,也未重新开播。 下文把可以按官方文档重新搭建的 OBS 基础链路,与已经删除源码的历史自定义模块分开说明。它不是原实验的一键安装包,也不证明游戏模型已经学会自主游玩。

先准备一条能验收的最小链路

先只保留三个环节:

可见的真实游戏窗口
        ↓ 实时窗口采集
OBS 场景合成、声音混音与编码
        ↓ 平台提供的推流地址和密钥
B 站直播间 → 独立观众端检查

游戏如果运行在远程桌面或容器里,先确认它有一个能持续更新的显示输出。浏览器远程桌面是访问游戏的一种方式;它不会自动成为稳定的直播采集源。不要把登录页、离线进度页或网页截图当成游戏视频。

本例适合有图形桌面的 Ubuntu 主机。历史实验使用 Ubuntu 22.04 和 OBS Studio 30.2.3;这个版本号是当时的运行记录,不是对当前最新版的判断。有 NVIDIA 显卡时可以检查 OBS 是否提供硬件编码器;没有合适的硬件编码器,也可以先用 CPU 编码完成基础录制验证。

安装 OBS,先在本地录一段

Ubuntu 的安装方式可参考 OBS 官方 Linux 安装说明:

sudo apt update
sudo apt install software-properties-common
sudo add-apt-repository ppa:obsproject/obs-studio
sudo apt update
sudo apt install obs-studio
obs --version

上述命令会安装仓库当前提供的版本,不能重建某一天的完整软件环境。文章整理期间没有执行安装命令。

启动 OBS 后先新建一个独立配置文件和场景集合。先用自动配置向导跑通录制,再按机器的实际负载调整。为了便于排查,下面可以作为普通游戏画面的起始配置,不是原实验的性能测量结果,也不是 B 站对所有账号的固定要求:

项目起始设置
画布与输出1280 × 720
帧率30 FPS
视频H.264;可用时选硬件编码器
音频AAC,48 kHz
视频码率先试 3000–4500 kbps,再依据平台要求、上行带宽与掉帧调整
关键帧间隔先设 2 秒,最终以平台当前要求为准

OBS 的 快速入门 包含自动配置、来源、混音与录制检查。先录一分钟,回放确认画面和声音,通常比一开始就调直播接口更有效。

第一次操作,可以按这个顺序完成:

  1. 启动游戏,先进入真正可玩的界面,关闭欢迎页、登录页或离线收益弹窗。
  2. 在 OBS 的“场景”区域点 +,创建“游戏主画面”;在“来源”区域点 +,选择桌面会话支持的窗口或屏幕采集,明确选中游戏所在的窗口。
  3. 在预览里拖动、缩放来源,保持游戏比例,检查底部和四角没有被裁掉,再锁定来源。若截图里出现无限套娃,通常是把 OBS 自己也采集进去了,应重新选择来源。
  4. 进入“设置 → 音频”,检查桌面音频或独立应用音频的来源;不用真实麦克风时,禁用麦克风输入。先用混音器电平判断有没有声音,再以录制回放判断实际听感。
  5. 在“设置 → 输出”指定录制目录。首次可使用 MKV 容器,录好后需要 MP4 再通过“文件 → 录像转封装”转换;这是 OBS 官方建议的抗异常中断录制方式,不是平台推流格式要求。录制输出说明
  6. 点“开始录制”,在游戏里进行几次可见操作,约一分钟后停止并回放。画面、声音都正常,再配置平台推流。

两个画面怎样组织

主场景让游戏占大部分画面,侧边只放当前目标、下一步候选和少量聊天信息。另建一个观察场景,给状态、预测与实际结果更多空间,游戏窗口仍然保留。

主游戏场景                         观察场景
┌────────────────┬───────┐       ┌───────────┬────────────┐
│                │ 当前  │       │ 游戏窗口  │ 当前目标   │
│  真实游戏窗口  │ 目标  │       ├───────────┼────────────┤
│                │ 聊天  │       │ 实际状态  │ 预测 / 结果│
└────────────────┴───────┘       └───────────┴────────────┘

Linux 上按桌面会话选择实际可用的窗口采集来源:X11 常见窗口采集,Wayland 通常经由 PipeWire 和系统选择器。不要照搬仅适用于 Windows 的 Game Capture 教程。采集后把窗口缩放、裁剪到场景内,再锁定来源位置。

目标和聊天布局可以用 OBS 的 浏览器来源。它支持本地 HTML 或网页地址,适合做透明字幕和状态卡片。历史实验也是网页布局,但原始自定义前端已经删除,本文没有提供可恢复的整套前端代码。

在来源属性里填写自己的页面地址或选择本地 HTML,设置与布局匹配的宽高。需要持续更新时,检查“不可见时关闭来源”和“场景激活时刷新”是否符合预期。浏览器来源只给必需权限,不要为了显示卡片而给不可信页面控制 OBS 的权限。

有一个很容易踩的坑:底部游戏按钮被状态条挡住。排版时给状态区单独留空间,检查采集区域四个角和底边;不要只在自己常用的窗口尺寸下看一眼。

目标区应该显示什么

如果画面里有自动游玩的程序,建议显示它实际输出的、可以核对的信息:

  • 当前游戏状态与更新时间。
  • 本阶段目标,以及这个目标来自用户指定还是策略选择。
  • 下一步候选动作和预测的变化。
  • 动作完成后的真实结果,以及预测误差。

这些是决策摘要,不需要展示模型内部推理。没有真实数据就显示“暂未观测”或“数据已过期”,不要让主持人的语言模型根据聊天内容编造装备、首领进度或学习收益。

观测接口应当只读。直播主持人、弹幕回复和音乐队列不应该抢占游戏控制程序的指令通道。历史项目把解说服务和游戏控制分开,这一边界比主播说得多流利更重要。

游戏声、BGM 与合成语音分别处理

先分别播放一小段游戏声、音乐和合成语音,检查 OBS 混音器是否捕获了正确的来源。回放本地录制,确认没有回声和重复采集;如果不使用真实麦克风,就在 OBS 中关闭对应输入。

BGM 和语音回复最好有独立音量。主持人说话时适度压低音乐,结束后恢复;先保证能听懂,再考虑复杂的音频自动化。素材的授权说明也要保留,本文不重新分发原实验使用的角色、歌曲或语音模型。

历史实验接入过歌曲队列。需求是普通请求排队、礼物请求优先,但当前歌曲至少播放 60 秒。可以把规则写成独立状态机:

普通点歌 → 普通队列
礼物优先请求 → 优先队列

当前曲目不足 60 秒:先继续播放,到时间后再检查优先队列
当前曲目已满 60 秒:有优先请求时可切歌
曲目结束:优先队列 → 普通队列 → 默认播放列表

平台礼物事件和付费状态必须来自可靠的事件源,不能把聊天里的“我送礼了”当作付费凭据。未知歌曲要明确回复“曲库没有这首歌”,不能只确认接收,却让观众一直等不到播放。

证据边界:历史记录提到普通点歌、聊天回复与语音的联调,真实礼物优先流程没有完成完整端到端验证。原队列程序和逐条日志已删除,这里给的是需求和实现边界,不是可直接运行的点歌插件。

弹幕回复接入到哪一层

可以按下面的关系拆开:

平台事件 → 事件校验、去重
             ├─ 点歌命令 → 音乐队列
             └─ 提问 → 读取最新游戏摘要 → 生成回答 → TTS → OBS 音频

历史主持人曾使用 DeepSeek API 做对话和意图判断,TTS 使用本地 ONNX 推理,游戏的普通决策由另一套本地程序处理。两者不能混为“主播模型一边聊天一边学会游戏”。

如果观众说“看看装备”,回复服务首先要拿到真实装备信息。是否切换游戏页面,应交给已有的控制边界处理;拿不到信息时如实说明。观众建议可以记录为待核查项,不能绕过游戏程序原有的动作权限直接执行。

这些自定义服务已经删除,本文没有保留它们的安装入口。要重做完整 AI 主播,仍需另行实现和验证事件接入、状态接口、队列、对话与 TTS;只安装 OBS 不会自动得到这些能力。

从平台取得开播权限和推流参数

用自己的账号,通过 B 站当前支持的开播入口确认资格、完成要求的本人验证,并取得平台提供的推流参数。平台页面和账号权限可能变化,本文不把某次遇到的粉丝数提示或某个客户端接口写成通用规则,也不提供绕过本人验证的脚本。

在 OBS 的直播设置中选择平台支持的方式,或填写其提供的自定义推流服务器和密钥。两项应当分开填写,不要贴到公开配置、截图或终端演示里。

具体操作是打开“设置 → 直播”,按平台提供的参数填写服务器和串流密钥,保存后再开始推流。用另一台设备或独立观众端查看自己的直播间,确认平台已经正常开播,而不只是 OBS 的发送流量在增长。不要把自己的 OBS 配置文件直接打包公开,其中可能包含仍有效的推流凭据。

历史实验曾在开播时遇到返回码 60043,当时对应的是“需要本人身份验证”。这是那个账号、那次请求的实际反馈,不能据此断言所有账号每次都要验证;是否再次验证由平台的当前反馈决定。

怎样确认观众真的看到了游戏

本地录制通过后,再做一次短时的观众端检查。不要只看 OBS 的按钮状态:

  1. 在游戏中移动角色、翻一页物品栏,或执行一个能看出结果的普通操作。
  2. 从独立观众端确认变化已经到达,至少重复几次,记录从操作到观众看到变化的时间;这才是端到端延迟,不是局域网 ping 或播放器解码速度。
  3. 分别播放游戏声、音乐和语音,确认音量与同步。
  4. 发送一条普通弹幕,检查接收、回复和语音是否走完;确认测试消息没有混入真实观众统计。
  5. 切换主游戏与观察场景,确认它们引用的是同一个正在更新的游戏状态。

历史采集支路最后配置为 H.264/fMP4、20 FPS。这只是采集支路的配置口径,不能等同于 B 站观众端稳定达到 20 FPS。原始帧日志已删除,本文不补造平均帧率、延迟、码率或在线时长数据。

一个会动的头像、进度条和“服务在线”提示,只能证明这些部件在更新。游戏停在欢迎页时,直播仍然可能正常编码、正常收流。画面链路健康与游戏内容有效,必须分别检查。

常见故障,从离源头最近的地方查

看到的问题先核查什么
观众一直看到欢迎页或离线收益页原游戏是否已正常进入;不要先调编码参数
OBS 预览正常,观众端不更新平台是否仍在直播、推流连接和当前场景是否正确
状态卡片更新,游戏不动卡片心跳不能证明游戏窗口有效;单独检查采集来源
音乐正常,语音听不到TTS 是否实际产出音频、播放器输出到了哪个设备、OBS 是否采集它
有回声同一路音频是否同时经桌面音频与独立来源被采集
点歌收到回复却不播放歌曲是否在曲库、是否还在 60 秒保护期、队列状态是否真实可见
装备或进度回答不对回复使用的游戏摘要是否新鲜;不能用旧聊天推断当前状态
再次要求本人验证以平台当前官方流程处理,不能承诺脚本永久免验证

停止与清理,也要做完

结束时先在 OBS 停止推流,再确认平台房间已结束直播。随后停止本项目自己的事件监听、音乐播放器、TTS 和游戏控制程序,关闭其自启及定时任务。

如果你把这些程序做成了自己的 systemd 用户服务,可以逐个停用;下面的名称必须替换成你实际创建的服务,不是原实验脚本:

stream_unit='YOUR_STREAM_UNIT.service'
systemctl --user disable --now "$stream_unit"
systemctl --user is-active "$stream_unit"

再清理专属容器、存档、浏览器来源配置、推流凭据和临时音频设备。共享的 Steam 客户端、Python 环境、其他网站和全局缓存应分别核对归属,不要把整机清理当成卸载单个直播项目。

这次实验的可保留经验,是把真实游戏采集、状态展示、声音、弹幕与平台推流拆成可单独验证的部件。它也留下一个明确的失败边界:开播成功不能代替游戏内容验收,程序一直运行也不能代替模型确实学到了东西。

上一篇
下一篇