视频直播的一点技术细节

虽然以前自己总觉得写博客就要写出能展开讨论的个人观点来,RTFM 的事情就没必要浪费时间。不过偶尔想想自己在 HOWTO 式的博客里受到的帮助,说不定试着写写也会有点价值呢,是吧。

所以我在这里就把自己从开始尝试直播到现在的技术方面的细节知识都记下来,不管这会有什么用。

由于我自己用的操作系统是 Archlinux,下面的内容涉及到具体软件的部分仅对 Linux 用户有意义。

个人知识与能力

首先你需要有能通过 Google 独立解决问题的能力,或者有一个任劳任怨的技术工作者能替你做这些事情。不过现在国内一些直播平台推出了自己的直播视频编码&传输客户端,技术上的问题可能会少一些吧。但真正诡异的疑难问题还是得有点搜索能力才能解决的。

永远不要指望自己可以通过在线的语音/文字聊天的方式来联系别人解决问题,除非你运气很好。

运营商

国内虽然一般认为只有联通和电信是骨干网运营商,其实大一点的直播平台也是有铁通/移动的推流服务器的。只要你乖乖地用运营商提供的 DNS 服务器来解析推流服务器 IP 就行。因此用铁通/移动的网并不是太大的问题。

上行带宽

上行带宽要多少够用?4000 kbps 就已经达到了 DVD 画质,2000 kbps 有些国内小水管都可能会看着开始卡。而我自己的视频输出压缩到 1280x720@30Hz 的质量时,ffmpeg 报告的实际码率就已经达到了 1700+ kbps。Youtube 推荐的 720p 质量对应码率是 2500 kbps。具体所需的码率还是要按照你能接受的视频质量和观众的网络条件来权衡。

线路质量

如果需要使用路由器,最好还是能用网线去连路由器,而不是 wifi。我以前用 wifi 凑合播的时候 ping 路由器动辄都要上百毫秒。最新的 802.11ac 技术不知道能否在这方面有所改善,但升级链路的成本总比插根网线高多了。

MTU 设置与路由器

理论上 MTU 值越大越好,不过执行 PPPoE 拨号的节点会卡在 1492 这么大。提前把本机的网卡 MTU 也改成 1492(或者更小,我自己用的是 1454,为了能访问一些 HTTPS 网站时不出现问题)可以避免因路由器重新拆/封包而消耗路由器计算资源。毕竟消费级路由的硬件水平高不到哪里去。

视频编码

这方面我完全是照搬了 https://github.com/wargio/Twitch-Streamer-Linux 中的参数。值得一提的是 Twitch 推荐的视频码率要选择 CBR 而不是 VBR,并给出了详细的解释。国内的直播平台一般都会给一张编码软件(比如 OBS)的设置截图了事,而截图中的 CBR 选项往往是不选中的。

再就是没必要按照视频源(比如桌面)的分辨率来决定输出视频的分辨率。把 1600x900 的桌面压缩到 1280x720 的视频输出就够满足大多数观众的质量需求了。

音频输入

对我来说 PulseAudio 是目前最好的音频录制管理方案。一来 ffmpeg 对 Pulse 有足够好的支持,可以直接以 `-f pulse -i LiveAudio.monitor` 的方式读取音频输入。二来因为要用 wine 跑 WoT,而 wine 目前又不直接支持 jack,用 alsa 设置起来又摸不着头脑。所以最终才选定了 PulseAudio。

Pulse 的 module-loopback 模块可以满足“把某个 source 复制一份并输出到另一个 sink”的需求。因此为直播单独创造一个 null sink,然后把麦克风和桌面声音都 loopback 送过去就好。

# ~/.config/pulse/default.pa
load-module module-null-sink sink_name=LiveAudio sink_properties=device.description=“LiveAudio”
load-module module-loopback source=alsa_input.pci-0000_00_1b.0.analog-stereo sink=LiveAudio
load-module module-loopback source=alsa_output.pci-0000_00_1b.0.analog-stereo.monitor sink=LiveAudio

文字公告

如果需要在视频里加入文字公告,理论上 dzen 应该是个不错的方案。不过为了支持真半透明背景色,我还是用 urxvt 去显示文字了。这一方案较适合常驻的公告信息(如 BGM 名字)

另一个方案就是用 HTML 布局文字&图片,用 phantomjs 渲染成透明背景色的 PNG,最后交给 pqiv 来显示图片(因为并非每个看图软件都支持透明背景)。这一方案更适合临时的公告信息(如临时 AFK)。

不管用哪一种方案展示文字公告,都需要注意文字颜色和背景色的对比。一般来说游戏场景都是暗色调,那么文字颜色以淡蓝色为宜 —— 既能有很好的辨识度又不至于鲜亮刺眼。再就是考虑给文字加上阴影会比没阴影的好看很多很多。

如果你需要给观众传递网址,而且网址的内容需要用手机来访问,那么最好能用二维码图片。如果不需要支持手机访问或者嫌二维码图片太占空间,那么也最好事先用一个可以支持自定义网址的短网址服务,生成容易阅读&输入的短网址。减少观众的认知负担。比如我自己使用的 http://bit.do/whyme-wot 。再就是自己直接把网址发到评论里让观众自行复制也行。

观众评论

你需要一个单独的显示器来观看观众评论。接收评论的软件必须能持久且完整地显示观众评论,当然字体大小也要合适。B站直播目前在这方面做得较好,是因为官方网站上提供的非官方弹幕姬是开源的,这样我可以去读传输协议,自己实现一个自己最满意的显示方案……

大致就这么多。

=======