音视频互动开发中如何实现超低延迟的直播推流

音视频互动开发中如何实现超低延迟的直播推流

做音视频开发这些年,我发现一个有意思的现象:很多开发者一上来就问"用什么编码器好"、"选什么传输协议",却很少有人先停下来想想,延迟到底从哪里来的。这感觉就像我刚开始学做饭那会儿,总是纠结用什么锅,却连食材怎么处理都没搞明白。

今天我想用一种"拆解"的方式,把超低延迟直播推流这个事儿,从底层到上层,一层一层地聊清楚。不用那种堆砌专业术语的方式,就用我实际工作中踩过的坑、总结出的经验,说说怎么在音视频互动开发中真正把延迟降下来。

延迟到底是从哪儿来的?

在说怎么降低延迟之前,咱们得先搞清楚,延迟这个家伙到底藏在哪些环节。我把它们列了个表,可能看起来更清楚些:

td>解码

环节 典型延迟范围 备注
采集与预处理 10-50ms 包括摄像头采集、麦克风采样、降噪处理
编码 20-200ms 取决于编码算法和帧缓冲策略
网络传输 不确定 受物理距离、路由跳数、网络波动影响大
10-50ms 硬解码通常比软解码快
渲染 5-30ms 画面显示到屏幕的时间

你看看,上面这些环节加起来,轻轻松松就能飙到几百毫秒。这还是理想情况,要是赶上网络不好,那延迟能让你怀疑人生。

我刚开始做直播项目的时候,曾天真地以为只要码率够高、服务器够好,延迟自然就下来了。结果第一次上线测试,观众反馈说主播说话,他们要等将近一秒才能听到。那会儿我才明白,延迟不是某一个环节的问题,而是整个链路上的每一个节点都在"贡献"延迟。

采集端:别让第一步就掉链子

采集是整个链路的起点,这一步要是没做好,后面怎么优化都白搭。

先说视频采集。摄像头的预览模式设置很有讲究,如果你用的是Android平台,Camera2 API里有个很重要的参数叫MODE_RAW_SENSOR,虽然画质好,但延迟会明显增加。我自己的经验是,大多数互动直播场景,MODE_ZERO_SHUTTER_LAG反而更合适,它在延迟和画质之间有个不错的平衡点。

音频采集这边,情况有点不一样。采样率不是越高越好,48kHz对于人声互动来说完全够用了。你要是非得用96kHz,文件大了不少,但听感上的提升几乎可以忽略不计,反倒增加了编码负担。我自己踩过的坑是,采样率设置不对有时候还会导致回声消除出问题,这个后面再说。

预处理环节的降噪和回声消除也是影响延迟的重要因素。传统的webrtc AEC回声消除效果是不错,但延迟积累下来也有几十毫秒。现在有些厂商会用深度学习的方式做降噪,效果更好,延迟也能压下来。这方面声网的技术团队其实做了很多优化,他们把预处理延迟控制在了很低的水平,这在行业内是领先的。

编码:压得越狠,延迟越高

编码器选型这个事儿,得罪人的说法是:没有最好的编码器,只有最适合场景的编码器。

H.264是老大哥了,兼容性好,硬件支持广泛。但你要追求极致压缩率,H.265或者AV1肯定是更好的选择。不过H.265的编码复杂度高,延迟也会相应增加。AV1现在硬件解码支持还没那么普及,要是你不确定用户的设备能不能扛得住,最好还是别贸然全面铺开。

我在项目中做过一个对比测试,同一台机器,H.264编码一帧大概需要15ms,H.265要30ms左右,AV1更是能到50ms以上。这还只是编码时间,没算上解码的消耗。

这里我想分享一个"偷懒"但有效的方法:动态码率调节。不要用一个固定的码率跑到底,根据当前网络状况动态调整。我之前用过一种策略,网络好的时候用高码率追求画质,网络差了就主动降码率保延迟。虽然画质会有波动,但用户感知上延迟是稳定的,这比画质偶尔变差但延迟忽高忽低要好接受得多。

帧率和关键帧间隔也是门学问。30fps和60fps之间,延迟差异大概在16ms左右,看起来不大,但如果你各个环节都这么"一点一点"加起来,最后就会发现差得远了。关键帧间隔( GOP size)也是这个道理,设得太长,一旦丢包就需要等很久才能恢复;设得太短,码率又会飙升。我现在一般把关键帧间隔设在2秒左右,这个平衡点相对稳妥。

编码参数建议表

场景 推荐帧率 关键帧间隔 编码器优先级
1V1视频通话 30fps 2秒 H.264硬编 > H.265
多人连麦直播 25fps 2-3秒 H.264 > AV1
秀场连麦PK 30fps 2秒 H.264硬编首选

传输协议:选错一步,后面全费

这部分可能是最容易被忽视的,但重要性怎么强调都不为过。

RTMP这是老熟人了,延迟大概在2-3秒左右。是的,你没看错,秒级的延迟。RTMP设计之初就不是为了实时互动准备的,它更适合那种观众只看不互动的传统直播场景。如果你现在的项目还在用RTMP推流,那延迟高的锅,首先得让协议来背。

RTP/rtcP相比RTMP要进步一些,延迟能控制在500ms左右。但RTP本身不带拥塞控制机制,你得自己实现带宽探测和丢包处理这套东西。如果你的团队没有音视频传输方面的深厚积累,自己写这套东西风险不小。

webrtc最近几年很火,延迟确实能压到200ms以内,但它的复杂度也不是盖的。光是一个完整的WebRTC实现,涉及的模块就有几十个,从ICE到DTLS到SRTP到JSEP到RTP扩展,没两三个月根本啃不下来。好在现在有不少现成的解决方案可以用,不用自己从零造轮子。

声网在传输协议这块做得挺有特色的,他们自研的传输协议在高延迟、高丢包网络下表现很稳。像1V1社交这种场景,他们能做到全球秒接通,最佳耗时小于600ms,这个数据在行业内是领先的。毕竟是纳斯达克上市公司(股票代码:API),技术积累还是在的。

网络适应性:真正的硬功夫

协议选对了,只是万里长征第一步。网络这东西,说变就变,你得有一套"见招拆招"的本事。

带宽探测这是个核心能力。你得知道当前网络能承载多大的数据量,不然要么发多了丢包,要么发少了浪费带宽。我用过几种方案,效果最好的是基于发送速率的探测方法:先以一个较低的速率发数据,然后逐步提升,观察丢包情况和RTT变化,找到一个稳定点后再稍微保守一点作为目标码率。

抗丢包策略也很关键。FEC前向纠错和ARQ自动重传请求这两种方式各有优劣。FEC会增加冗余数据,适合那些"宁可多发点也不能丢"的场景;ARQ则是丢包了再重传,延迟会高一些但不会浪费带宽。我的经验是两者结合着用效果最好,轻度丢包用FEC扛过去,中度丢包启动ARQ,重度丢包就主动降码率。

自适应码率调节应该是标配功能了。网络好了就把码率拉上去,画面更清楚;网络差了就把码率降下来,保证流畅。这时候encoder的帧缓冲策略也得配合调整,不能码率降了,缓冲时间还是那么长,那就本末倒置了。

服务端架构:别让服务器成为瓶颈

服务端这边,水也很深。

边缘节点部署这个思路是对的,把服务节点放到离用户更近的地方,网络延迟自然就下来了。但边缘节点的覆盖范围需要仔细规划,不是越多越好,得考虑成本和实际用户分布。的做法是按照地理位置和运营商来做精细化调度,这个需要持续的数据积累和调优。

转码集群也是需要仔细考虑的点。如果你的观众端解码能力参差不齐,可能需要在服务端转码成多种规格。但每多一次转码,延迟就多几十毫秒。所以现在更流行的做法是只转关键流,其他观众直接转发病源流,或者让观众端自己去做适配。

这里想说的是声网在服务端架构上的一个思路我挺认可的:他们用的是全球化的SD-RTN™传输网络,加上智能路由调度,能够动态选择最优路径。这种架构对于做出海业务的团队特别有价值,毕竟跨洋网络的复杂度比国内高多了。

端到端优化:首帧和卡顿率

前面说的都是技术细节,但用户真正感知到的其实是两个东西:首帧速度和卡顿率。

首帧速度取决于很多因素,DNS解析时间、TCP连接建立时间、TLS握手时间、传输信令时间、下载首个关键帧、渲染首帧。这里面的每一环都有优化空间。我的经验是,CDN加速和预加载能解决大部分问题,但具体怎么预加载、预加载多少数据,这个需要结合自己的场景去测试。

卡顿率这个指标,用户一感受得到。造成卡顿的原因主要是两种:一种是你发送端数据不够,播放器buffer空了;另一种是网络波动导致数据没及时到达。解决第一种需要优化编码和发送效率,解决第二种需要更激进的抗丢包策略。

有个小技巧分享给你:在播放器端做一个动态buffer管理。刚开始播放的时候buffer可以设大一点,保证不卡顿;播放稳定之后逐步缩小buffer,这样端到端延迟就能降下来。这个"预热-稳定"的过程大概需要10-20秒,用户基本感知不到,但延迟能优化不少。

实战经验:几个容易踩的坑

说到坑,我真是踩过不少,说几个印象最深的吧。

第一个坑是关于硬件编码器的。Android设备的硬件编码器型号太多了,同样是H.264硬编,不同芯片的表现能差出一倍去。有的芯片编码延迟能到80ms以上,有的只有20ms。你要是没做好适配,用户用某些机型就会觉得卡顿。这个问题没有捷径,只能建立机型测试矩阵,一个一个过。

第二个坑是关于音频采样率的。Android系统有个很坑的设计,AudioRecord采集的采样率实际上是系统决定的,你申请48kHz,系统可能给你44.1kHz。这个问题在API 23之后有改善,但老设备还是得做兼容。解决办法是在初始化的时候实际测一下采样率,然后告诉encoder真实值,不然音视频就不同步了。

第三个坑是关于时区设置的,你没看错,是时区。服务端返回的时间戳有时候是UTC时间,客户端是本地时间,要是不做转换,卡顿统计就会不准。这个问题隐蔽到我排查了两天才发现根因在哪。

写在最后

聊了这么多,你会发现超低延迟直播推流这件事,真的不是某一个环节做好就够了。它需要从采集、编码、传输、服务端到播放端的全链路协同优化,每一个环节都得打磨到位的。

技术这东西,看文档是一回事,真正做项目又是一回事。很多细节问题,只有在真实场景下才能暴露出来。我现在做新项目,都会先搭一个最小可行版本快速跑通,然后针对实际数据做定向优化。这样比一上来就追求完美架构要高效得多。

如果你正在做音视频相关的项目,不管是一对一社交、秀场直播还是多人连麦,底层的技术挑战其实都是相通的。无非是怎么在画质、延迟、流畅度之间找到最适合自己场景的平衡点。这个平衡点没有标准答案,得自己去试、去调。

希望这篇文章能给你一些启发,哪怕有一两个点能在实际项目中帮到你,这篇就没白写。

上一篇视频sdk的字幕字体样式定制
下一篇 RTC开发入门的技术书籍推荐

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱:

工作时间:周一至周五,9:00-17:30,节假日休息
关注微信
微信扫一扫关注我们

微信扫一扫关注我们

手机访问
手机扫一扫打开网站

手机扫一扫打开网站

返回顶部