欢迎光临散文网 会员登陆 & 注册

单兵双机作战也能完成的纯OBS游戏比赛多视角导播台(以Apex Legends为例)

2023-07-21 00:26 作者:Aster_Studio  | 我要投稿

让我们思考一下曾经看过国内外各种大大小小的赛事,从ALGS到星空杯,甚至是没有解说的VeryApex Open训练赛,为了确保观众能够看到精彩的画面,总会安排多个OB视角,在主台进行包装和汇总,在发生交火时立即切换到捕捉到了画面的视角:

这篇文章是一个手记心得,记录了我如何在没有团队协作的情况下完成这种多时间的导播式直播,带给观众酣畅淋漓的观赛体验(指比ALGS导播切得好、切得快)。

多视角导播体系的问题在于,大型赛事直播通常OB机位都在同一个局域网内,他们有太多太多方法,无论是基于采集卡还是基于NDI,都能够做到无延迟、高质量的视频流聚合,但大家伙现在天各一方,中间相隔的网络太过于复杂了,如何跨越各种碍事的NAT把所有机位的视角聚集起来成为执行的难点。

条件梳

我需要先在这里列举一下这个体系想要完成的需求,以及拥有的条件:

需求

  1. 有一个导播台,将最多5个OB位聚合到一个屏幕上

  2. 解说需要根据导播台输出的Mainstage画面进行解说

  3. 将Mainstage画面和解说语音送到直播平台供观众观看

  4. OB与总台异地,受复杂NAT和上行带宽限制

  5. OB的计算机基础参差不齐,需要让他们都能弄懂方案

  6. OB位有时候会兼职解说

  7. 导播台自己甚至要输出一路Apex视角

  8. 导播台自己甚至有可能也要充当一下解说

  9. 导播台在推流的同时可能还要顺便录像

  10. 整套系统要在免费的非商用软件完成

条件

  1. 有一台性能足够强大的电脑,笔者是5900X + 64GB RAM + RTX3090

  2. 有能够使用的多路音频输出通道,笔者是Motu M4声卡 + Monster Audio,但是也可以通过Voice Meter等软件纯虚拟跳线实现

  3. 有2个或者以上的编码加速单元,笔者有NVENC + 一台核显笔记本的QuickSync,否则运行这套系统编码器可能会过载,推荐Intel Non F CPU + 4070Ti以上的N卡,或者双N卡(没有测试过,理论上可行)

  4. 一台服务器,然而带宽和计算能力都不高,也许你的服务器平常是用来托管网页之类的

  5. NAT比较优秀的家宽,或者有IPV6可用,上行带宽至少50Mbps

  6. 运营一个基于P2P打洞的内网穿透方案,比如Zerotier或者Tailscale/Headscale

  7. 快速稳定的LAN环境,比如1000Mbps有线或者WiFi6

系统架构

这个系统的核心架构,可以用“找补”来形容。一开始只聚合多机位,后来再考虑解说视角,处理完后又注意到太子流的音频回响问题,通过基础架构之上不断地patch以完成最终目的。


这套系统绝大多数消耗算力和需要进行工程处理的部分都在本机完成,甚至连OSSRS都搭建在本机。

具体来说,

  • 各个OB视角通过自己安装OBS客户端、添加游戏源和程序声音捕捉来完成自己视角的采集,并通过IPV6直连或者Zerotier内网将RTMP流送到本机的SRS上

  • OBS通过向localhost抓取OB源,和自己机器上的Apex视角整合到一起,做一些排版和切换动画工作,输出聚合太子流

  • 解说通过Zerotier或者IPV6直连,非Apple平台使用SRS控制台,Apple平台使用VLC,以完成最低延迟低获取到太子流并进行解说

  • 把解说Kook频道和本机的麦克风音频通过NDI发送到笔记本,把太子流RTMP也发送到笔记本,进行QSV二压,并送到直播平台

OB视角传输方式的选择

受制于上行带宽的画面传输是一个trade-off的艺术,大概就是画质、延迟、带宽组成的一个不可能三角:

在项目开始之前我本来打算尝试RTMP串流、WebRTC串流以及NDI传输,发现最后可选的手段只有高度优化的RTMP转发服务。

NDI

NDI无疑是Ethernet载体最优秀的视频流传输方案之一,几乎无延迟、画质损失肉眼不可感知,非常适合专业工作流,我本来都要选择它了,直到我在我的PC和笔记本之间的视频流传输测试发现1080P60会占用150Mbps以上的网络带宽,这种事情在外网是无法实现的。再加上NDI已经和NVIDIA构成合作,支持(并且默认调用)N卡硬解NDI,本身直播推流NVENC就需要占用一部分显卡资源,运行Apex更是消耗大户,显卡没法承受这种强度的压力。因此无论从性能还是带宽来看,NDI方案都只能直接告吹。

WebRTC

WebRTC笔者之前接触过开发,它实在是太诱人了,使用Webcam对话的时候延迟甚至不可感知,如果能用WebRTC来完成OB位的画面传输绝对无敌。

然而现实给了我狠狠的3棒子:

  1. 即使SRS支持该协议,WebRTC目前无法在OBS生态中推流,而且协议决定了推流强制需要HTTPS,而我们要上域名HTTPS必然会经过备案环节,浪费时间并且难以成功。

  2. OBS目前没有任何办法将WebRTC流作为媒体源输入

  3. WebRTC本身的设计目标并不是用于高保真直播,进而通过测试发现在高分辨率高码率高帧率回放时,会出现画面撕裂错位/被抽帧成30fps等问题,高保真视频流有点为难这个为视频会议而生的协议了

还有第4点,成熟的WebRTC直播方案现在都被各大商业公司握在手里等着我们给他们砸钱。


打通直连网络

为什么打通直连网络这么重要?因为我把SRS部署在本机上。

为什么要把SRS部署在本机上?因为我手头现有的服务器无论是地段、性能还是带宽配置都不足以提供RTMP转发服务,唉,唉唉。

加上我的服务器本来就跑了一个Zerotier Moon,PC性能又过剩,那为什么不把东西架在我的PC上,然后让他们调通内网穿透,直接访问我机器的服务呢?

事实上我也这么做了,招聘并确定了几个OB后,我写了一篇教程手把手地教他们怎么加入我的Zerotier网络,并且完成推流、解说、远程控制等等工作。照顾到可能有些朋友计算机基础一般,我甚至在搭建moon的时候省略了cmd操作,直接把moon配置文件给他们,让他们通过拷贝法部署:


事实上,当真正部署好网络之后,才发现NAT这个东西真的很复杂。

有的人在校园网里搭了一个路由器,结果古早年间的路由器不支持IPV6,即使Zerotier搭建好了能联通也被迫走IPV4链路产生不必要的多跳;

有的人的宽带网IPV4、IPV6齐全,但是Zerotier搭建好之后发现他无论通过什么方式都没法访问我的PC上的任何服务,甚至ICMP Ping也超时(怀疑UDP出口被限制)。我远程协助摸索了半小时发现Zerotier网络报废,最后IPV6地址直连反而能跑得通;

有的人读完了我的教程之后下载了moons.d,不选择复制文档里的路径,毅然决然地手敲目录,最后把moon放在了Program Files (x86)\Zerotier One里,发现没有粘贴权限。然后问我“文档里的Programdata文件夹我去C盘看没有,我要不要手动创建一个?”

总之,历经千辛万苦,所有OB位的网络都已经连通,所有OB都能够访问我的SRS控制台,进而能够进行后续的推流工作。

传输延迟的优化工作

传输延迟很大一部分来自于RTMP协议本身的包装和传输开销,在未优化的情况下默认推流延迟可能高达十几秒,我在两年前曾经顶着这样的延迟为部门开过一个游戏合家欢直播互动会,单向传播(主播玩游戏给观众看)体验尚可,但那一晚我忘不了的是互动环节,主播-转发-观众带来的十几秒延迟以及部分主播挂着直播频道产生的回声卷积带来的地狱级糟糕体验。

那时候我的推流用的是阿里云的直播服务。所以这一次我吸取教训,痛定思痛,决心尽我最大所能将延迟降到最低。

好在SRS考虑到了这个需求,官方就写了一个非常详细的文档(doc/low-latency)来科普并且教开发者与RTMP延迟相关的参数以及如何构建一个最低延迟直播配置。通过对Merged-Read、Merged-Write、GOP-Cache、Max Queue Length、TCP delay等参数的更改,使SRS能够达成理想情况下(网络传输时间和渲染时间都近似为0)RTMP单向推流-解码协议开销能够降低到0.65s

编码延迟的优化工作

编码延迟的优化体现在OBS编码器的设置上,我写了一篇详尽的文章教他们如何配置OBS,包括搭建纯净流场景和优化编码器,在这里直接引用:

引用之前我先自裁,下面的编码器教学教他们使用high profile,这会导致GOP的增加。相比使用main和baseline配置,high配置会让延迟增加0.25s。

另外,将最大b帧从2调整到能够带来大约0.1s的提升。


确保你的画布尺寸是1080P@60fps


!!接下来的编码参数教程里,如果你在XX大学使用校园网推流,那么校园网的上行带宽是低于10000Kbps的,你需要适当降低码率,否则会导致大量丢帧!!

根据热心校友的测试,暑假期间XX宿舍校园网支持的最高串流码率在8000Kbps附近

我们推荐编码器使用的顺序是QuickSync >> NVENC >>>>>> x264 >>>>>>>>>>>>>AMF

1. 假设你使用CPU软编码,那么我推荐使用CBR、10000码率、CPU预设veryfast、配置high、微调zerolatency

2. 假设你是有核心显卡的Intel系统,那么我强烈推荐使用QuickSync H.264编码器,CBR 10000Kbps码率、目标Speed、配置High、延迟ultra-low,其它看情况调整。

3. 假设你有一张GTX1660或者以上的显卡(在台式机平台,笔记本我不好说,因为没试过),那么推荐使用NVENC H.264编码,CBR 10000Kbps码率,预设P2(不用P1是因为Nvenc画质稍差),调节超低延迟,单次编码,配置High

  1. 关于音频参数,我推荐码率打到192Kbps,如果你是一个对音质有追求的人,你也可以拉到320Kbps,但是不建议低于160Kbps。

  2. 如果你的电脑性能比较捉急,那么可以尝试在推流时关闭预览:在非工作室模式下对视频窗口右键-将开启预览的勾勾去掉。

  3. AMD显卡的玩家可以准备/re了,直播生态与你无缘,AMF做了十年一直是一坨,如果你是Intel non F CPU请选择2方案,如果是Intel F或者Ryzen CPU请尝试1方案,发现性能较差(推流掉帧/游戏无法满足60fps)的话请升级CPU或者换一张N卡😋

解码延迟的优化工作

解码优化的工作来源于最后的联调。第一次真实环境的测试里我通过对时法发现,无论如何【广州—(RTMP)→深圳—(RTMP)→广州】(即OB视角→PC聚合流→主视角送给解说)的推流信号都有高达8秒的延迟,这个结果对于Apex这种节奏非常快的游戏是绝对不可容忍的。既然编码和传输的延迟已经尽力了,那么唯一能够调整的也只有解码端了。

经过测试我发现,VLC虽然全平台通用,但是为了回放质量默认情况下自带一个playback buffer,使得接收端产生约0.5s的延迟。VLC目前这个buffer支持的最低值是100ms,即有0.1s延迟不可避免,但预设的ultra-low latency模式也仅把buffer缩小到了333ms,也许100ms确实不适合绝大多数情况下的网络:

VLC on iOS

值得一提的是,SRS唯一的低延迟回放方案只有VLC,因为iOS的浏览器内核完全不支持Flash,因而任何基于flv.js的web端rtmp播放器都无法运行。

实际测试,无论是SRS控制台预览亦或是其它任何基于flv.js方案的rtmp播放器,都会固定比“最低延迟”设定的VLC快大约0.5秒。

0.52-0.12=0.4,背后的播放器是SRS控制台自带预览flv

可这才解决了0.5s,我和OB机器的TCP ping大约在5-20ms,双向推流延迟(0.65协议+0.02网络)*2+单客户端回放0.5=1.84s,那么我按照保守估计延迟大约2s,这离8秒中间还差了6秒去哪里了?

排除了所有的可能性后,可能性仅剩下OBS的媒体源了。当我把目光转移到OBS媒体源并进行测量后,惊奇地发现OBS媒体源的延迟大得就离谱,即使你设定了0MB的网络缓存也有差不多4s的延迟:

要注意,“最短回放时间”来源于异地推流,0.75s包含了对面的机器渲染、推流过来并解码的完整过程耗时

经过大量的尝试以后,我发现在“媒体源”里的“FFMpeg选项”栏里无论填写任何与ffmpeg降低回放延迟的参数,比如

等,均无任何效果,并且我去GitHub转了一圈obs的源码,意味着我们必须要寻找其它的替代方案。

在网络上搜索了一大圈,发现有一个obs-gstreamer插件也许有用,它借助gstreamer构建管道通过参数优化能够完成非常非常低延迟的rtmp回放,据称效果能够逼近flv.js。

来自Dx's Monkey Life

但是我经过多次尝试,更换搭配了各个gstreamer-mingw版本,在确保自己的PATH环境绝对没有问题,能够任意目录运行gstreamer组件的情况下,安装obs-gstreamer组件仍旧报错无法加载,也许是和obs29不太兼容。

那么我们可知的能够播放rtmp的来源只剩下VLC了,死马当活马医:

这下马还真活了,VLC里有个网络缓存的选项,与我们在APP里见到的如出一辙,它最低支持100ms,即便如此也只比flv.js慢了0.3s,相比原生媒体源的4s快了10倍多!(上面对比图的“优化输入时间”用的就是VLC源)

这就收回前面的伏笔了,为什么我要把SRS搭载本机上。因为我能够100%保证在我机器执行最多的回放行为是延迟最低并且绝对不会丢包的,任何流从localhost拉下来都能把buffer缩短到可允许的极限工况,比如在这里的100ms,我相信如果VLC允许,我能够再缩短到50ms甚至更低。

如果把SRS架在LAN以外的区域,我还真不能够保证100ms的buffer能够稳定回放。

至此,全链路优化完成,从OB推流解说观看这一段对延迟要求非常高的链路通过编码优化、网络优化、回放优化,将延迟从8秒缩短到能够符合基本交互和解说需求的2秒。至于后面的聚合解说语音推流到平台的延迟,再到平台观众观看的延迟随它去吧。

为什么单机体系宣告失败了

因为编码器过载。

我使用rtmp-multiple-output插件,试图将我的主视角流同时推送到SRS和直播平台,然后发现这个插件是双编码方案,同时运行会导致强如3090的NVENC也严重过载,即使分一路编码去x264也无法缓解,游戏帧数难以达到165、推流直播疯狂掉帧,并且调试后发现,将任意一路编码停下来都能够缓解直播和游戏的掉帧问题,就是没办法双编码输出。

然后我在考虑转发直播流:Nginx有内置的纯网络协议方法,但在Windows上部署Nginx未免有些脱裤子放屁,而且跟SRS功能冲突并且又需要大量的时间写config调试;SRS的forward方法与vhost绑定,纯IP使用的时候因为只有一个_defaultVhost_似乎无法完成转发(因为SRS的forward是面向edge或者集群的方案,与我们的工况需求并不一致)。

这也导致了我最后将主视角输出到直播平台的部分交给了笔记本处理,主PC仅推流到SRS,笔记本导入SRS的太子流,使用QSV进行二压并送到直播平台上(毕竟NVENC的压缩比众所周知偏低,用QSV二压到更低的码率也是合情合理,甚至可以走VBR为观众省流),完美地分担了计算资源的压力。


OB、解说、太子流的冲突与和解

一开始我搭建这套系统想让解说同时兼职OB位,大不了他们操作更加忙一点就完事了。可是有一个解说配合我调试完OBS之后问了我一个问题:

我们要看哪里解说呢?总不能在平台吧,延迟太大了……

把我问懵了,对啊,解说总得看一个总台吧,对着自己的视角解说那和以前的各自操作模式又有什么不一样呢?

太子流在这个时候才诞生,才产生后续的8秒回放延迟问题,可伴随而来出问题的不只有回放。

假设解说兼职OB只有1台机器,那么解说需要调整Apex Legends使得:

  1. 切换到后台时不掉帧

  2. 游戏声音与自己的讲话/解说频道语音独立开来采集

  3. 切换到后台时不静音

问题2能够通过OBS29新增的应用程序音频采集(测试)来源做到单独采集Apex的声音,问题3能够通过开启Apex设置-声音-背景声音完成,但是问题1无解。

Apex出于对硬件友好的考量,切换到后台之后会强制锁在10fps以降低显卡工作强度,目前不支持任何的设置/启动项/CFG参数进行修改,导致了解说兼职OB的方案直接破产。这意味着提供OB的机器必须时刻保持Apex在前台。如果想要继续兼职,必须要掏出一个副屏或者副设备,或者直接放弃供给OB位,直接做纯解说。

在此之后独立出来了太子流供解说专用。但在第二次联调测试的时候,有个解说兼OB一直在纳闷他自己讲话会有回声被打断,调了半天OBS以为闹鬼了,最后我说声音是我这里推出去的。

然后我想了一下,对啊,给解说看的太子流就应当是没有解说音频的!先抛开有解说使用外放导致回声卷积的可能性不谈,解说说着说着被自己的声音打断也确实非常影响体验。所以我们要把解说语音剥离,只有推送给直播平台的流加上语音。

于是在此处我发挥出了我的声卡机架优势,把KOOK输出到独立的声音通道中,并在OBS引入为全局音频设备,把他们挂到轨道2用于录像和后期。因为直播只能输出1个音轨,因此语音轨道将不会被送往太子流。

与此同时,我将这两路语音挂到可靠的好朋友NDI协议上,送到笔记本,由笔记本完成混合和推流到平台供观众观看。

此时,OB、解说与太子流达成了和解。为什么说和解?因为我们知道,在整套环路做到了极限的延迟优化后,解说与实时的游戏画面仍然存在大约2s的延迟,意味着他们的解说内容比我从PC推出去的画面慢大约1秒。那么这个时候,我在笔记本上的回放能够通过自由控制视频buffer长度以完成画面与解说延迟的匹配,达到一个相对和谐的程度。最后RTMP回放的延迟反而被利用起来以弥补语音的滞后。

与此同时,我甚至能够通过Dynamic Delay或者类似插件把我本机的Apex采集画面做延迟,与其它四个接收到的视频流的时间进行匹配处理,达成完美的时间同步!

我想明白这点的那一刻,整个系统飞升了。音画同步问题可控,甚至留有安全播出的调整空间,可以提前在笔记本进行掐断或者其它紧急处理,太绝活了!

远程控制权

OB到导播台的画面仍然存在0.75-1s的延迟,怎么样才能弥补这个延迟,尽量不错过第一时间的战斗场面呢?毕竟RTMP的开销0.65s,但机器之间的ping只有5ms,有办法通过视频以外的方法进行补救。

对的,就是websocket。我开启了本机的obs-websocket端口,并且允许ob在语音和导播(我)沟通确认并且自己先手通过websocket client切换场景:

image-20230721000310915
我查了一下电影制片团队构成,好像还真有这么个Director of photography的职位?

这样一来,一切由延迟导致的画面错过都将会不复存在。

一些混音与动效的小优化

在介绍混音与动效之前,应该首先展示一下主视角的布局:

视频画幅2400*1080,精确地塞下了1个主画面和4个副画面,通过切换场景来放大右边4个不同的机位,使用move-transition插件赋予动态缩放效果,以给观众连贯的变化感。

我喜欢用Circle运动曲线,在offset 2.00的情况下,500ms的动效观感与我第一喜欢的Material Design动画曲线非常类似,灵动且优雅。

这种场景搭配方法让每个场景所有媒体源都在播放,熟悉OBS的朋友都知道,这种情况下混音器的调整是与场景独立的,我无法做到在原生情况下把某个画面缩回去,它的声音随之变小,反之亦然。

但是OBS社区的朋友洞察到了这个需求,他们之中有个人做了一个Lua脚本,能够记住每个场景的混音器音量设定,并且随着场景自动切换:

这个脚本就是这套系统的点睛之笔,使最后一个混音难题成为了可能。

系统和赛事成果

这套系统我投入了大量的时间搭建和优化,从一开始的天方夜谭经过几十个小时的优化,达到真正能落地实战的程度,已经摩拳擦掌蓄势待发。

就是比赛到现在还没凑满60个人,没开起来,群里70来个人,每天发公告催他们填表报名打比赛,到现在就收到了30个选手的问卷💧

单兵双机作战也能完成的纯OBS游戏比赛多视角导播台(以Apex Legends为例)的评论 (共 条)

分享到微博请遵守国家法律