文 / 张亮
整理 / LiveVideoStack
大家好,我是四达时代的研发总监张亮,本次分享的内容是基于四达时代在非洲做在线视频服务时所遇到的一些问题和一些优化的经验。大家都知道,非洲的网络环境非常复杂,甚至可以说几乎没有比非洲更差的网络环境了,因此我们这里介绍的是一个比较极端的情况,仅供大家参考。
分享的内容主要分为三部分。首先是对StarTimes On App的简单介绍,由此引出我们的产品到底应该关心哪些指标,优化必须要明确最核心的目的,想一起优化所有的指标肯定是不可行的。第二部分会列出一些实际数据让大家了解非洲的实际网络情况。第三部分会重点和大家分享在如此极端的网络环境下我们具体采用了哪些优化方式、方法,并最终取得了怎样的效果。
1 StarTimes On APP 简介
也许之前大家不太了解四达时代,因为我们主要的业务是在非洲做电视运营。在非洲,四达时代可以说是一家家喻户晓的公司,我们已经在非洲耕耘了十四年,在四十五个非洲国家做运营,目前已经拥有超过1000万的付费电视用户,所以我们的整体收入规模和影响力还是具备一定水平的。同时我们也是“万村通”项目的实施方,这是我们国家“一带一路”中的一个重要项目。
1.1 StarTimes On APP
StarTimes On 这个APP做的比较晚,直到2017年才上线,上线直接面临的就是2018年世界杯的考验。最初我们对于非洲的网络环境有多差是没有作心理准备的,只是从APM厂商那里获得了一些数据,但实际真实的数据比拿到的数据还要差的多,因此在世界杯的转播过程中还是出现了一些问题,不过好在我们都及时想办法解决掉了。
现在,StarTimes On 已经基本上具有一定的知名度,在Google Play娱乐板块上也一直是名列前茅。
1.2 商业模式与运营指标
从APP的商业模式上可以找到我们的核心指标。首先,我们的内容都是版权内容。用户分为两类,一类是免费用户,另一类是付费用户。
免费用户观看视频需要看广告,广告会给我们带来收入。免费用户看VIP内容则有限制,只能试看三分钟。所以我们的运营指标就是免费用户看了多少视频,因为观看视频就意味着广告播放的增加,其次播放次数多则意味着更有潜力成为付费用户。
对于付费用户来说我们的收入来源是订阅费,付费用户不需要看广告,所有的内容权益也相应解锁。因此对于付费用户,我们则重点关注用户观看视频的数量和观看的时长。看得多、看得久就代表满意度高,满意度高就会继续付费,所以这是我们运营上的指标。
有了运营指标的要求,我们就可以进一步拆解指标,从技术角度上进行分析,哪些地方需要优化。运营指标可以拆解成观看视频数量与观看视频时长。
观看视频数量很容易理解,如果视频启动失败了,观看数量自然也就会降低,而如果每次打开视频都能成功,都能顺利看到第一帧,那就是一个好的结果。所以QoE部分我们就会关注用户的主动退出率,用户为什么会主动退出,大部分情况都是因为等待的时间太久,比如用户等待的时间超过8秒钟,那可能大部分用户都会选择退出。QoS角度则会关注首屏时间,就是首屏时间越快、越小,主动退出率越低。
观看时长有两种度量方法。对于电视剧、电影,我们会关注用户观看时长占视频总时长的比例。如果是直播频道,则关注观看的时间长度。影响用户观看时长最核心的QoS因素是卡顿。用户普遍会有一个心理预期,例如看一部电影,可以容忍视频卡三次,如果出现太多次卡顿用户可能就会放弃观看。
经过以上分析,我们可以导出此业务模式下最核心的两个QoS指标:首屏时间和卡顿比。之前和很多同学交流,有很多做互动、RTC方面的同学会更多关注延迟,但是在我们这个业务模式下延迟并不需要特别关注。后面会介绍到,我们还会有一些优化策略是通过牺牲延迟来获得其它收益。
2 非洲网络状况与挑战
接下来和大家说一下非洲网络的真实情况。
2.1 非洲网络基本情况
首先,大家看数据图中的南非,南非算得上是一个中等发达国家,网络情况还算可以。南非到欧洲CDN的延迟在闲时约为100多毫秒,忙时200毫秒,这其实还算可以。但如果往西边看,尼日利亚、加纳、科特等一些国家就糟糕多了。像尼日利亚,在忙时的RTT能超过600毫秒。这意味着我们在做任何网络操作的时候,哪怕是下载一个字节的文件,也需要600毫秒的等待,因为网络一来一去硬指标就在那里。如果我们业务上的后台放在欧洲,那么执行任何操作都需要600毫秒的延迟,非常影响用户的体验。
而东边像肯尼亚、乌干达、坦桑尼亚其实网络情况也不太好。在国内,如果最北边地区的用户访问最南边地区的机房花几十毫秒,已经可以算作比较慢了,而在非洲动辄就是几百毫秒,他们的网络情况相比国内差十倍甚至几十倍,这也就意味着我们面临的是一个艰巨的挑战。
下面是丢包率,丢包问题现在更严重。近期我们收集过一次数据,相比于疫情前,丢包率呈现翻倍的情况。受疫情影响,大家会更多使用手机流量,而非洲的带宽资源又非常不足,所以丢包情况变得更加严重。如图中所示,在高峰期丢包率会有24~25%左右,在这样的丢包率的情况下,下载速度是肯定上不去的。
再来看其它的一些指标,建连的成功率有80%,指标相对比较稳定,5次里会失败1次。我们会通过长连接缓解建连失败的影响,但长连接也会出现断连,所以很多时候仍然需要重连。DNS解析时间也很长,要1秒左右,数据都比较差劲。
视频封装我们使用的是HLS协议,CDN上有大量M3U8索引文件和视频切片文件。索引文件大小几百个字节,下载这样一个文件可能需要1000~2000毫秒。视频切片下载速度在200~400kbps左右。以上就是非洲目前的网络情况。
2.2 问题发生的原因
接下来我们简单梳理下非洲的网络问题究竟出现在哪里,只有定位了问题所在,才可以更好地探索优化的思路。
非洲网络丢包率很高,延迟很大。丢包的产生有很多原因,这里我列了两个比较主要的:一个是无线接入网丢包,因为在非洲网络资源(接入网)是非常不足的,虽然大家都使用3G,也有部分的4G基站,但是基站数量太少,如果大家同一时段一起使用的话,基站资源明显是不够的。所以高峰期信号弱、小区切换会有很多问题,这就会导致数据包丢掉。另一个原因是拥塞,不论在非洲哪个国家拥塞都是非常严重的,拥塞在运营商的出口方面会体现的非常明显。如果网络一直处于拥堵的状态,但大家还在大量发送包,或者去请求包,那最后大概率就是丢包。
延迟可以分为几类,像传输延迟和处理延迟等。排队延迟说到底还是和拥塞有关系,如果网络拥塞的很厉害,那中间的交换机,路由器都要排队,排队会花费更多的时间。经过实际分析我们发现:排队延迟是最主要的问题。重发延迟是指丢包之后重新发包带来的延迟,从应用层的角度看,这也是一种延迟。
在了解了非洲网络延迟与丢包的情况后,我们想定位一下这些问题究竟发生在哪个环节,随后再去寻找相应的解决办法。上图是从手机发送请求到最后IDC中的服务器收到并响应的过程。一开始用户的手机需要先连接基站,向基站发送无线信号,基站内部处理后,把网络的请求通过运营商的互联网出口传出,随后有一个更大的互联网,但其实这里面有很多层网络供应商,最终送到了IDC,以上所有的环节都可能发生问题。
最初我们想通过MTR或者Ping这些工具来诊断问题,但在实际操作中发现,如果是在移动端上收集数据,基本上是采集不到数据的,有可能是运营商对这些数据比较敏感。在国内做MTR可以看到很多的数据,但在非洲几乎所有的环节看到的数据都是“***”,表示它不允许探测。
2.3 确定问题所在
最后我们设计了几个实验来确定网络问题的源头,总的来说可以分成三组。
首先我们要确认是不是真的存在十分严重的拥塞。我们分别在闲时和忙时观测视频卡顿和启动时间这些指标,发现差别很大。相较于忙时,闲时的首屏可以减少30%,卡顿降低40%,这是非常显著的差异,这也说明了拥塞的存在,但是具体在哪一部分还不能确定。
接下来我们想验证用户接入网的差别是否为造成差异的因素。我们知道4G网肯定比3G网好很多,但是在非洲4G用户较少,我们推测网络拥塞情况应该也相对良好,通过实验得以验证确实如此,使用4G网络的情况会比使用3G网络的情况好很多,但也没有像闲时与忙时的差异那样显著,因此接入网并不是主要的问题所在。
接下来验证是否为运营商出口网络的问题。在运营商内部我们也设置了一些服务器,通过它们来做测试。结果显示与欧洲的CDN相比,运营商网内设置服务器更具有收益,但并不显著。这也就说明了运营商的出口也存在问题,但不是主要问题。
在非洲还有一些IXP,国内IXP可能比较少。所谓IXP,简单来说就是设置一个机房,各个运营商把它们的线路都拉到这个机房内,从这里可以很方便地连上各个运营商,运营商彼此间也可以交换流量。但实际上非洲IXP与运营商之间的网络也有拥塞,如果把CDN放在IXP的话,优化效果相比于放在运营商网络内会更差一些。
通过以上测试我们得出了这样一个定性的判断:从手机到基站这部分的网络拥塞是最严重的,从运营商互联网出口出去后也存在一定的问题,由此之后的流程则没有太大的问题。在这种情况下,优化其实是比较困难的。但至少我们已经认识到了问题的所在,接下来就是思考具体的解决办法。
2.4 非洲网络情况总结
总地来说,非洲的网络从链路和网络层来看,带宽严重不足,非常拥塞。
从传输层角度来看,不是传输层本身的问题,而是链路层和网络层影响了传输层,传出层的表现为丢包率高、RTT高。到应用层,解析域名很慢、下载速度很慢,并经常出现下载失败的问题。以上就是非洲的基本网络情况。
3 高延迟、高丢包视频体验优化
在有了对网络基本情况的判断后,接下来我们需要确定如何进行优化。
3.1 确定优化目标
回到具体指标,因为我们做的是版权长视频,所以会更关心首屏和卡顿的问题。延迟对我们而言不是特别关键,因为直播电视频道并不涉及到互动环节,观众对延时不是太敏感。所以我们的工作重心会放在解决首屏和卡顿的问题上。
用户体验和成本这部分,因为我们的核心用户是付费用户,他们对视频质量是有一定要求的。但由于是在非洲,他们的要求肯定没有中国或者美国用户的要求那么高,关键在于如何定义“一定的需求”。
最终我们确定的目标是:第一,降低卡顿比,第二,减少首屏时间。卡顿比高,用户主动退出率会增加,这是我们不想看到的。首屏排在第二位是因为用户对首屏还是有一定的耐受度的,长视频启动慢一点相对来说可以接受。但如果短视频如果启动慢,用户应该会很难接受。因此我们结合业务特点,希望将首屏时间限定在不能超过5秒。至于延时,在业务模式下相对来说是可以牺牲部分的。
针对画质我们进行了市场调研,对一些关键的内容——例如球赛做了很多的调研,最后得出结论:对于球赛视频,用户的最低要求是能看到球。其实这个要求并不是太容易满足,以非洲的网络下载速度,视频想要流畅播放就必须降低码率,而码率一旦降低,球就会模糊——球在天上飞的时候非常小,画面里就一两个像素那么大,编码的时候非常容易把球编没。所以经常的情况是:球在天上飞找不到位置,过一会又出现落在地上。对于这个问题我们也是做了非常多的优化才使其达到用户能够接受的最低要求。而在其它方面包括新闻类节目,报道播出的时候需要清晰显示新闻人物的人脸,在国内这些都是不用担心的事情,但在非洲则需要通过各种优化实现。以上就是我们最终定下来的优化目标。
3.2 优化思路
具体的优化思路要从CDN层面说起。刚刚我们提到非洲整体网络慢、差、拥塞,那么原因究竟是什么呢?我们从IDC角度来看就能发现一些问题,非洲的ISP非常多,和东南亚以及印度类似,规模偏小,彼此间的互联互通做的也很差。打个比方,如果在非洲同一个国家两个不同的运营商互相访问,因为运营商之间没有做互联,所以流量需要跑到欧洲绕一圈,或者跑到南非绕一圈。
由此我们想到或许可以在非洲找一个IDC,或者通过云的方式来解决这个问题,但最后发现并不行。因为IDC只会和某些运营商之间有Peering或者购买了运营商的Transit,它无法和所有的运营商都做到完全的互联。假如在IDC里设置服务器,某一个运营商的用户会非常开心,但相对应其它运营商的用户就很痛苦,这些用户的流量需要先转到欧洲,再绕回到非洲来,还不如直接使用欧洲的云服务。
最初我们也不知道这些信息,使用的是欧洲的CDN和云服务来支持业务,后来尝试挪到非洲本地,发现效果更差。最终我们制定的策略就是在较大的ISP网内自建CDN,再使用欧洲的CDN作为备份。
还有一个思路是找寻与ISP直连的第三方CDN,但实际上很难找到。因此第三方CDN只能作为备份和辅助,这是针对非洲网络特点设计的方案。
目前我们自建CDN的部署规模已经相对比较大,图中四达时代logo的位置代表我们在非洲的运营商中铺设的CDN服务器,这些CDN基本都是轻量级的,我们在每个机房里就设置一台服务器,服务器本身是高可用的,它看上去更像是普通的服务器,但内部所有的模块都有备份,比如电源、风扇、背板、交换、计算、存储等模块都是双份的,因此可靠性非常高。我们通过大量铺设这一类服务器,作为边缘的缓存节点,供用户直接在网内访问、播放视频。
3.3 监控与调度系统
使用上面提到的自建CDN服务器,在调度上可能会遇到一些问题。
首先自建CDN仅能供内网用户访问,因为这些CDN没有公网IP,它们的IP地址是类似10.x这样的内网IP。如果调度出现错误,让用户去访问另外一个运营商网内的自建CDN,则必然无法建立TCP连接,所以在调度上需要更加谨慎。
其次是运营商网内的出口不稳定,原因是非洲的运营商运维水平有限。举个例子,我们的一个CDN服务器连接到机房的交换机上,再从交换机出去,有时候机房交换机会丢包,如无任何征兆地丢包90%。运营商自己也没有监控,每次都是我们发现问题后,联系重启交换机进行解决——这其实很影响用户体验。
另外就是一些球赛、演唱会场景,这些场景对于做视频的人来说就和“秒杀”的性质是一样的,会瞬间进来一大批人,运营商的网内出口可能就直接被打爆了。
在发现这些问题后,对于CDN调度就需要做针对性处理,主要有以下3种策略:
- 基于用户体验的调度:对于上述机房交换机的问题,即无征兆地出错而且也不报警,我们在播放器中加了很多埋点,通过播放器实时上报卡顿、启动成功率、下载速度等指标,后台获取到这些信息进行实时分析,分析结果可作为调度策略的参考输入。假设运营商网内出口不稳定,尽管这种情况下CDN本身没问题,但用户体验极差,则用户体验指标会报警,调度系统就会将用户调至备用CDN。
- 基于CDN状态的调度:这点比较基础,例如CDN服务器出现故障、机房网络不通、或者CDN的带宽已经打满,那流量就不能再往这里调度。
- 基于成本的调度:我们会优先将用户调往网内的CDN,网内CDN不可用时再转向第三方CDN。
3.4 音视频技术
音视频技术层面的内容会比较多,首先物理网络本身就不太好,铺设CDN后有一定的改善,但仅仅是少量的提升,并没有质的飞跃,更多的优化需要从技术的角度进行。
具体可以总结为以下几个层面:
- 业务接口的异步化:在播放视频时,用户会认为点开视频的链接,视频就应该开始播放,但实际上业务后台还要做很多事情,比如鉴权,广告等一些策略,这些策略如果是串行执行的,会对首屏时间有很大影响。
- 网络层的优化指通过优化传输协议、拥塞控制算法等提升下载速度、降低建连时间对首屏时间的影响等。
- 视频封装优化可以减少播放器与CDN的交互次数,从而减少首屏时间、降低卡顿。
- 视频编码优化可以降低码率,同样可以减少首屏时间、降低卡顿率。
流媒体协议选择
在分析更具体的问题前,先来说说流媒体协议的选择,我们最终选择的是HLS封装。起初,我们考虑过国内使用较多的HTTP FLV封装,它的延迟低、封装开销比较小,使用的人很多、技术也较为成熟。但就对比实际的需求,我们发现使用HTTP FLV会存在很多问题,例如我们有多音轨和多字幕的需求,很多电影有2个音轨(如英语和法语),有些还要加上当地语言,这样最终就可能会是4、5个音轨。如果我们将所有的音轨打到同一个流里,那这个流的封装效率就很低,用户只会使用一个音轨,但却需要下载整个流。包括多字幕,也是同样的问题,因此我们需要将这些不同的流拆分开来。
除此之外,在音视频数据流分离、平滑的码率切换这些方面FLV做的都不太好。如果使用FLV,我们还需要在它的基础上进行二次开发。再有就是海外第三方CDN的支持问题,大部分海外CDN厂商都表示不支持FLV协议。
另外,当时还有个选择就是DASH,不过我们在2016年开始做研发的时候,DASH的开源工具还非常少,因此最终选择了HLS,各方面需求支持都比较好,技术成熟度也很高。
3.5 首屏时间问题
接下来到具体问题的分析,首先我们要解决的是首屏问题。从用户点击视频到最后视频成功播放需要几个环节,如上面流程图所示。
第一,业务鉴权。像我们这样的付费业务,用户是否有权益是需要校验的,并且校验过程相对复杂。例如有很多人盗流,那我们就需要防黑产,即要判断当前用户是否是合法用户、是否有权限使用这个流。在这里我们做了大量的数据模型来判断用户是否为机器人,只有真实用户才会获得CDN的token。其它业务逻辑还包括播放广告的策略、是否续播、选择用户喜好的码率等,这些业务逻辑都是在用户点击播放按钮之后执行的。
接下来就是选择CDN。因为CDN的数量很多,算上第三方的大约有几十甚至更多,需要作出最为合适的选择,选择CDN后还要进行域名解析。解析域名后开始下载视频文件,因为我们使用了HLS协议,所以播放器要下载M3U8文件,以及切片文件,最后才可以得到首帧的数据。
整条链路是比较长的,如果不做任何的优化,首屏时间基本上要超过十几个RTT。比如按照HLS的规范,m3u8和切片可以放到不同的CDN上,但是这样就不能用同一个TCP连接去下载,需要各自建立连接再先后下载。而且建连次数多还会影响首屏成功率,因为TCP握手的成功率也只有80%,连续建两个连接都成功的概率就只有64%了。
我们通过全流程再看几个数据,第一个是首屏的成功率,这是一个整体的指标。错误率指的是在任何一个环节都有可能出错,比如CDN可能会有错,下载文件时可能会返回404或者403,再或者建连的时候失败了,总之任何环节出错,都会记到错误率指标中。还有主动退出率,假设用户最终没有观看视频,要么是因为出错,要么是因为主动退出。如果是主动退出,我们还要记录主动退出的环节和时间,这些信息对后面的优化有很强的指导意义。
图中展示的是我们在定义指标后采集到的一些数据,上面的横条是启动时间的平均值,不同的颜色代表不同的环节。最左边深绿色为业务接口,蓝色为CDN选择,和刚刚介绍的流程一致。按照流程我们进行了一段时间的采集,通过查看平均的数据,我们发现用户花费了大量的时间在下载切片文件上,这个文件可能有几百k左右的大小,而前面一些环节可能就几十个字节,所以看起来也比较合理。
但实际上如果我们需要优化首屏时间,我们需要看下面的横条,这是85分位的首屏时间分析,下载仍然是耗时最长的,不过因为前面的一些环节会占到整个环节的2/3。如果我们的目的是通过降低首屏时间来降低用户的主动退出率,仅仅优化下载切片的时间是不够的,就算优化成0,前面环节也需要5s左右的时间,用户仍然难以接受。所以在拿到这个数据后我们再分析根本原因,很明显是因为RTT很大,所有环节又都是串行执行,这就会导致首屏时间变得非常长。根据数据得到结论后我们就可以定一个优化的思路。
首屏时间优化方案
首先看业务接口的优化,根据各企业业务的不同,优化方式也多种多样。在我们的业务中像鉴权、广告播发这样的逻辑都可以改为异步,比如向客户端下发一个策略,客户端异步执行,像续播、码率的选择,可以交由客户端自己实现,因为客户端可以记录播放历史,每次App启动时和服务器进行同步。具体视频开始播放时,是否续播由客户端自行决定。这些优化可以减少串行环节,整体流程上可以减少1-2个RTT,在非洲就可以体现为几百ms甚至1秒钟左右的时间节省。
CDN选择包括DNS的解析其实优化思路也是一样的。为节省CDN的选择时间,我们直接在列表页上做CDN的选择,在列表页查看用户的位置,将数据提供给后台做快速选择。APP端也可以异步选择CDN,比如手机的网络有变化,从3G到4G或者切换到WIFI,有产生变化的时候,APP会做一个异步的选择解析,这样就可以保证视频的正常播放,同时在流程上也可以减少2个RTT。
然后就是M3U8下载的问题,要下载就必须先建立TCP连接,而TCP握手需要花1RTT。我们有2种方式来节省建连时间,第一种是CDN选择结束后客户端直接建立连接,然后做心跳保活。在非洲做连接保活很不容易,连接一会就断了,发包发不过去,这时候重建连接就会浪费用户的流量,但不重建的话,等需要下载视频数据时重新建连会更浪费时间。总之要细调这个保活策略。
更理想的是使用QUIC,因为它具有0RTT快速连接的特性。QUIC也需要通过握手建立连接,但因为握手包和数据包是一起发出的,从用户的角度看,就相当于没有握手的时间。当然也同样会存在问题,它的生效比例不是特别高,在谷歌默认的策略里,IP变了0RTT也会失效,这其实是一个很强的约束,因为移动网络的IP很容易就出现变化。根据实际测验,0RTT生效的比例只有50%,谷歌自己的数据是60%左右,当然这也要考虑到地区差异性。做到上述优化又可以节省1-2个RTT。
接下来是M3U8下载的问题。M3U8有master M3U8,也有子M3U8,而且我们用到的是fragmented MP4的封装,没有用TS。封装会增加一个init.mp4文件,文件不大但需要独立地下载,独立下载意味着又会增加一个RTT。于是我们就将这些文件的内容合并到视频的URL中,用户在访问URL时可以直接获取到文件内容,无需多次单独下载。这些文件的内容都是文本或是字符串,我们只需要把字符串传到客户端,由客户端在本地构造M3U8等文件后给到播放器,播放器就可以正常播放。这样做可以节省1~2个RTT。
最后是切片下载的TCP建连时间,有的公司可能会把切片和m3u8放到两个CDN上,这样也就必须分别建立连接,但如果切片和m3u8在同一个CDN上,我们可以用同一个连接,至少在点播上是可行的,因为点播只需要下载一次M3U8,接着下切片文件。而直播可能就不行了,因为直播的M3U8的更新和切片的更新是独立的,它们是在两条线并行地更新,所以这时候必须要有两个连接去做并行的下载。而这种情况下我们对于直播的优化策略就是建连的时候直接建立两个连接。当然如果有使用HTTP2或者QUIC的协议就会更简单一些,因为这些协议支持连接复用,HTTP2和QUIC的建连可能会更困难一些,因为他们建连的数据包更多,不过因为连接可以复用,总体上来说又可以减少1-2个RTT。
所以整体的优化思路其实特别简单,目标也很明确,RTT高本身很难优化,那就直接减少RTT的个数。在所有的优化完成后,通过计算我们发现大约减少有10个RTT,我们在最差的基础上做优化,最终减少10个RTT。那在现实中10个RTT的提升究竟是什么效果?用户在列表页点视频的时候,没有任何其他环节了,甚至连接都建好了,播放器直接去下载视频本身的数据,下载一点数据视频首帧就能出来,所以启动时间会有非常显著的改善。
这就是我们优化的结果。之前首屏时间85分位能到7s多,这个时间对于非洲的用户来说也是难以忍受的,但我们优化完成以后,现在的时间不到3s。对于国内的标准,虽然还是会比较长,但对于非洲用户来说这个时间是可以接受的。
主动退出率这一块也很明显,之前是14%,100人看视频,有14个人因为不愿意等就退出了,这是一个很糟糕的数据。我们做了优化以后它降低了一半大概能到7%左右。当然还有一些用户3s都不愿意等,我们也分析这些用户的行为,发现这些用户可能自己在操作习惯上有问题,比如他们会在频道列表里“乱点”,1s点好几个视频,频繁退出,这样的操作在后台还是会算成主动退出,所以总体上主动退出比例只降低了一半。但对于正常观看视频的用户来说,这一首屏时间已经可以接受了。
3.6 卡顿问题
接下来是卡顿。卡顿这一块的指标体系会更简单一些。播放器先下载M3U8,然后下载切片。如果是直播的话就轮流下载,点播就下载一次M3U8,后面不停下载切片就可以了。再往后就是缓存、解码的过程。这一环节非常简单。
卡顿比这一块的优化思路主要是提升下载速度,下载速度只有250kbps,而且播放器还不能一直下载,这就导致直播的卡顿比要比点播高得多,原因就是直播不能一直下切片,要频繁下载M3U8。
卡顿优化方案
这里的优化思路就是M3U8和切片要并行下载,有一个方法是把M3U8的内容放到切片里面去。这是一个比较有意思的改动,我们直接将M3U8的文本放到切片的http response header中,因为m3u8本身就是个字符串,这样播放器就不用单独下载m3u8了,只需要不停地下载切片。因为每一个切片里都自带了下一个m3u8,这样就节省了单独下载m3u8的时间,整体下载速度自然也就提升了。
然后是缓冲区的优化,因为我们不关心延迟,所以就把缓存区加到了75s。
码率这一块,我们用的fragmented MP4,这个封装的Overhead很低。大家如果是用HLS,就一定要注意这个问题,因为大部分情况下HLS用的是TS封装,而TS封装的Overhead非常高,在小码率下能到10%,比如音视频原始码流的码率是200kbps,封装出来就变成220kbps了,这是很不划算的。而fragmented MP4只有1%的overhead,但同样fMP4也有它自己的问题,它会把音频编在前面去,视频编在后面,这样就会影响启动的时间,所以我们还需要自己去做一些交织的封装。
编码部分,刚刚有提到过我们主要针对内容来进行优化,经过处理优化提升低码率下的画质以及播放流畅性。
CDN部分,通过自建CDN、优化CDN选择策略等,也可以明显提高下载速度。
最后,关于BBR/QUIC这部分还是值得说一下,起初我们使用BBR的拥塞控制算法,收益并不明显,与预期的差别很大,后面分析得到结论可能是因为拥塞过于严重。总地来说,BBR算是一个相对君子一点的算法,不像cubic一样疯狂发包直至丢包为止,BBR是检测到开始拥塞就停止发包,但由于非洲的网络本身拥塞就很严重,因此BBR的收益也就没那么显著,后面我们还会进行一些其它的尝试。
卡顿优化之后的收益也是非常显著的,在85分位下,原来直播的卡顿比有15%,现在不到2%,就在非洲来说这是个不错的结果。而对于点播,85分位播放卡顿比不到1%,也是个不错的结果。
这几件事情做完以后我们的用户体验得到了很大的提升,促进了业务的发展。
3.7 优化思路总结
最后简单总结一下。首先,数据是改进的基础,想准确发现问题需要预先埋特别多的点。如果仅靠臆想问题所在,然后直接修改程序,那结果很可能是随机的。因此我们甚至在网络协议栈中也埋了点把一部分用户的网络协议栈日志拉回来,比如每一个IP包什么时候发,什么时候丢,为什么重发,重发的是否及时,每一个数据都拉回来做分析。至于播放器和业务埋点就更基本了,一定要埋全。
其次,要在分位线上看数据,不能只看平均值,平均值会掩盖极端的情况,结果把我们导向错误的优化方向。
最后是抓核心指标,对于我们来说就是牺牲延迟,把其它指标做好。要能找到核心瓶颈并针对其进行优化,这样才能保证比较高的做事效率。