
埃格(Egor)关上笔记本电脑的盖子,从睡眠不足的地方擦了擦红眼睛。 “客户继续抱怨流被冻结,新的修订包根本没有帮助!那么这个(经过审查的)HLS怎么办?” 他说书房无效。
浏览器不仅是超文本,而且是流媒体
浏览器已经获得播放器很长时间了,但是使用视频编码器和流式传输的故事却有所不同。 现在,在几乎所有最新版本的浏览器中,您都可以找到用于编码,流传输,解码和回放的模块。 这些功能可通过JavaScript API使用,其实现称为Web实时通信或WebRTC。 该内置在浏览器中的库可以做很多事情:从内置的虚拟或USB摄像机捕获视频,用H.264,VP8,VP9编解码器压缩,然后通过SRTP协议将其发送到网络,即 用作软件视频流编码器。 结果,我们看到一个浏览器具有与ffmpeg或gstreamer类似的功能,可以很好地压缩视频,在RTP上播放流并播放视频流。
WebRTC使您可以自由地在JavaScript中实现各种流传输案例:
- 将流从浏览器流传输到服务器以进行记录和后续分发
- 点对点
- 播放其他用户的视频流并发送自己的视频聊天
- 服务器转换其他协议,例如RTMP,RTSP等,并以WebRTC的形式在浏览器中播放
完善的流控制脚本可能如下所示:
HLS在WebRTC不起作用的地方工作
WebRTC可以在最新版本的浏览器中运行,但是,有以下两个因素:1)并非所有用户都及时更新浏览器,并且可能会在某种类型的Chrome上使用三年。 2)几乎每周发布一次更新,并使用新的浏览器,WebView以及可以上网的其他客户端和即时通讯程序。 不用说,并不是所有人都支持WebRTC,如果支持的话,它可能会被截断。 看看现在情况如何:

头痛不已-每个人都喜欢的苹果设备。 他们最近获得了对WebRTC的支持,有时与Orthodox Webkit浏览器相比,其行为令人惊讶。 在WebRTC无法正常工作或无法正常运行的地方,HLS可以正常工作。 在这方面,需要兼容性,并且类似转换器的东西会将WebRTC转换为HLS并在几乎所有设备上播放。
最初,HLS并不是为实时流而设计的。 确实,通过HTTP的视频时间是多少? HLS的任务是将视频切成小块,并通过逐个下载将它们平稳地传递到播放器,而不会着急。 HLS播放器要求严格构成和流畅的视频流。 这里出现了冲突,因为WebRTC相反会由于实时要求和低延迟而使其自身丢失数据包,并且具有浮动FPS / GOP和可变比特率-就流的可预测性和维数而言,这与HLS完全相反。
一个明显的方法-WebRTC拆包(SRTP)和随后的转换为HLS,可能无法在本机Apple HLS播放器中工作,也可能无法以带状装饰的形式工作。 这里的本地播放器是指在Apple iOS Safari,Mac OS Safari和Apple TV中使用的播放器。
因此,如果您注意到本地播放器中的HLS带状装饰,也许就是这样,并且流的源是WebRTC或标记不均匀的另一个动态流。 此外,在实施本机Apple播放器时,有些行为只能凭经验来理解。 例如,服务器应在返回m3u8播放列表后立即开始发送HLS段。 每秒延迟会导致冻结。 如果在此过程中更改了比特流配置(这在WebRTC流式传输中是很常见的情况),那么也会有麻烦。
对抗本土玩家的fr带
因此,HLS中直接诚实的WebRTC拆包和打包通常不起作用。 在Web呼叫服务器(WCS)流视频服务器中,我们以两种方式解决该问题,并且我们提供了第三种方法:
1)转码。
这是使WebRTC流符合HLS要求,设置所需GOP,FPS等的最可靠方法。 但是,在某些情况下,转码不是一个好的解决方案,例如,对VR视频的4k流进行转码是个好主意。 就CPU时间或GPU资源而言,如此繁重的流代码转换非常昂贵。

2)在HLS的要求下,WebRTC流的适应和调整是即时的。
这些是特殊的解析器,用于分析H.264比特流并针对本机Apple HLS播放器的功能/错误对其进行更正。 在这里,我们必须承认,诸如video.js和hls.js之类的非本地播放器更能容忍具有动态比特率和FPS(即WebRTC)的流,并且不会放慢Apple HLS的参考实现永久冻结的速度。

3)使用RTMP代替WebRTC作为流源。
尽管事实上已经淘汰了闪存,但是RTMP协议仍被积极地用于流传输,就像OBS Studio一样。 而且我必须承认,RTMP编码器产生的流通常比WebRTC还要均匀,因此实际上在HLS中不会产生条带,即 从of带的角度来看,转换RTMP> HLS看起来更合适,包括在本机HLS播放器中。 因此,如果从桌面和OBS执行流传输,则最好将其用于转换为HLS。 如果源是Chrome浏览器,则RTMP必须安装插件才能使用,而无需安装插件。

上面介绍的所有三种方法都经过测试并可以工作,因此有机会根据任务的条件进行选择。
WebRTC到CDN上的HLS
当多个WebRTC流交付服务器位于WebRTC流源与HLS播放器(在我们的情况下,基于WCS服务器)中的CDN之间时,在分布式系统中可能会遇到一些麻烦。 看起来像这样:有一个Origin-一个接收WebRTC流的服务器,还有一个Edge-分发包括HLS在内的流的服务器。 可以有许多服务器,这可以实现系统的水平扩展。 例如,可以将1000个HLS服务器连接到一个原始服务器,在这种情况下,系统容量将扩展1000倍。

这个问题已经被发现了,并且这个问题通常出现在本地播放器中:iOS Safari,Mac OS Safari,Apple TV。 原生是指可以直接指示标签中播放列表网址的播放器,例如<video src="https://host/test.m3u8"/>
。 一旦播放器请求播放列表,并且此操作实际上是播放HLS流的第一步,则服务器必须立即无任何延迟地开始发送HLS视频片段。 如果服务器没有立即开始提供分段,则播放器确定他被欺骗并停止播放。 同样,这种行为是Apple本地HLS播放器的典型现象,但我们无法告诉用户-“请不要使用iPhone Mac和Apple TV播放HLS流”,用户将无法理解。
因此,当您尝试在Edge服务器上播放HLS流时,该服务器应立即开始返回段,但是如果没有流,它将如何处理? 确实,当尝试在此服务器上播放流时丢失了。 CDN逻辑基于延迟加载的原理-在有人在此服务器上请求此流之前,我们不会将流驱动到服务器。 第一个连接存在问题-第一个从Edge服务器请求HLS流并且不计后果地从Apple本机播放器执行此操作的人将受到限制,因为从Origin服务器订购此流需要一些时间才能获得它在Edge上继续进行HLS切片。 即使需要三秒钟,播放器也不会保存它。 他会发呆的。

这里又有两个决定隐约可见:一个是正常的,另一个不是很大。 有人可以放弃CDN中的延迟加载方法,而将流量发送到所有节点,而不管那里是否有查看者。 一种解决方案,可能适用于流量和计算资源不受限制的用户。 源将驱动所有边缘服务器的通信,因此,所有服务器以及它们之间的网络将不断加载。 也许此方案仅适用于少量输入流的某些特定解决方案。 当复制大量线程时,这种方案显然将导致资源效率低下。 而且,如果您还记得我们仅解决了“从本机浏览器进行首次连接的问题”,那么很显然,这是不值得的。

第二个选项更优雅,但也可以解决。 我们为第一个连接的用户提供了一个视频图片,但这仍然不是他想要看到的流-这是一个预加载器。 由于我们现在必须立即提供某些东西并立即进行操作,但是我们没有源流(仍是从Origin订购并交付的),因此,我们决定请客户稍等一下,然后向他展示带有动态动画的预加载器的视频。 用户等待几秒钟,预加载器旋转,当实际流到达时,用户开始显示实际流。 结果,第一个用户看到了预加载器,随后的用户终于看到了来自CDN的正常HLS流,这是按照延迟加载的原理进行的。 工程问题解决了。
但还没有结束
似乎一切正常。 CDN正在运行,HLS流是从边缘边缘服务器获取的,并且解决了首次连接的问题。 这是另一个陷阱-我们将预加载器的宽高比固定为16:9,而CDN可以包含任何格式的流:16:9、4:3、2:1(VR视频)。 这是一个问题,因为如果您为播放器提供16:9格式的预加载器,并且有序流将为4:3格式,那么本机播放器将再次等待刷新。
因此,出现了一个新任务-您需要知道流以什么纵横比进入CDN,并以相同的比例提供给预加载器。 WebRTC流的一个功能是在更改分辨率和代码转换时保留宽高比-如果浏览器决定降低分辨率,则以相同的比例降低分辨率。 如果服务器决定对流进行代码转换,则它将纵横比保持相同的比例。 因此,如果要显示HLS的预加载器,则以与流进入时相同的纵横比显示它是合乎逻辑的。

CDN的工作方式如下:当流量进入原始服务器时,它将向网络上的其他服务器(包括边缘服务器)通知新流。 问题在于,此时,源流的分辨率可能还未知。 分辨率由H.264比特流配置以及关键帧承载。 因此,边缘服务器可能会接收到有流的信息,但不会知道其分辨率和宽高比,这将使其无法正确生成预加载器。 在这方面,仅当存在关键帧时,才需要用信号通知CDN中是否存在流-这可以确保提供边缘服务器的大小信息,并允许生成正确的预加载器,以防止出现“第一个连接的查看器问题”。

总结
在本地Apple播放器中播放时,将WebRTC转换为HLS通常会带来麻烦。 通过对H.264比特流进行分析和调整使其符合Apple的HLS要求,可以解决该问题,可以进行代码转换,也可以使用向RTMP协议和编码器的迁移作为流源。 在具有延迟加载流的分布式网络中,存在第一个连接的查看器的问题,该问题使用预加载器并确定原始服务器端(CDN中流的入口点)的分辨率来解决。
参考文献
Web呼叫服务器 -WebRTC服务器
低延迟WebRTC流 CDN-基于WCS的CDN
通过HLS播放WebRTC和RTMP视频流 -服务器功能可将流从各种来源转换为HLS