实现Jitsi SFU自动关闭/启动视频层
本文来自Jitsi Videobridge SFU的后端开发人员之一Brian Baldino,他过去在思科和Highfive工作过,拥有丰富的视频会议产品研发经验。他分享了在Jitsi实现自动减少转发视频层,从而降低客户端CPU和带宽使用。LiveVideoStack对原文进行了摘译。
文 / Brian Baldino
译 / 元宝
审校 / Ant
原文 https://webrtchacks.com/suspending-simulcast-streams/
对高流量的流控制(来源:usbr.gov)
大多数人可能都熟悉典型的SFU风格的用户界面,该界面最初是在Google Hangouts的消费者市场中推广的,并由Jitsi Meet和其他服务部门使用。绝大多数屏幕空间的正面和中心是当前活跃的演讲者的视频。所有其他参与者都可以在他们自己的缩略图中看到,通常在右侧或底部。我们想让活跃的演讲者的视频在中间看起来很棒,因此分辨率很高。底部/右侧的缩略图会很小,因此高分辨率会浪费带宽。为了优化这些不同的模式,我们需要每个发送者视频的多个分辨率。值得庆幸的是,这已经是一个用联播解决了的问题!
通过联播,所有发送者编码3种不同的分辨率并将其发送到SFU。SFU决定将哪些流转发到每个接收器。如果参与者是活跃的发言者,我们会尝试并将他们发送给其他人的最高质量的流转发到他们的主界面上。如果要在右侧的缩略图中看到参与者,那么我们就会转发他们的最低质量的流。
联播权衡
联播是优化下载带宽的绝佳机制。然而,与生活中的大多数事情一样,联播涉及权衡——编码3个流比编码单个流需要占用更多CPU。您可以在下面的chrome:// webrtc-internals统计信息中看到这一点,其中使用联播的CPU使用率提高了几个百分点:
没有联播的CPU使用率
使用联播的CPU使用率
它还涉及发送更多比特数:
在没有使用联播时的发送比特率(~2,5M比特/秒)
使用联播时的发送比特率〜(3M比特/秒)
这些图表是由chrome:// webrtc-internals自动缩放的,因此请注意y轴刻度可能不同。请查看实际的y轴值。
流暂停
那么这是否意味着联播对用户来说效率较低呢?相反,由于我们可以单独控制联播的流,因此联播使我们有机会通过关闭不使用的层来节省CPU和比特数。如果你不是活跃的发言者,则根本不需要3层中的2层!
让我们看看当我们关闭前2层时的使用率:
CPU使用率
没有使用联播的CPU使用率基线
具有3个联播流的CPU使用率
禁用前两个层的联播的CPU使用率
每秒比特数
没有使用联播的发送比特率基线
使用3个联播流的比特率
禁用前两个层的联播的比特率
对于客户端和SFU上的负载来说,这是一个巨大的胜利!
实施暂停
现在让我们看看我们是否可以将其集成到实际代码中。这里有两个问题需要解决:
1.在SFU上——弄清楚何时没有使用流并让客户知道
2.在客户端——在不使用流时关闭流,并在需要时再次启动它们
SFU
第一个问题很容易解决——当客户成为活跃的发言人时,客户端会明确地请求参与者提供高质量的流,这样我们就可以告诉发送者何时使用高质量的流以及何时不通过数据消息通道。
客户端
第一次尝试
我们也想到了第二个问题。我们知道Chrome会在可用带宽下降时暂停联播流的传输,那么如果我们只限制可用带宽会发生什么呢?我们可以通过在远程SDP中设置带宽限制来实现此目的:
使用SDP限制最大发送带宽
在 b = AS 的那一行将可用带宽限制到200kbps。让我们试一试,看看会是什么样子:
SDP限制带宽后的CPU使用率
SDP限制带宽后的发送比特率
太棒了!这正是我们所希望的:它与我们之前的测试结果相匹配!现在让我们移除上限以模拟某个人成为活跃的发言者并且我们想要他们的高质量流:
移除上限的CPU使用率
移除上限的发送比特率
移除上限的发送帧的高度
话说回来,还有一个问题......整个过程需要30秒才能恢复到高质量。这意味着当某人成为活跃发言人时,他们在主舞台上的低视频质量将至少持续30秒。这不行,那么为什么这么慢呢?
如果你曾经使用Chrome进行过网络损伤测试,那么你知道它会应用大量逻辑来防止监控。由于担心丢失数据包,因此提高发送比特率是非常谨慎的。我们基本上通过我们的SDP参数完成的工作是让Chrome认为网络的数据包容量非常低(200 kbps),因此当我们删除它时,Chrome会小心地提高比特率,同时计算实际发送的数量。当网络出现问题时,这很有意义,但对于我们的用例,这是一个阻碍因素。
Google Meet测试
我们注意到当Google Meet正在使用时,我们首先开始讨论联播流暂停。我们来看看Google Meet电话会议的图表:
Google Meet上的CPU使用率上升
Google Meet上的发送比特率上升
Google Meet上的发送帧的高度
哇!它们下降并且非常快速地增加。他们是如何做到的呢?我们看了他们的SDP,他们正在使用b = AS上限。我们知道这不会让我们快速上升(正如我们在第一次尝试中看到的那样),所以他们肯定还做了其他事情。
我们看了一下chrome:// webrtc-internals并注意到了这一点:
使用webrtc-internals调查Google Meet
这个addStream可能看起来没有什么作用,但它不是在调用的开始,它在中间的位置,当我们希望流恢复时,那么这里发生了什么呢?正在添加另一个视频流,但没有一个被删除,这是如何工作的呢?它与比特率快速上升有关吗?
所以我们仔细看了一下,发现了一些细节。这是参与者首先将其媒体流添加到 peerConnection的位置:
以下是当我们想要提高比特率时的addStream:
所以我们在这里可以看到轨道ID是相同的但是流ID是不同的。这让我们想起了Chrome如何为新创建的流提供一个免费的时间段,其比特率可以很快提升; 这样,当你加入通话时,你可以快速开始发送高清视频。我们怀疑,新流的自由上升期是这里所利用的,当参与者成为活跃的演讲者时,让流看起来是新的。
尝试2
根据对Meet的调查,我们开始使用独立的WebRTC演示应用程序尝试重现其中的行为。通过这样做,我们能够在我们的测试环境中重现相同的行为:
复制媒体流
将复制的媒体流添加到对等连接
Munge SDP从新流中删除新的ssrcs / stream信息并将其替换为原始信息。
但我们还没有在实际的Jitsi调用中尝试它,测试环境是点对点的,并没有使用联播,所以我们不确定它能移植到Jitsi并工作。曾经我们尝试或,我们发现我们没有得到快速上升。它很慢,就像以前一样只有带宽上限。我们开始对此进行调试,并认为它可能与我们在SFU上的速率控制中的某些因素有关,这会阻止比特率快速上升。
在我们进一步发展之前,出现了一种新的可能性。
尝试3
WebRTC团队最近推出了关于RTCRtpSender的PSA。支持修改登陆Chrome 69的编码参数。这有一个API,可让我们控制各个联播编码,包括它们是否已启用!所以,当我们发现我们不能进入主界面时,客户端可以这样做:
应该禁用前2层,让我们看看它的表现:
CPU通过RtpSender参数丢弃没有使用的层
通过RtpSender参数丢弃没有使用层的发送比特率
我们没有像以前那样下降,但它仍然是一个很大的进步!但是,让我们看看当我们重启它们时如何提升:
CPU使用率上升
发送比特率上升
发送帧高度上升
哇!比特率立即上升了!这将完全适用于有源扬声器切换。我们不会在Chrome 69之前获得此功能,但它是一个好的解决方案,并为我们提供了我们想要的东西:当流不使用时快速降低比特率,并在我们再次需要时快速恢复。
今天就试试看Jitsi Meet,将#config.enableLayerSuspension = true添加到你的URL(只要你使用Chrome v69 +)或查看Jitsi Github中代码。
实现Jitsi SFU自动关闭/启动视频层相关推荐
- JS视频| DOMException: 无法启动视频源(DOMException: Could not start video source)
JS视频| DOMException: 无法启动视频源(DOMException: Could not start video source) 问题 DOMException: Could not s ...
- 海思 hisi SDK中视频层号和通道号的理解
SDK 将通道归属于视频层管理,一个视频层上可显示多个视频,每一个视频显示区域称为一个通道,视频被限制通道内,通道被限制在视频层内.对于一个视频层,其上面的通道都是独立的.同时,不同的视频层上的通道也 ...
- 海思 关于视频层和通道的认识
一.视频层和通道号的关系 SDK 将通道归属于视频层管理,一个视频层上可显示多个视频,每一个视频显示区域称为一个通道,视频被限制通道内,通道被限制在视频层内.对于一个视频层,其上面的通道都是独立的.同 ...
- Android高工必备:说说从手机开机到APP启动FrameWork层的整体执行流程
引言 本文讲解从开机到app显示画面的流程,但不分析源码,如果想阅读源码请到参考文章中查阅. 纸上说来终觉浅,建议有时间的小伙伴去我的B站观看视频讲解:Android进阶:手机开机到APP启动中间Fr ...
- android 启动视频,android 启动页面全屏播放视频
有时候大家在启动软件的时候,会看到有一个比较炫酷的短视频,觉得很有意思,现在做项目的时候也遇到了,跟大家分享一下. 首先,在 res 目录下建一个文件夹 raw, 把你的视频文件(.mp4等)放进去. ...
- UEFI启动视频详解:启动分析+N项操作实例
============================================================= ※※※※最给力的视频解说※※※※ 2011hiboy全部共享资料:立刻去 ...
- SRS之SFU多人视频
以下不是WebRTC推流和播放,而是两个人一对一的通话 介绍 修改SRS启动配置文件 go环境安装 signaling信令服务器 httpx-static代理服务器 介绍 WebRTC是通信的能力,从 ...
- 基于pion生态的SFU实时音视频发布服务(一)
pion是google 大佬Sean-Der开源在github.com上的性能优异的基于golang开发的webrtc协议栈,同时他也是aws kvs的代码主要维护人,目前有两大sfu基于此构建ion ...
- cocos2d video视频层放置ui
最近在做ios的视频播放,发现ios的视频播放永远都是置顶的,但是我们要在上面放置跳过按钮那些就实现不了,研究了一下相关文档还挺多,但是我试了都不行,最后被我自己琢磨出来了,分享一下. 第一步:App ...
最新文章
- 方便的boost_python
- servlrt程序的入口点是_刚刚,微信偷偷更新,小程序又放大招了!
- 身体曲线如何反映出健康
- vue中src文件夹下各文件_Win10下与虚拟机中的linux共享文件夹
- oracle全文检索 分区表,oracle全文检索
- hibernate中one-to-many实例一
- 【通信】基于matlab FDTD法研究移动通信终端电磁辐射对人体的影响【含Matlab源码 761期】
- JAVASE8.0的安装和配置
- 一位平凡毕业生的大学四年
- 怎么使用水经注万能地图下载器制作百度行政区划个性化地图
- 一个点的经度和纬度,以这个点为圆心,1000米为半径,最大的经度和纬度,最小的经度和纬度
- Webstorm查找替换快捷键
- 结绳计数——最原始的备忘录
- 莫名骨痛,警惕骨转移
- 【PTHREAD】线程退出与取消
- 打造Android的中文Siri语音助手(一)——小I机器人的接口
- HTML垂直对齐方式
- 6:直角坐标系象限判断
- JAVA编程实战之编写小游戏-大球吃小球(eat ball game)
- 生字癖用计算机,那些因为太复杂没被收录的生僻字,终于被录入电脑
热门文章
- kubernetes学习笔记 (二):k8s初体验
- 使用Apache Common Daemon实现Windows服务
- storm 动态设置并发度
- 网络编程中如何得知一次请求(或响应)的数据已接收完
- 只允许特定的组用户su切换到root
- 关于iframe的contentDocument和contentWindow
- jquery post 同步异步总结
- hibernate JPA 双向多对多 bi-directional many-to-many association
- 求【javascript设计模式】【高性能网站建设指南】PDF!哪位有给下啊!!!
- C++对自定义结构体变量排序