第一个观众问题,或将WebRTC视频流转换为HLS的困难


乔治关上笔记本电脑,揉了揉睡眠不足的红眼睛。 “客户继续抱怨流冻结;新的修复程序包根本没有帮助!我如何处理这个(经过审查的)HLS?” 他说。


浏览器不仅是超文本,而且是流媒体


浏览器拥有播放器已有很长时间了,但是故事与视频编码器和流媒体不同。 现在,在几乎所有最新版本的浏览器中,我们都可以找到用于编码,流传输,解码和回放的模块。 这些功能可通过JavaScript API使用,其实现称为Web实时通信或WebRTC。 这个内置在浏览器中的库可以做很多事情:从内置的虚拟或USB摄像机捕获视频,用H.264,VP8和VP9编解码器压缩,然后通过SRTP协议将其发送到网络; 即,它用作软件流视频编码器。 结果,我们看到了一个浏览器,它具有与ffmpeg或gstreamer类似的东西,可以很好地压缩视频,在RTP上播放流并播放视频流。


WebRTC使我们可以自由地在JavaScript中实现各种流情况:


  • 从浏览器流到服务器以进行记录和后续分发
  • 分发对等流
  • 播放其他用户的视频流并发送自己的视频流
  • 由服务器转换其他协议,例如RTMP,RTSP等,并以WebRTC的形式在浏览器中播放

完善的流控制脚本可能如下所示:


//Launching broadcast from browser to server session.createStream({name:”mystream”}).publish(); //Playing broadcast by the browser session.createStream({name:”mystream”}).play(); 

HLS在WebRTC不起作用的地方工作


WebRTC在最新版本的浏览器中运行,但是,有以下两个因素:1)并非所有用户都及时更新其浏览器,并且可能会使用Chrome的旧版本三年。 2)更新和新浏览器,WebView以及帮助用户上网的其他客户端和即时通讯程序几乎每周发布一次。 不用说,并非所有人都支持WebRTC,如果有的话,它可能会受到限制。 看看现在情况如何:



苹果公司最喜欢的设备可能让人头疼。 他们只是在最近才开始支持WebRTC,有时,与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段。 1秒的延迟可能会导致冻结。 如果在此过程中更改了比特流配置(这在WebRTC流传输中很常见),那么也会冻结。


与本土玩家抗争


因此,WebRTC拆包和HLS打包通常不起作用。 在Web呼叫服务器(WCS)流视频服务器中,我们以两种方式解决该问题,并且我们提供了第三种方法:


1)转码。


这是使WebRTC流符合HLS要求,设置所需GOP,FPS等的最可靠方法。 但是,在某些情况下,转码不是一个好的解决方案。 例如,对4k流进行转码
VR视频的确是个坏主意。 就CPU时间或GPU资源而言,这样的重量级流进行代码转换非常昂贵。



2)随时随地调整和调整WebRTC流程以符合HLS要求。


这些是特殊的解析器,用于分析H.264比特流并对其进行调整以匹配Apple本地HLS播放器的功能/错误。 不可否认,video.js和hls.js等非本地播放器对流的容忍度更高
动态比特率和FPS在WebRTC上运行,并且不会减慢Apple HLS的参考实现导致冻结的速度。



3)使用RTMP代替WebRTC作为流源。


尽管Flash Player已经过时,但RTMP协议已被积极地用于流式传输。 以OBS Studio为例。 我们必须承认,RTMP编码器通常可以产生更高的
与WebRTC相比,视频流的传输速度更快,因此实际上不会在HLS中引起冻结,即RTMP> HLS转换在冻结方面看起来更适合,包括在本地HLS播放器中。 因此,如果流是
使用桌面和OBS完成操作,则最好将其用于转换为HLS。 如果源是Chrome浏览器,则必须先安装插件才能使用RTMP,除非安装插件。



上面介绍的所有三种方法都已经过测试和工作,因此您可以根据任务选择。


WebRTC到CDN上的HLS


当WebRTC流源和HLS播放器之间有多个WebRTC流传输服务器时,在分布式系统中会遇到一些不良情况,在本例中, CDN基于WCS服务器。 看起来像这样:有一个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播放器执行此操作的人将被冻结,原因是订购该流需要一些时间
从原始服务器上,将其放在Edge上,然后开始HLS切片。 即使需要三秒钟,这也无济于事。 它将冻结。



在这里,我们有两种可能的解决方案:一种可以,而另一种则可以。 有人可以放弃CDN中的“延迟加载”方法,而将流量发送到所有节点,而不管是否有查看器。 一种解决方案,可能适用于流量和计算资源不受限制的用户。 源将向所有边缘服务器发送流量,因此,所有服务器和它们之间的网络将不断加载。 也许此方案仅适用于少量输入流的某些特定解决方案。 当复制大量流时,这样的方案将很明显
在资源方面效率低下。 而且,如果您还记得我们只是在解决“本机浏览器中第一个连接的用户的问题”,那么很明显,这是不值得的。



第二个选项更加优雅,但这也只是一个终结。 我们为第一个连接的用户提供了一个视频图片,但这仍然不是他们想要看到的流-这是一个预加载器。 由于我们必须已经给他们一些东西并立即进行操作,但是我们没有源流(仍在从Origin订购并交付),因此,我们决定请客户稍等一下,然后向他们展示有关
带有动画的预加载器。 当预加载器旋转时,用户等待几秒钟,然后当实际流最终到来时,用户开始获取实际流。 结果,第一个用户将看到
预加载器,然后连接的人最终将看到来自CDN的常规HLS流,该CDN以延迟加载的原理运行。 因此,解决了工程问题。


但尚未完全解决


似乎一切正常。 CDN正在运行,从边缘服务器加载了HLS流,并且解决了第一个已连接用户的问题。 这是另一个陷阱-我们给
预载器的固定纵横比为16:9,而任何格式的流都可以输入CDN:16:9、4:3、2:1(VR视频)。 这是一个问题,因为如果您将16:9格式的预加载器发送给播放器,并且有序流为4:3,则本机播放器将再次面临冻结。


因此,出现了一个新任务-您需要知道流以什么纵横比进入CDN,并将相同的比率分配给预加载器。 WebRTC流的一个特征是当
更改分辨率和转码-如果浏览器决定降低分辨率,则会以相同比例降低分辨率。 如果服务器决定对流进行转码,则它将纵横比保持在相同的比例。 因此,有意义的是,如果我们要显示HLS的预加载器,则以与流进入时相同的纵横比显示它。



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



总结


在默认的Apple播放器中播放时,将WebRTC转换为HLS通常会导致冻结。 通过对H.264比特流进行分析和调整使其符合Apple的HLS要求,可以解决该问题,方法是使用ranscoding,
或迁移到RTMP协议和编码器作为流源。 在具有流的延迟加载的分布式网络中,存在第一个连接的查看器的问题,该问题使用预加载器并确定原始服务器端(CDN中流的入口点)的分辨率来解决。



Web呼叫服务器 -WebRTC服务器


CDN用于低延迟WebRTC流 -基于WCS的CDN


通过HLS播放WebRTC和RTMP视频流 -服务器功能可将流从各种来源转换为HLS

Source: https://habr.com/ru/post/zh-CN481668/


All Articles