AcoFork 旧站归档 · 第 19 次重构 · 已归档,仅供怀旧展示
← 返回博客

如何在直播中让你的观众实时了解你在用什么软件?

通过持续监测当前前台进程和指定程序的窗口标题,并用 OpenGL 渲染一个透明悬浮窗,让 OBS 游戏源实时向观众展示你正在使用的软件、当前播放的歌曲,甚至播放/暂停状态。

如何在直播中让你的观众实时了解你在用什么软件?

引言

我在直播时,经常会被观众问到这些问题:

主播主播,你现在用的是什么软件?

主播主播,这是什么游戏?

主播主播,这首歌叫什么?

这些问题当然可以直接口头回答,但总觉得不够优雅。毕竟这类信息通常也不涉及隐私,完全可以交给程序自动展示。

于是我就开始琢磨:能不能做一个小工具,把 当前正在使用的软件正在播放的歌曲 之类的信息,自动同步给 OBS,再展示给直播间观众?

第一版:TXT + OBS 文字源

一开始我想到的是 OBS 的 文字源。它支持从文件读取内容,所以思路一下子清晰了:

只要让 OBS 持续读取一个 TXT 文件,再写一个小程序不断更新这个 TXT 不就好了吗?

这个思路完全可行。实测下来,OBS 会每隔几秒重新读取一次 TXT 内容。虽然它不是即时 Hook,而是简单轮询,但对于“当前正在使用什么软件”这类信息来说,已经完全够用了。

不过,只做实时进程显示,其实只解决了 “我当前正在用什么软件” 这个问题。

如果我还想进一步告诉观众:“我现在正在放什么歌” 呢?

所以我又补了一个功能:支持监测指定的 EXE,并实时读取这个进程的窗口标题变化。一般来说,不少音乐播放器都会把当前播放曲目写进窗口标题里。

那如果中途我把音乐软件关掉了怎么办?也很简单:在检测不到目标进程时,程序就向 TXT 写入一个零宽空格。这样 OBS 端看起来就像“空白”,不会残留上一次的歌曲名;等软件重新启动后,显示内容又会自动恢复。

更进一步:透明悬浮窗 + OBS 游戏源

文字源方案能用,但它有个小遗憾:没法做透明叠加。我平时用 VTube Studio 时很喜欢 OBS 游戏源的透明捕获效果——如果能让这些实时信息也以一个透明的悬浮层叠到画面上,观感会好很多。

而 OBS 游戏源捕获的是 渲染管线,不是普通桌面窗口。所以这个悬浮层必须真的用图形 API 画出来。于是我就用 OpenGL 写了一个窗口程序:

  • 一个普通的窗口:标题栏、最小化/最大化/关闭都有,可以随意拖动和缩放
  • 窗口里实时画两行字:当前进程(前台窗口标题 + 进程名)和 歌曲(目标程序的窗口标题)
  • 背景透明(逐像素 alpha),在 OBS 里用 游戏源 → 捕获特定窗口 指向这个窗口,就能把它透明地叠到直播画面上

这里有个有意思的细节:OBS 游戏源 hook 的是渲染引擎的交换缓冲(wglSwapBuffers),而不是窗口本身。所以就算我把这个窗口最小化,或者被其他窗口挡住,OBS 依然能捕获到它——只要进程在跑,内容就在渲染。

播放 / 暂停状态

一开始我以为只能靠窗口标题拿到歌曲名。后来发现,用 Windows 的音频会话(WASAPI)还能直接拿到 播放/暂停 状态:

  • 程序有活跃的音频会话 → 播放中,前面显示
  • 会话处于 inactive → 已暂停,前面显示

这个检测对任何播放器都通用,不依赖窗口标题。这样观众不仅能知道在放什么歌,还能看到是不是暂停了。

一些小细节

  • 窗口尺寸记忆:拖到什么大小、放在哪个位置,下次启动自动恢复
  • 等比缩放:把窗口拖小,两行文字会按比例缩小,超长的进程名也能在小窗口里完整显示
  • TXT 输出保留:第一版写 TXT 的功能还在,想继续用 OBS 文字源的话完全兼容

于是,这个小项目就这样迭代到了现在的版本:

afoim/process_watch2txt

Community notes

评论

评论来自 GitHub Discussions,登录 GitHub 后即可参与。