本文由 著名直播平台都在使用的云计算公司 UCloud 流媒体研发团队撰写!html
网络视频直播存在已有很长一段时间,随着移动上下行带宽提高及资费的下调,视频直播被赋予了更多娱乐和社交的属性,人们享受随时随地进行直播和观看,主播不知足于单向的直播,观众则更渴望互动,直播的打开时间和延迟变成了影响产品功能发展重要指标。那么,问题来了: 如何实现低延迟、秒开的直播?html5
先来看看视频直播的5个关键的流程:录制->编码->网络传输->解码->播放,每一个环节对于直播的延迟都会产生不一样程度的影响。这里重点分析移动设备的状况。受限于技术的成熟度、硬件环境等,咱们针对移动场景简单总结出直播延迟优化的4个点:网络、协议、编解码、移动终端,并将分四大块来一一解密UCloud直播云实现低延迟、秒开的技术细节。android
实现就近接入的技术比较广为人知,就是CDN即Content Delivery Network (内容分发网络)。CDN包含两大核心技术:负载均衡和分发网络,随着10多年的演进,对负载均衡和分发的实现方式已多种多样,分发网络的构建策略一般是通过日积月累的总结出一套最合适的分发路由,而且也不是一成不变,需时刻关注调整,动态运营。这里重点介绍下CDN的负载均衡技术。ios
负载均衡是如何实现让用户就进访问的呢?比较广泛的实现方式:经过用户使用的DNS服务器来判断客户端所在的网络位置,从而返回对应的服务IP。以下图示例:nginx
广东电信用户IP:1.1.1.1 须要看一个直播http://www.ucloud.cn/helloworld.flv ,实现就近访问的过程是:git
1>用户向配置的DNS服务器1.1.1.0(一般是运营商指定,也称local DNS,后面简称Ldns)发起www.ucloud.cn 的查询;github
2> Ldns 上没有该域名的记录,则往顶级即Root NS上发起查询;算法
3>Root NS返回告知Ldns该域名的权威解析记录在UCloud NS上;docker
4>Ldns 向UCloud NS发起查询;后端
5>UCloud NS 向UCloud GSLB服务发起查询,GSLB发现 Ldns1.1.1.0是属于广东电信;
6>返回广东电信的就近节节点IP1.1.1.2;
7>返回1.1.1.2给Ldns;
8>返回给用户1.1.1.2,用户到1.1.1.2上去获取直播内容。
链路很长,可是每一个Ldns上都会对查询过的域名作合理的缓存,下一个广东电信的用户再来查询的时候就能够直接返回1.1.1.2。架构并不复杂,关键点是如何知道Ldns是位于广东电信,这就涉及一个IP地址库。有开源地址库,也有商业地址库,能够按需求采购便可,通常一年1万左右。这里不难看出来,调度的准确度是彻底依赖用户配置的Ldns,而这些Ldns大多数是省级别的,即GLSB只知道用户是广东电信,可是经常分不出来是广东广州电信,仍是广东深圳电信。 HTTPDNS就是实现更精准的调度一种方式:
1>用户1.1.1.1经过HTTP协议直接向UCloud NS请求直播域名www.ucloud.cn;
2>UCloud NS发现用户IP1.1.1.1属于广东深圳电信;
3>返回广东深圳电信节点1.1.1.11给UCloud NS;
4>返回给用户。
HTTPDNS的好处显而易见:一可精准得到用户端的IP,有效避免用户配错Ldns(有时是网络中心配错DNS)的状况,可更精准定位用户所在网络位置。二可避免DNS解析劫持。
BGP即Border Gateway Protocol (边界网关协议),业内简称BGP。为何BGP中转架构对直播加速和分发如此重要?不得不提国内复杂的网络情况,较广为人知的是“南电信北联通”的宽带用户分布。那一个简单的问题,电信主播发起了直播,联通的用户想看怎么办呢? 从结构上讲,确定是有有限个电信联通两个运营商的交汇点,至关于信息桥梁。 这就会带来两个问题:一、路程要绕远,网络延迟高且不稳定;二、高峰期拥堵,致使直播流卡顿。
BGP的技术原理往简单的说就是容许同一IP在不一样网络中广播不一样的路由信息,效果就是同一个IP,当电信用户来访问时走电信网内的路由,联通用户来访问时走的联通的路由。因此BGP技术对跨运营商的访问带来了巨大的便利,特别是直播场景。不一样于传统的文件缓存场景,一个图片哪怕第一次是跨了遥远的距离从源站获取后,本地网络进行缓存,后面的访问都走本地网络。直播加速是流式的,而且当要作到低延迟的时候,中间的缓存要尽量少。 BGP至关于给跨网的用户就近搭建了一坐桥梁,没必要绕远路,延时和稳定性都大大提升了。
技术原理部分介绍完了,那么多直播延迟影响有多少改善呢?首先这里的就近,不必定是物理距离近,不考虑瞬时负载状况下,更可能是指测速延时最优的机房。在国内通常而言相同的接入运营商(电信、联通、移动)而且地理位置最近的状况网络延迟最优,小于15ms。跨省同运营商的网络延迟25~50ms,跨运营商状况更复杂一些,在50~100ms。总结起来,直播当中每一个包的延时能够缩短100ms,因为网络的叠加效果,反射到上层是秒级的延迟缩减。
国内常见公开的直播协议有几个:RTMP、HLS、HDL(HTTP-FLV)、RTP,咱们来逐一介绍。
RTMP协议:
是Adobe的专利协议,如今大部分国外的CDN已不支持。在国内流行度很高。缘由有几个方面:
一、开源软件和开源库的支持稳定完整。如斗鱼主播经常使用的OBS软件,开源的librtmp库,服务端有nginx-rtmp插件。
二、播放端安装率高。只要浏览器支持FlashPlayer就能很是简易的播放RTMP的直播,协议详解能够Google了解。相对其余协议而言,RTMP协议初次创建链接的时候握手过程过于复杂(底层基于TCP,这里说的是RTMP协议自己的交互),视不一样的网络情况会带来给首开带来100ms以上的延迟。基于RTMP的直播通常内容延迟在2~5秒。
HTTP-FLV协议:
即便用HTTP协议流式的传输媒体内容。相对于RTMP,HTTP更简单和广为人知,并且不担忧被Adobe的专利绑架。内容延迟一样能够作到2~5秒,打开速度更快,由于HTTP自己没有复杂的状态交互。因此从延迟角度来看,HTTP-FLV要优于RTMP。
HLS 协议:
即Http Live Streaming,是由苹果提出基于HTTP的流媒体传输协议。HLS有一个很是大的优势:HTML5能够直接打开播放;这个意味着能够把一个直播连接经过微信等转发分享,不须要安装任何独立的APP,有浏览器便可,因此流行度很高。社交直播APP,HLS能够说是刚需,下来咱们分析下其原理 。
基于HLS的直播流URL是一个m3u8的文件,里面包含了最近若干个小视频TS(一种视频封装格式,这里就不扩展介绍)文件,如 http://www.ucloud.cn/helloworld.m3u8 是一个直播留连接,其内容以下:
假设列表里面的包含5个TS文件,每一个TS文件包含5秒的视频内容,那么总体的延迟就是25秒。固然能够缩短列表的长度和单个TS文件的大小来下降延迟,极致来讲能够缩减列表长度为1,1秒内容的m3u8文件,可是极易受网络波动影响形成卡顿。
经过公网的验证,目前按同城网络能够作到比较好的效果是5~7秒的延迟,也是综合流畅度和内容延迟的结果。那么Html5是否能够有更低延迟直接打开的直播流技术呢? 咱们在最后会探讨这个问题。
RTP协议:
即Real-time Transport Protocol,用于Internet上针对多媒体数据流的一种传输层协议。
实际应用场景下常常须要RTCP(RTP Control Protocol)配合来使用,能够简单理解为RTCP传输交互控制的信令,RTP传输实际的媒体数据。
RTP在视频监控、视频会议、IP电话上有普遍的应用,由于视频会议、IP电话的一个重要的使用体验:内容实时性强。
对比与上述3种或实际是2种协议,RTP和它们有一个重要的区别就是默认是使用UDP协议来传输数据,而RTMP和HTTP是基于TCP协议传输。为何UDP 能作到如此实时的效果呢?关于TCP和UDP差异的分析文章一搜一大把,这里不在赘述,简单归纳:
UDP:单个数据报,不用创建链接,简单,不可靠,会丢包,会乱序;
TCP:流式,须要创建链接,复杂,可靠 ,有序。
实时音视频流的场景不须要可靠保障,所以也不须要有重传的机制,实时的看到图像声音,网络抖动时丢了一些内容,画面模糊和花屏,彻底不重要。TCP为了重传会形成延迟与不一样步,如某一截内容由于重传,致使1秒之后才到,那么整个对话就延迟了1秒,随着网络抖动,延迟还会增长成2秒、3秒,若是客户端播放是不加以处理将严重影响直播的体验。
总结一下:在直播协议的选择中,若是选择是RTMP或HTTP-FLV则意味着有2~5秒的内容延迟,可是就打开延迟开,HTTP-FLV 要优于RTMP。HLS则有5~7秒的内容延迟。选择RTP进行直播则能够作到1秒内的直播延迟。但就目前所了解,各大CDN厂商没有支持基于RTP直播的,因此目前国内主流仍是RTMP或HTTP-FLV。
HLS的优势点是显而易见的:移动端无需安装APP使用兼容HTML5的浏览器打开便可观看,全部主流的移动端浏览器基本都支持HTML5,在直播的传播和体验上有巨大的优点。
而看起来惟一的缺点:内容延迟高(这里也有不少HLS限制没有提到,好比必须是H264 AAC编码,也可认为是“缺点”之一)。若是能获得解决,那将会是直播技术很是大的一个进步。或者换个说法,有没有更低延迟可直接用连接传播的直播方案?不局限于HLS自己。
对于浏览器直接的视频互动,Google一直在推WebRTC,目前已有很多成型的产品出现,能够浏览器打开即实时对话、直播。但来看看以下的浏览器覆盖图:
很是遗憾的说,在直至iOS 9.3上的Safari仍然不能支持WebRTC。继续咱们的探索,那Websocket支持度如何呢?
除了老而不化的Opera Mini外,全部的浏览器都支持WebSocket。这彷佛是个好消息。梳理一下HTML5 WebSocket直播须要解决的问题:
一、后端兼容
二、传输
三、解码播放
对于#1彷佛不是特别大问题,对于作过RTMP转HLS、RTP来讲是基本功。#2对于浏览器来讲使用HTTP来传输是比较好的选项。对于#3 这里推荐一个开源的JS解码项目jsmpeg: https://github.com/phoboslab/jsmpeg,里面已有一个用于直播的stream-server.js的NodeJS服务器。
从测试结果看,该项目的代码相对较薄,还没达到工业级的成熟度,须要大规模应用估计须要自填很多坑,有兴趣的同窗能够学习研究。
以上就是直播云:直播应用层协议及传输层协议的选择以及对直播体验影响的分析 。关于接入网络优化、内容缓存与传输策略优化、终端优化,请参阅接下来发布的其余部分。
I帧表示关键帧。你能够理解为这一帧画面的完整保留;解码时只须要本帧数据就能够完成。(由于包含完整画面)
P帧表示这一帧跟以前的一个关键帧(或P帧)的差异。解码时须要用以前缓存的画面叠加上本帧定义的差异,生成最终画面。(也就是差异帧,P帧没有完整画面数据,只有与前一帧的画面差异的数据)
B帧是双向差异帧。B帧记录的是本帧与先后帧的差异(具体比较复杂,有4种状况)。换言之,要解码B帧,不只要取得以前的缓存画面,还要解码以后的画面,经过先后画面的与本帧数据的叠加取得最终的画面。
B帧压缩率高,可是编解码时会比较耗费CPU,并且在直播中可能会增长直播延时,所以在移动端上通常不使用B帧。
关键帧缓存策略
一个典型的视频帧序列为IBBPBBPBBP……
对于直播而言,为了减小直播的延时,一般在编码时不使用B帧。P帧B帧对于I帧都有直接或者间接的依赖关系,因此播放器要解码一个视频帧序列,并进行播放,必须首先解码出I帧,其后续的B帧和P帧才能进行解码,这样服务端如何进行关键帧的缓存,则对直播的延时以及其余方面有很是大的影响。
比较好的策略是服务端自动判断关键帧的间隔,按业务需求缓存帧序列,保证在缓存中存储至少两个或者以上的关键帧,以应对低延时、防卡顿、智能丢包等需求。
延迟与卡顿的折中
直播的延时与卡顿是分析直播业务质量时,很是关注的两项指标。互动直播的场景对延时很是敏感,新闻体育类直播则更加关注播放的流畅度。
然而,这两项指标从理论上来讲,是一对矛盾的关系——须要更低的延时,则代表服务器端和播放端的缓冲区都必须更短,来自网络的异常抖动容易引发卡顿;业务能够接受较高的延时时,服务端和播放端均可以有较长的缓冲区,以应对来自网络的抖动,提供更流畅的直播体验。
固然,对于网络条件很是好的用户,这两项是能够同时保证的,这里主要是针对网络条件不是那么好的用户,如何解决延时与卡顿的问题。
这里一般有两种技术来平衡和优化这两个指标。
一是服务端提供灵活的配置策略,对于延时要求更敏感的,则在服务端在保证关键帧的状况下,对每一个链接维持一个较小的缓冲队列;对于卡顿要求更高的直播,则适当增长缓冲队列的长度,保证播放的流畅。
二是服务端对全部链接的网络状况进行智能检测,当网络情况良好时,服务端会缩小该链接的缓冲队列的大小,下降延迟;而当网络情况较差时,特别是检测到抖动较为明显时,服务端对该链接增长缓冲队列长度,优先保证播放的流畅性。
丢包策略
何时须要丢包呢?
对于一个网络链接很好,延时也比较小的链接,丢包策略永远没有用武之地的。而网络链接比较差的用户,由于下载速度比较慢或者抖动比较大,这个用户的延时就会愈来愈高。
另一种状况是,若是直播流关键帧间隔比较长,那么在保证首包是关键帧的状况下,观看这个节目的观众,延迟有可能会达到一个关键帧序列的长度。上述两种状况,都须要启用丢包策略,来调整播放的延时。
关于丢包,须要解决两个问题:
一是正确判断什么时候须要进行丢包;
二是如何丢包以使得对观众的播放体验影响最小。较好的作法是后端周期监控全部链接的缓冲队列的长度,这样队列长度与时间造成一个离散的函数关系,后端经过自研算法来分析这个离散函数,判断是否须要丢包。
通常的丢帧策略,就是直接丢弃一个完整的视频帧序列,这种策略看似简单,但对用户播放的影响体验很是大。而应该是后台采用逐步丢帧的策略,每一个视频帧序列,丢最后的一到两帧,使得用户的感知最小,平滑的逐步缩小延时的效果。
解析优化
参见以前介绍的DNS过程,以下图:
基于可控和容灾的须要,移动端代码通常不会hardcode 推流、播放的服务器IP地址,而选用域名代替。在IP出现宕机或网络中断的状况下,还能够经过变动DNS来实现问题IP的剔除。而域名的解析时间须要几十毫秒至几秒不等,对于新生成热度不高的域名,通常的平均解析延迟在300ms,按上图的各个环节只要有一个通路网络产生波动或者是设备高负载,会增长至秒级。几十毫秒的状况是ISP NS这一层在热度足够高的状况下会对域名的解析进行缓存。以下图:
按咱们上面分析的状况,本省延迟大概是15ms左右,那么域名解析最低也能够作到15ms左右。但因为直播场景的特殊性,推流和播放使用的域名使用的热度较难达到ISP NS缓存的标准,因此常常须要走回Root NS进行查询的路径。
那客户端解析优化的原理就出来了:本机缓存域名的解析结果,对域名进行预解析,每次须要直播推流和播放的时候再也不须要再进行DNS过程。此处节省几十到几百毫秒的打开延迟。
播放优化
直播播放器的相关技术点有:直播延时、首屏时间(指从开始播放到第一次看到画面的时间)、音视频同步、软解码、硬解码。参考以下播放流程:
播放步骤描述:
根据协议类型(如RTMP、RTP、RTSP、HTTP等),与服务器创建链接并接收数据;
解析二进制数据,从中找到相关流信息;
根据不一样的封装格式(如FLV、TS)解复用(demux);
分别获得已编码的H.264视频数据和AAC音频数据;
使用硬解码(对应系统的API)或软解码(FFMpeg)来解压音视频数据;
通过解码后获得原始的视频数据(YUV)和音频数据(AAC);
由于音频和视频解码是分开的,因此咱们得把它们同步起来,不然会出现音视频不一样步的现象,好比别人说话会跟口型对不上;
最后把同步的音频数据送到耳机或外放,视频数据送到屏幕上显示。
了解了播放器的播放流程后,咱们能够优化如下几点:
首屏时间优化
从步骤2入手,经过预设解码器类型,省去探测文件类型时间;
从步骤5入手,缩小视频数据探测范围,同时也意味着减小了须要下载的数据量,特别是在网络很差的时候,减小下载的数据量能为启动播放节省大量的时间,当检测到I帧数据后就立马返回并进入解码环节。
视频缓冲区或叫视频缓存策略,该策略原理是当网络卡顿时增长用户等待时间来缓存必定量的视频数据,达到后续平滑观看的效果,该技术能有效减小卡顿次数,可是会带来直播上的内容延时,因此该技术主要运用于点播,直播方面已去掉该策略,以此尽量去掉或缩小内容从网络到屏幕展现过程当中的时间;(有利于减小延时)。
下载数据探测池技术,当用户下载速度不足发生了卡顿,而后网络忽然又顺畅了,服务器上以前滞留的数据会加速发下来,这时为了减小以前卡顿形成的延时,播放器会加速播放探测池的视频数据并丢弃当前加速部分的音频数据,以此来保证当前观看内容延时稳定。
推流优化
推流步骤说明:很容易看出推流跟播放实际上是逆向的,具体流程就很少说了。
优化一:适当的Qos(Quality of Service,服务质量)策略。
推流端会根据当前上行网络状况控制音视频数据发包和编码,在网络较差的状况下,音视频数据发送不出去,形成数据滞留在本地,这时,会停掉编码器防止发送数据进一步滞留,同时会根据网络状况选择合适的策略控制音视频发送。
好比网络不好的状况下,推流端会优先发送音频数据,保证用户能听到声音,并在必定间隔内发关键帧数据,保证用户在必定时间间隔以后能看到一些画面的变化。
优化二:合理的关键帧配置。
合理控制关键帧发送间隔(建议2秒或1秒一个),这样能够减小后端处理过程,为后端的缓冲区设置更小创造条件。
软硬编解选择
网上有很多关于选择软解仍是硬解的分析文章,这里也介绍一些经验,但根本问题是,没有一个通用方案能最优适配全部操做系统和机型。
推流编码: 推荐Andorid4.3(API18)或以上使用硬编,如下版本使用软编;iOS使用全硬编方案;
播放解码:Andorid、iOS播放器都使用软解码方案,通过咱们和大量客户的测试以及总结,虽然牺牲了功耗,可是在部分细节方面表现会较优,且可控性强,兼容性也强,出错状况少,推荐使用。
附软硬编解码优缺点对比:
云端机型及网络适配
上面分析了不少针对视频编解码的参数,但实际状况最好的编解码效果是须要根据机型的适配的,因为iOS的设备类型较少,能够作到每一个机型针对性的测试和调优,可是对于Android就很是难作到逐款机型针对性调优,而且每一年都会出产很多的新机器,若是代码中写死了配置或判断逻辑将很是不利于维护和迭代。
因此咱们就诞生了一个想法,这些判断逻辑或配置是否能够放在云上呢? 这样就产生了云端机型与网络适配的技术。
终端在推流、播放前会获取经过协议上报当前的机型配置、网络状况、IP信息。云端会返回一个已最适合的编解码策略配置:走软编仍是硬编、各项参数的配置,就近推流服务的IP,就近播放服务的IP。 终端获取一次便可,不须要每次推流、播放前都去获取一次。
这样,在咱们不断的迭代和完善机型编解码适配库的同时,全部使用该技术的直播APP都将收益。
分析不少直播后端、终端的关于低延迟、秒开的优化技术,在UCloud直播云上都已有了相关的实践,都是一些较“静态”的技术。实际提供稳定、低延迟、流畅的直播服务,是平常中很是大量细致的监控、算法和动态运营的结果,并非实现了某些的技术点,就能坐享一套稳定的直播服务,只能说是完成了万里长城的第一道砖。