阿里云李刚:下一代低延时的直播CDN

摘要: 在上周落幕帷幕的多媒体领域技术盛会——LiveVideoStackCon音视频技术大会上,阿里云的高级技术专家李刚进行了《下一代低延时的直播CDN》技术分享。主讲人李刚,多年关注在CDN这个领域,早期主要研究和cache服务器缓存以及流媒体相关的技术, 专一CDN文件分发、图片与大文件下载等业务。算法

在上周落幕帷幕的多媒体领域技术盛会——LiveVideoStackCon音视频技术大会上,阿里云的高级技术专家李刚进行了《下一代低延时的直播CDN》技术分享。主讲人李刚,多年关注在CDN这个领域,早期主要研究和cache服务器缓存以及流媒体相关的技术, 专一CDN文件分发、图片与大文件下载等业务。从2015年开始负责全面构建阿里云CDN直播系统,对流式长链接的分发有很深入的理解。今天主要分享内容是阿里云自研低延时直播系统在构建时,遇到的一些技术难点与实践。浏览器

分享从当下直播技术回顾、低延时直播技术思考、低延时直播技术实现、展望四个部分展开,本文为演讲原文,但愿对直播CDN相关从业者有必定的帮助。缓存

1、直播场景回顾
下图列举了当下存在的一些常见的直播场景。安全

图片描述

秀场直播是国内最先出现的直播形式,在各个直播平台上是比较常见的。
游戏直播,像斗鱼、虎牙、战旗等直播平台都是比较典型的游戏直播平台,游戏直播对码率要求比较高,观看人数也多,因此它也是流量贡献最大的直播形式。
移动直播是最近一两年比较火的直播形式,比较明显的特色就是推流和播放比较容易, 经过手机APP就能够进行直播,因此手机直播通常也是推流数最多的直播形式。
活动赛事直播,像今年夏天的世界杯,这类直播通常对交互要求不高,因此通常都是HLS播放形式,延迟相对其余都会多一些。
答题直播是今年年初左右出现的新型直播形式,每场直播的时间不长,突发流量比较高。
这些直播场景,在国内主要用HTTP-FLV和RTMP这种传输形式,这两种传播形式通常延时在3-5秒,固然这也会受视频自己GOP影响, 移动直播通常是1-2秒时间间隔,因此控制在3-5秒是比较容易的。可是游戏直播关键帧延时通常在8-10秒,因此游戏直播的延时更大一些。而活动赛事直播通常不会强调互动性,对流畅度比较高,因此会通常选用HLS,延时在10秒以上。服务器

2、低延时直播需求
3~5秒延时对于多数常见的直播形式通常问题不大, 可是对于某些场景效果会不好。网络

对于连麦场景影响是最明显的, 连麦超过1秒,对话可能就没办法维持下去了。如今通常直播平台的连麦直播需求都会借助第三方的连麦服务,而后再推给直播CDN厂商。socket

在答题直播场景下, 通常都要求在一段时间内用户提交答案,若是有各别用户延迟比较大,这样对用户是不公平的。虽然直播平台仍然使用FLV的传输形式完成答题直播,可是基本都会采用SEI插帧等方法来解决时间同步问题, 须要平台的端和直播CDN作一些配合来完成。ide

除了连麦、答题场景以外,像在线课堂、在线拍卖等场景由于涉及到实时性的互动,对延时的要求也比较高。优化

从对业务的支持层面来看, 仅仅有RTMP、FLV这种3~5秒延时以上的直播形式已经不够了, 须要对更低延迟的直播业务进行支持。从技术的角度来看,国内经常使用的FLV、RTMP这种直播手段,自己是Adobe本身的标准, 并且很快会中止对flash的维护, 另外一方面WebRTC技术的兴起,Chrome、Safari等浏览器也都进行了支持,所以也须要对新的技术有一些调研和准备。阿里云

基于对于这些问题的思考, 阿里云CDN也开展了对低延时直播技术的研发。

3、短延时直播VS实时音视频通讯
简单介绍下实时音视频通讯和短延时直播的区别:

图片描述

使用WebRTC主要用于解决实时音视频通话的需求,必然对延迟要求很是严格, 一个会议室中参与的多方能够进行视频通话, 每一个参与者能够看到其余参与者,也能听到其余参与者说话。每一个参与者既有推流,又有播放,数据是双向的。因此参与人数不会太多,通常不能超过20个。
短延时直播仍然是直播业务类型, 只是延时比较低, 短延时直播的业务模型相对简单, 数据单向传输,一个主播推流,参与的播放者人数没有限制,上百万均可以。

4、技术选型的思考
在作短延时直播项目的时候,咱们在技术选型上作了一些思考。

首先,是必需要兼容已有直播业务和技术栈,由于阿里云直播CDN系统已经有了不少客户,短延时直播须要从现有直播的业务上慢慢衍生, 可让客户在短延时和常规直播手段进行切换, 这也是处于业务稳定性的考虑。

第二,对于直播来说, 秒开是一个很重要的指标,咱们后面详细展开。固然卡顿也是重要的指标,由于WebRTC在移动端拥塞控制和重传方面有一些处理,因此卡顿率方面不会比TCP差。

第三,对齐到WebRTC会是最终的结果, 毕竟用户可以使用H5就能够直接推流或者观看直播, 更方便客户的接入和使用。但因为完整的支持WebRTC要解决加解密、打洞、音频格式等问题, 因此前期考虑只使用WebRTC中的一部分技术,完整支持WebRTC会是二期的工做。

5、TCP的可能性
图片描述

已有的业务,不管是图片、大小文件、点播、直播,这些都是在TCP通讯基础上实现的,因此短延时直播在开展的时候咱们就思考了TCP的可能性。

咱们对于短延时的目标定义为从端到端800毫秒之内,一场直播的延迟来自于推流端延迟、CDN产生的延迟、播放端延迟这三个方面,不少客户会关注CDN产生的延迟,咱们也对数据进行过统计,CDN从入到出所产生的总延时,全网平均不到100毫秒,晚高峰平均也不超过200毫秒。而从经验角度来看,播放端的延迟会比较严重,主要是两方面,一方面是开播时候卡前一个关键帧所带来的延迟,另外一方面若是CDN服务器到播放端有抖动,累积的延迟会愈来愈多。

以前有一个彩票直播业务的客户, 由于客户担忧用户怀疑刮奖的时效性, 因此对延时要求就很是苛刻, 客户的端进行延迟优化, 延迟也能够作到1秒内。

因此,一开始咱们有了这样一个结论,网络正常的状况下,使用现有的RTMP、FLV进行分发,延迟也能够作到1秒之内。

可是现实状况是网络是不可能出现不丢包的状况。当网络抖动出现丢包的时候,TCP是ACK确认机制的,也就是发送方发送一包以后,必定要等过对方回应,才会继续发。若是说网络一旦出现丢包,就会在一个RTO以后重传,RTO的值和RTT有关,而且RTO的最小值是200ms。若是想保证流畅性,你的播放端必定要至少能容忍200ms以上的抖动,但播放端的jitbuffer太多又没法知足低延时的要求。

图片描述

这里对一下比WebRTC中RTP传输使用的NACK机制,NACK的丢包反馈更加及时,若是网络是偶然性抖动居多的时候, NACK机制效果更加好。这里咱们也作了一个统计,全网平均RTT小于15ms,若是CDN节点覆盖足够好的状况下,延迟理论上会很低。以1.5Mbps码率的音视频流举例,每秒钟100个包,包和包之间就是10ms的间隔。若是当第二个丢包出现的时候,第三个包对方接收到了,就能够立刻知道第二个包是丢掉了,就能够马上返回一个NACK,进行重传。在这种极限状况下,重传间隔就是25ms,相比以前TCP的200ms是一个质的提高,想知足绝大部分播放延迟在800ms之内才有可能。

图片描述

另外,使用TCP的话,无效传输无法避免,。TCP是采用socket buffer进行通讯,数据也是从应用层先进入socket buffer再分发。对于RTMP或FLV的分发来讲,假如某一帧的数据的一部分已经进入了socket缓冲区, 那么也必须将这一帧剩余的数据发送出去, 若是剩余的数据不发出去的话, 播放端会出现解析错误, 断开链接, 这个体验会不好。

而在网络在出现波动的时候, 有可能这socket buffer里面的数据好久以后才能传送到对方, 而在短延时直播的场景下, 这些socket buffer里面和应用层过久的数据再发送给播放端已经没有意义,也就是说会产生不少无效的传输。

图片描述

6、自研短延时直播方案
基于这些考虑,咱们最终采用了如下的方案。WebRTC是当下短延时流媒体的传输比较热门的技术, 因此在实现短延时直播的同时会考虑使用WebRTC相关的一些技术。原有的RTMP, FLV, HLS这些使用TCP,新增阿里自研私有ARTP短延时方案,最终会支持WebRTC,ARTP和WebRTC使用UDP传输。

图片描述

在研发以前,咱们会对各项部署作一些思考。

1.端口问题
WebRTC的默认工做方式SFU服务器会为每一个参与者须要为其余每一个参与者分配一个端口, 必定程度上来讲是经过不一样的端口来区分参与者。而CDN从安全的角度来考虑, 不会采起这种方式, 因此从一开始就认定在短延时直播这个场景下,咱们会使用固定端口的方式来提供服务。下图是最终的方案,流媒体服务器会开几个端口分别支持不一样播放形式的访问,容许用户的端进行的灵活控制。

图片描述

  1. 秒开问题

这里讲一下播放秒开的问题, 若是采用标准的WebRTC方式,那么须要通过下图这样几个环节。
图片描述

这样下来对于直播秒开的体验来讲就会不好,因此在实现低延时直播方案时针对这个问题须要进行优化处理, 去掉一些没必要要的环节。

CDN服务器自己是有公网IP和端口的, 播放端没有独立的公网IP和端口,若是是像WebRTC这么实现的话, 服务器把数据直接传给播放端,那么必然涉及到打洞探测的问题,因此若是想要达到秒开效果的话,就不能使用WebRTC的这种方式, 须要让播放端先给服务器发送请求, 让本身所在的NAT网关创建起映射以后,服务器再把数据吐给客户端时就OK了。

图片描述

上图就是最终的时序图,使用的是比较简单的应答模式。没有了TCP的三次握手环节,因此秒开效果必定比FLV、RTMP更好。同时,客户端直接发起播放请求,请求包长度尽可能控制在一个UDP包内,不要出现一个请求两个包的状况。
图片描述

国内直播平台大部分仍是使用h264和AAC,因此咱们也是首先支持这两种格式,其余音视频格式像HEVC等也是咱们后续要支持的格式。

3.RTP报文
PT字段是载荷类型,sequence number是包序列号,发送端切片的时候,写好序列号,接收端依据这个序列号进行数据的还原。并且在重传发生的时候,还依靠这个序列号进行NACK的反馈。时间戳对流媒体传输很是重要,播放器依赖它进行解码和同步。SSRC用来识别不一样的身份,同一个IP和端口被NAT从新分配的时候, SSRC识别出这是一个不一样的链接。
图片描述

前面讲过使用TCP传输的时候,网络抖动出现堆积时,须要丢帧,可是必定是丢完整的帧,不能丢片断。那为何RTP场景下为何没有这个问题?以H264为例,RTP在封装的时候,若是NAL单元小于MTU,那么咱们认为一个RTP包能够完整封装一个NAL单元的,若是出现丢帧,那么咱们认为缺乏的是一个完整的NAL单元,对后面NAL单元解析是没有问题的,不会出现数据错乱。

图片描述

若是一个NAL单元大于一个MTU的时候,假设一个NAL单元须要三个RTP包封装,无论丢到哪个仍是所有丢掉,接收端均可以标识出这个NAL单元,不会影响其余NAL单元的解析。
图片描述

4.平滑发送机制
如今采用的混合拥塞算法,基于丢包率和基于延迟进行码率控制。标准的作法是,当播放卡顿时,会让发送端降码率。

图片描述

从两个方面来看,当推流端上行出现抖动的时候,服务器会反馈数据包,把码率自动降下来。当播放端出现下行抖动的时候,一种是输出转码流,另外一种是让主播推两路流上来,让播放卡顿的用户换到低码率。

图片描述

5.播放端上的优化
第一阶段是开播阶段,得到GOP数据的时候,若是端不作处理的话,必定会有一个延迟。因此在这个阶段,播放端必定进行快进的操做,缩短延迟。第二阶段是当网络出现抖动的时候,会慢慢放大buffer的长度,来必定程度上适应抖动,提升流畅度。第三阶段,当网络恢复的时候,咱们能够适当快进,减少buffer,把进度赶回来。也就是说这个buffer大小是动态变化的。

图片描述

6.RTC内部打包机制
H264和AAC数据会在内部先进行切片,放到平滑发送队列再发送给对端,同时重传包也会进入平滑发送队列, 而且会放到平滑发送队列的队首位置。
图片描述

7.FEC冗余传输
FEC是靠冗余传输,来提升容错率。关键帧10%冗余率, 非关键帧5%,根据丢包判断出网络情况,动态调整冗余度。
图片描述

8.UDP传输注意事项
UDP无链接,也就没有TCP的链接断开时的挥手确认链接关闭的机制。那么对于主播来讲,若是出现断开,而后短期再重推的话就会遇到问题,由于CDN会认为前一个推流链接还在,新的推流链接推的是同名流,会拒绝掉新的链接,主播也会反馈没法推流。对于播放来讲,虽然没有同名流问题,可是若是播放端再也不观看,CDN服务器会仍然将数据发送给指定的IP和端口,这就产生了不少无效的传输。最终会反映到流量和计费日志上。因此采用RTCP报文的方式,对于播放和推流链接的断开进行通知,节省资源消耗, 流抢占等问题。
图片描述

9.探活策略
除了对于正常关闭进行主动通知以外, 还须要对超时状况进行处理。即使是TCP传输的时候也有相似的问题,推流端发送了FIN结束报文,可是服务器未必收到,因此必定要有超时的机制来进行管理。咱们采用数据及时反馈的机制,在下行播放端要求周期性的返回心跳,上行要求推流端在8或10秒内必定要有一些真实数据传输,不然咱们就会断开。
图片描述

这幅时序图更细致的展开了一下实现的逻辑,播放端和服务器。
图片描述

Tengine是阿里开源的服务器软件, 阿里云CDN的文件、点播、直播功能都是在其基础上进行开发,而在短延时直播功能的实现咱们也是把开源的WebRTC的库进行了一些改造。选择Tengine来作主要缘由也是由于对其很是的熟悉,并且在其基础上也积累了不少配套的技术,包括配置下发管理、日志收集、业务处理等。

最后,咱们来看下实际的数据状况。
目前短延时直播功能是在一些地区进行了部署和验证,还没到全网铺开的阶段。
秒开数据比原来FLV访问提高很大, UDP交互省去了三次握手环节。错误率和延迟都有了较大的提高。这里目前只对比了下行,从已经灰度的一些节点来看,上行卡顿数据要优于原有RTMP的推流。
图片描述

7、后续展望
完整的支持WebRTC必定是目标, 毕竟直接经过浏览器就能够完成推流和播放对于用户的接入来讲实在太方便, 对于CDN来说控制接入必定是一个必须作的事情。

对于CDN要作的另外一个事情就是优化传输,其实不管对于文件加速仍是流媒体加速,传输永远都是最重要的,CDN这个分发网络自己就是为了优化传输而存在。

从实践来看,UDP传输比原来的TCP传输对资源消耗要多,并且重传、封包、FEC冗余计算等都会额外增长计算量,在多进程模式下可能还会遇到内存资源的过多消耗。