腾讯研发总监王辉:十亿级视频播放技术优化揭秘

urbn5787 7年前
   <p style="text-align: center;"><img src="https://simg.open-open.com/show/4b5f0b1b9de3ca96155f5f3b325aa95c.jpg"></p>    <p>QQ 空间在 2016 年日均视频播放量由年初的千万级迅速突破到十亿级,过程中也对整个视频播放技术的可靠性、性能、操作体验等方面提出严峻的考验,相关质量急需提升。经过多个迭代持续和各项优化,外网整体质量已经达标:在保证播放成功率提升到 99.92% 的基础上,首次缓冲耗时降到 0.70s,二次缓冲概率降到 0.48%,做到稳中有升。我们将从视频组件的整体架构,优化效果衡量,首次缓冲耗时优化,播放成功率优化,二次缓冲优化,总结六个方面介绍视频点播在整个优化过程中的心路历程。</p>    <h2><strong>写在前面</strong></h2>    <p>我今天的话题是“十亿级视频播放技术优化揭密”。介绍我们团队在去年短视频风口上,视频播放量从 5000 万到十亿级过程中的一些技术实践,希望我的分享能给大家带来一些借鉴和参考。</p>    <p>自我介绍一下,我叫王辉,来自腾讯,从 2009 年开始从事 QQ 空间技术研发,近期主要关注手机短视频、视频直播、AI 智能硬件。我个人喜欢跑步,觉得跑步是解决程序员亚健康的一个比较好的方式。</p>    <p><img src="https://simg.open-open.com/show/789d732a8bdfca9fc03f3520883ecfa8.jpg"></p>    <p>众所周知,短视频去年是一个风口,起因是来自 非死book 2015 年 Q3 的财报,财报表明在 非死book 平台上每天有 80 亿次短视频播放,给 非死book 带来了强劲的广告收入,正是这个数据给国内核心大公司和创业公司带来的一些新的突破口。</p>    <p><img src="https://simg.open-open.com/show/520bd3af20daf275dae522024284995f.jpg"></p>    <p>其实短视频已经不是一个新的概念,从 2006 年开始国内就有很多公司在做短视频。随着 非死book 吹起短视频风,去年在短视频行业有近百款应用出现,中国网民里面每 5 个里面就有 1 个是短视频的用户,短视频成为互联网的流量入口。</p>    <p><img src="https://simg.open-open.com/show/bc6f521be9ebbc7f786443e8d903382c.jpg"></p>    <p>QQ 空间也在这个风口中,从 2015 年 11 月份的每天 5000 万视频播放量,经过一年的耕耘细作,徒增到 2016 年 12 月份的 10 亿量级,现在还在不断增长。</p>    <p><img src="https://simg.open-open.com/show/046a7f557dd402291bc4394d09aaace2.jpg"></p>    <p>我的分享主要是按照我们产品迭代的几个关键步骤展开:</p>    <p>1、首先是快速上线,2015 年我也是跟随着大家的体验快速上线了新短视频的体验;</p>    <p>2、其次面临的是成本问题,在做的过程中做了一些成本的优化工作;</p>    <p>3、然后是体验优化。在解决成本问题之后,短视频的观看体验要做到极致。比如说视频的秒开、不产生缓冲、不卡、成功率的提升。</p>    <h2>快速上线</h2>    <p><strong><img src="https://simg.open-open.com/show/01390c945d1c2d5fd926396c0e5cc66c.jpg"> </strong></p>    <p><img src="https://simg.open-open.com/show/a5d16da6f1db7f0978bae219c8532e5e.jpg"></p>    <p>首先看快速上线,在开始之前,我先介绍一下我们的团队职责,我们团队负责手机 QQ 和手机 QQ 空间两个 APP,每个 APP 有 iOS 和 Android 两个团队,一共四个团队,四个团队负责两个 APP。在这个项目中,我们四个团队要针对两个平台实现四套逻辑,这里的效率是存在一定的问题。</p>    <p><img src="https://simg.open-open.com/show/9f42387175cddf2073115855bd3a04a1.jpg"></p>    <p>关于短视频体验,在这之前,我们也只是做到能播放而已,没有做很精细的工作,并且这里的产品观感体验也不是很一致,也不是很好。</p>    <p><img src="https://simg.open-open.com/show/6c611e35d74a3bb3cb053b88edf94452.jpg"></p>    <p>技术上,之前也只是做很基础的架构,直接由播放器连接服务器下载数据,达到能播放就可以。之前我们没有积极去做这个事情,导致播放成功率低、失败原因未知、不支持边下边播、缓冲时间比较长等问题,流量浪费也比较严重。</p>    <p><img src="https://simg.open-open.com/show/a77d5938268829299e1fe41ce12e49b3.jpg"></p>    <p>在产品上要解决的,是在整个 APP 里面把所有产品的体验做到一致,比如说每个功能的观看体验,视频浮层的体验,统一观看体验也为我们项目清除了很多障碍。</p>    <p><img src="https://simg.open-open.com/show/35f8e0ae5f50f93d9fa9f5f5e5d4119a.jpg"></p>    <p>而这里的技术上的要点是非常关键的,第一个是边下边播,这是基础的要求,是为了加快视频播放速度。第二个是流量的控制,这么大的平台,之前只是做 5000 万的播放量,如果没有流量控制的云策略,可能到后面流量是无法把控的。第三,刚才讲到团队的现状,团队要负责两个 APP,这里要做代码复用,不可能再像之前一样四个团队维护四套代码,第四,我们支持第三方的视频源。第五,需要完善监控上报,对业务知根知底。</p>    <p><img src="https://simg.open-open.com/show/95e91b4840a35d9cc87a981f594f9df2.jpg"></p>    <p><img src="https://simg.open-open.com/show/5f417696194684aadaae2f769067347f.jpg"></p>    <p>可以看到,完成核心技术要点最核心的一点是如何控制视频的下载,传统的方式是播放器直接塞播放地址给播放器,它就可以直接播放,这其实是一个黑盒。我们在中间加了一个本地代理,播放器与服务器的数据请求,我们完全可以把控。在这个过程中,比如说播放器要数据时,可以给它更多的数据,这样能解决它缓冲的问题。有了这层代理之后,架构也更清晰一点。</p>    <p><img src="https://simg.open-open.com/show/a2cfe266468dcd1c49bd65ae34efce57.jpg"></p>    <p>基于 MVC 架构,在 MODEL 一层做一些业务的逻辑,在 VideoController 这一层做控制视频的播放和下载。有了下载代理之后,就可以通过代理管理下载,在 APP 里面有很多的视频请求,VideoProxy 可以管理这些请求,做流量控制,做预加载,还可以做优先级调度和做监控上报,下载逻辑层则主要关注怎么优化服务器,对接缓存管理层,同时我们抽象出了一个数据层,我的数据源可以是 HTTPDataSource,也可以读本地,也可以是来来自腾讯视频的数据源,也可以是第三方 APP 的数据源,协议层主要是 HTTP、HTTPS、HTTP2 的解决。</p>    <p>在 VideoController 的逻辑里,其实都可以放到 C 层来实现,这样安卓和 iOS 完全可以通用,这一层的逻辑可以在 QQ 和 QQ 空间两个 APP 里面使用,相当于是我们一套逻辑可以完全复用,不用再开发四套逻辑。</p>    <p><img src="https://simg.open-open.com/show/6aa98d8416c1eabe4391646f138089e8.jpg"></p>    <p>我们团队的职能也做了相应调整,之前可能是按团队划分,四个团队负责四个终端,现在可能是按 FT 的方式划分做视频的团队,iOS 做视频的团队可能负责 QQ 和 QQ 空间里的业务,安卓也是如此。直播的 FT 也可以这样划分,iOS 的负责 iOS 的两个 APP,安卓的负责安卓的两个 APP,这样代码复用更清晰一点,我的团队更专注一点。视频的团队专注视频的研发。</p>    <p><img src="https://simg.open-open.com/show/e8ac8367b4b57579b2f67f67bb80bf5a.jpg"></p>    <p>监控上报,肯定是不可缺少的,这是一个成熟的项目必备的要素:</p>    <p>1、问题定位,老板跟用户反馈说我这个视频播不了,要有一套成熟的问题定位的方式;</p>    <p>2、耗时统计,用户播放这个视频花多长时间播出来,这也是要了解到的;</p>    <p>3、成功率统计,外网用户播放视频的成功率是多少?还要通过实时报警,才能及时知道外网发生一些故障。</p>    <p><img src="https://simg.open-open.com/show/50c1a7038777199156bb64204764cd1d.jpg"></p>    <p>传统的捞 Log 方式大家都有,但是这种方式效率太低,需要等用户上线之后才能捞到 Log,Log 捞到之后还得花时间去分析。我们做法的是在关键问题上做一些插装,把每一类错误和每一个具体的子错误都能定义出来,这样一看错误码就知道播放错误是由什么原因导致的。</p>    <p><img src="https://simg.open-open.com/show/121adc140e1b7cd9b657f3724f1c4cf5.jpg"></p>    <p>还可以把每次播放视频的链路所有关键流水上报到统计系统里来,每一次播放都是一组流水,每一条流水里面就包含了例如首次缓冲发生的 Seek,或下载的链接是多少,下载的时间是多少,有了这些流水之后,用户反馈播放失败,我首先可以用流水看发生了什么错误?错误在哪一步?每一步信息是什么?几秒钟就可以定位到问题。</p>    <p><img src="https://simg.open-open.com/show/6a76e194cae15461feb8b1c296a114da.jpg"></p>    <p>有了这个数据上报之后,还可以做一些报表。比如说可以做错误码的报表,有了报表之后就可以跟进哪个错误是在 TOP 的,负责人是谁,原因是什么,都可以看到。</p>    <p>我们也有自己实时的曲线,可以看到各项数据的情况。</p>    <p><img src="https://simg.open-open.com/show/a14999ac453727ae888abeef888c78fb.jpg"></p>    <p>在告警方面,基于成功率和失败率的统计,进行实时告警。一出现错误码,微信立即可以收到提醒,提醒说是什么原因导致这次告警,完全全自动。</p>    <h2>成本优化</h2>    <p><img src="https://simg.open-open.com/show/386cc941ba609b71bb8c9bb13864ad9f.jpg"></p>    <p><img src="https://simg.open-open.com/show/7f8fce123ed7533a18262f53dac46de2.jpg"></p>    <p>上线一个月之后,一个坏消息一个好消息。好消息是播放量涨了 4 倍,坏消息是带宽涨了 6 倍,带宽优化是每个做视频的人必须要面临的问题!</p>    <p><img src="https://simg.open-open.com/show/b59407cfe817011860ff61cbc4292e13.jpg"></p>    <p>我们也分析这个过程中的原因,发现因为改为边下边播之后用户观看视频的意愿比较强,用户有挑选心理,不是每个视频都去看,看了一下之后不喜欢就划走了,之前下载的那部分其实是浪费的。</p>    <p><img src="https://simg.open-open.com/show/52ece54b2e36f3489bfe04b73aadf2e5.jpg"></p>    <p>如果之前不做限速的话,一点开视频就疯狂地下数据,带宽有多大就下多少的数据,这样浪费很严重。我们采取的第一个策略是进行流量控制。在高峰期播放到第 10 秒时,预下载 N 秒数据,下载到 N 秒就停下来。然后,可以做多级限速。一开始不限速,下载到合适时机做 1 倍码率限速。高峰期时预加载的数据会少一些,防止高峰期时带宽占用明显,这是初级的策略。最终我们也有码率切换的策略。这对用户的观看体验影响比较大,这也是之前必备的一个策略。</p>    <p><img src="https://simg.open-open.com/show/026cc2dc5118754695ecbe6408ca0d28.jpg"></p>    <p>上线这个策略之后,对带宽的优化还是比较明显的。在高峰期时从 18:00 到凌晨 1 点带宽下降 25.4%,这个是我们不断灰度最终确定的值。这个值会影响播放缓冲,因为数据少的话必定会卡顿,在卡顿之间和流量之间取了一个最优值,最终是 25.4%。</p>    <p><img src="https://simg.open-open.com/show/4fe90afb17bb3dd1306b0da0f4788377.jpg"></p>    <p>但这样肯定是不够的,因为流量涨的还是很明显的,我们想到 H.265,压缩率相对于 H.264 提升了 30%-50%,但它的复杂度也是呈指数级上升。复杂度导致它的编解码耗时更长,占用资源也更长。如果把 H.265 用在客户端上的话,可能要评估一些点,比如说在编码上面,现在手机上没有做 H.265 硬件支持的,相对于 H.264 的耗时 3-7 倍,之前耗时可能是 10 分钟,而现在可能需要到 70 分钟左右。</p>    <p><img src="https://simg.open-open.com/show/ef0a16dede780a0f32eaa0659223ef06.jpg"></p>    <p>解码的硬件支持 H.265 的也很少,耗时差不多是一样的。解码是可行的,你可以采用软解的方式,这个带来的问题是 CPU 占用非常高,可能之前 H.264 占 20% 的 CPU,H.265 占 70%、80% 左右,带来的问题是发热和耗电。</p>    <p>结论,解码是可行的,但是编码不用考虑,在移动客户端不可行的情况下,那编码就要放在后台来做了。</p>    <p><img src="https://simg.open-open.com/show/1a5cf6fd2a98ecdf7238af7c32f5dac0.jpg"></p>    <p>为了解决如何在我们手机上能够解码的问题,对手机的解码能力做一次评估。我在合适的时机做一次大规模的浮点数运算,将数据上传到后台服务器进行云适配。如果当前的指数满足 H.265 条件的话,可以给你下载 H.265 视频给你播放。从而保证软件解码柔性可用,针对视频源规格按机型适配降级,保证用户视频播放体验。</p>    <p><img src="https://simg.open-open.com/show/6cd632dfa742cbe86c78db2d4805b736.jpg"></p>    <p>经过评估之后,判断当前机型更适合 360P 还是 480P 等等,保证如果手机不适合 H.265 就不会给你的手机下发 H.265 视频的。</p>    <p><img src="https://simg.open-open.com/show/2f47edd8b3ab9a2ad1c4873cc1a5cf71.jpg"></p>    <p>经过我们的统计,外网上有 94% 的手机还是支持 H.265 解码的。支持 1080P 手机的解码占 46%。</p>    <p><img src="https://simg.open-open.com/show/98e95824f2e0c2b149e6678c807efdfe.jpg"></p>    <p>编码只能在后台做,如果在视频后台进行全面编码的话,是不现实的。因为编码复杂度呈指数级上升,拿后台服务器进行编码也是不可行的。我们的做法是只用热点视频进行后台转码,不是所有视频都去编码,对观看量在 TOP N 的视频进行编码,只需要编码少量的视频就可以带来流量优化效果,因为 TOP N 就占了全网 80-90% 的流量,只对少量的视频进行解码,让 90% 的视频享受转码的优势。</p>    <p><img src="https://simg.open-open.com/show/476797387714fb4465147ce0ef8269eb.jpg"></p>    <p>因为热点转瞬即逝,可能前一分钟是热点,后一分钟就不是热点,社交网络的传播非常快,我们给后台的要求是转码速度一定要快。在之前没有优化时,转一个 10 分钟的视频要半个小时左右。后来做了分布式处理之后,转 10 分钟的视频只用 2-3 分钟。一些短视频最长 5 分钟左右,只要监测到视频很热的话,1 分钟之内就能转出来,就是 H.265 了。</p>    <p>同样,在 H.265 编码器上做了一些优化,比如编码速度和码率的节省都会有提升。</p>    <p><img src="https://simg.open-open.com/show/4c79577645a02f8201d5a50b7a962c02.jpg"></p>    <p>经过 H.265 尝试之后,带宽进一步下降,节省了 31% 左右。</p>    <p><img src="https://simg.open-open.com/show/97b1527fd3b7c91ddde12a7192de1780.jpg"></p>    <p>带宽问题解决之后,面临的下一个问题是体验优化。用户最想要的是视频能立马播出来 。</p>    <p><img src="https://simg.open-open.com/show/274ba7a79b57d3fa54d11de096fe06a9.jpg"></p>    <p>我们定了一个秒开技术指标,只要这个视频从到我的视野范围,到视频播出来之间的耗时在一秒以内。这也是对标 非死book 的体验,非死book 一打开动态,视频是能立即播出来的,不需要等待就能播,这个体验其实很顺畅。</p>    <p><img src="https://simg.open-open.com/show/fdc086684f10a1a821e8d937aeea5ed7.jpg"></p>    <p>核心的流程主要是三个步骤:</p>    <p>1、客户端初始化播放器;</p>    <p>2、下载数据;</p>    <p>3、等待播放。</p>    <p>这里主要有两个大的耗时点,第一下载视频数据耗时;第二个是客户端的耗时,下载视频数据耗时的话,主要是下载数据量和下载的速度。</p>    <p>这里有一个很直接的问题,播放器需要下载多少数据才能播放?</p>    <p><img src="https://simg.open-open.com/show/8d1eb458ec29f9621d4bc1df832fea33.jpg"></p>    <p>我们可以看一下 MP4 格式,MP4 其实是一个比较灵活的容器格式,每个东西都是用 Box 表达的,每个 Box 又可以嵌入到另外一个 Box。MP4 主要由 MOOV 和 Mdata 组成,MOOV 是囊括了所有的视频关键信息,肯定是先把 MOOV 下载完之后才能找视频数据才能播起来。不巧的是,在我们外网会发现有 5% 左右用户上传的视频,它的 MOOV 是在尾部的。后来也发现,有很多安卓手机比如说山寨机,一些摄像头处理的厂商可能比较偷懒,因为他们只有在你采集完信息之后才能知道他所有的信息,他可能把所有的信息放在尾部。</p>    <p><img src="https://simg.open-open.com/show/e7108da7e9515c687ab9625f2f6e8333.jpg"></p>    <p>对于 iOS 来说,一开始把头部下载了,找不到 MOOV,就猜测 MOOV 在尾部,多一次 Range 请求去探测 MOOV 到底在哪?基本做法是去尾部探测, 如果 MOOV 在其他地方的话,这次播放肯定是失败的。安卓某些手机如果没有经过处理,MOOV 在尾部的情况下需要下载整个视频才能开始播放。</p>    <p><img src="https://simg.open-open.com/show/35ef9e1df3eda7eadc294a5fa580b2d6.jpg"></p>    <p>我们的处理方式,用户在后台统一做一次转码修复,客户端采集后做一次转码修复。</p>    <p><img src="https://simg.open-open.com/show/dac44492ce49fcd8036f9092be933298.jpg"></p>    <p>看一下 Mdata,视频的原数据。目前大部分是 H.264 编码,H.264 通过帧预测的方式进行视频编码。这里有一个 GOP 概念,也是在直播里面经常谈的。一般的播放器需要下载完整的 GOP 数据才可以播。</p>    <p><img src="https://simg.open-open.com/show/2ebf17fc2b60e3c4c0e451f779a3cf36.jpg"></p>    <p>需要下载多少数据才能播呢?每个播放器的行为也不一样。iOS 要下载一个完整的 GOP 才可以播。像 FFmpeg Based Player 的话只需要关键帧就可以播出来。安卓是比较尴尬的一个系统,在 6.0 及以下,需要下载 5 秒视频数据才可以播起来。</p>    <p><img src="https://simg.open-open.com/show/bc1c06e04b9dc9f60c91d375bfb17bff.jpg"></p>    <p>如果需要下载 5 秒数据才可以播的话,肯定是非常慢的。我们这里的策略会采用 FFmpeg Based Player 自己来做解码,要关注兼容性和耗电的问题。解决了 Mdata 之后,如果 MOOV 数据在头部,拿关键信息进行播放的话,其实需要的开始播放数据量是非常小的。</p>    <p><img src="https://simg.open-open.com/show/aa649cfed524c9ad2587154e6c9ffce8.jpg"></p>    <p>对于下载优化,会有一个防盗链的请求,通过 HTTP 拿到真实的播放 URL 才可以下载数据。</p>    <p>但是在手机上执行 HTTP 请求非常耗时,这里走私有长连接通道做这个事情。</p>    <p><img src="https://simg.open-open.com/show/11cbe47c1f800c5bb0d8590135b86400.jpg"></p>    <p>关于优化下载链路,这里也是谈的比较多的,一般也是直接输出 IP 地址,利用 IP 地址做跑马的策略,兼顾性能的效率,这个是用的比较多的方式。</p>    <p><img src="https://simg.open-open.com/show/8d27e4ed1966d42f0298bc4be35fd8f4.jpg"></p>    <p>进一步思考,按照普遍 600K 码率的话,我们统计到现在 APP 上面下载的平均速度是 400K 左右,这样计算的话,可能在安卓上面播放一个视频的话,需要将近 0.9 秒左右才可以下载到你需要的数据。</p>    <p><img src="https://simg.open-open.com/show/5c9542697e6132ebeb8719ee4e1b8b69.jpg"></p>    <p><img src="https://simg.open-open.com/show/016bc4ec3a4102b3d2d71a1cbe4afc31.jpg"></p>    <p>如果码率再进一步提升的话,可能会更大,这其实我们也做了一些场景分析,会发现我们是社交网站,它有好友动态,视频在好友动态里播放,或者是在视频浮层里播放,我们的选择是预加载的策略,这也是常见的策略。</p>    <p><img src="https://simg.open-open.com/show/a88b33f31288acef3fb183efc4756539.jpg"></p>    <p>我们会在当前看这条动态时,预加载后面视频的关键信息,比如会加载头部信息和需要播放的数据。在播放当前视频时,加载一定数据之后会加载下一个视频的数据,这些都可以做到的。预加载有一个问题,我们之前踩了一个坑,可能预加载视频时还是要优先图片的。视频当然重要,但是社交网络的图片更重要,可能在预加载视频时会考虑到更高优先级的一些任务。</p>    <p><img src="https://simg.open-open.com/show/86d3f0fa822fbac8ecd8a7b28a32cfcd.jpg"></p>    <p>优化效果也是比较明显,经过刚才几个策略,一个是我们对头和播放器的处理,我们对防盗链的处理,还有对下载链路的处理和预加载,这样我们的耗时大幅度减少了,之前是 1.8 秒降到 0.6 秒左右。</p>    <p><img src="https://simg.open-open.com/show/13d443c800684545f07275e289010645.jpg"></p>    <p>客户端的性能也是让人容易忽视的问题,发现有些用户虽然有视频的缓存,但是播起来还是很慢,这其实是客户端性能的影响。</p>    <p><img src="https://simg.open-open.com/show/43f88874772cd2a5684ca617facfd08d.jpg"></p>    <p>因为视频涉及到的流程比较多,在这个过程中还要更关注客户端的影响,要分析下客户端哪些在抢占视频播放资源,我们之前犯过一些错误,md5 会卡住一些流程,或者是 HttpParser 会阻止你的任务,会导致视频播放更慢。</p>    <p><img src="https://simg.open-open.com/show/5579216e5e45f60447646cc12592250e.jpg"></p>    <p>在优化视频播放过程中,我们在 4 月份也做直播。直播这里面插入个事情,我们要播放直播的视频流,是 HLS 的视频,在好友动态里面可以观看直播的内容。HLS 在安卓上面体验非常差,因为安卓 3.0 之后对 HLS 基本没有做的优化工作,这里每次安卓上播放 HLS 需要等待 6-9 秒。</p>    <p><img src="https://simg.open-open.com/show/6a314c304b17a2f70917e51e602e0573.jpg"></p>    <p>分析发现它的处理也不是很得当,因为安卓系统请求链路较长,串行下载,需要下载 3-4 片 TS 才能启动播放,下载 3 个分片的话,耗时就会很久。之前提到我们这里有代理,有了代理之后做事情方便很多了,通过里获取 M3U8,解析 M3U8 里面有哪些文件,可以做并行下载,只让他下载一次 M3U8,这样下载速度大幅度提升。回到刚才架构上,有了下载代理层的话,你可以做 HLS 的加速和管理,可以加入 HLS 的视频源。</p>    <p><img src="https://simg.open-open.com/show/a28e039a3f3bf95346f90db3c8b3e5b5.jpg"></p>    <p>回到刚才架构上,有了下载代理层的话,可以做 HLS 的加速和下载管理,可以加入 HLS 的视频源。</p>    <p><img src="https://simg.open-open.com/show/ed1b03adf2c8af04441650d1e4b34855.jpg"></p>    <p><img src="https://simg.open-open.com/show/bb4f9fa5f4235f9dfda6ac95ca211cf3.jpg"></p>    <p>HLS 优化效果也是很明显的,之前需要 6 秒左右,现在 1 秒左右就可以播起来。整体从之前的 2 秒左右,现在优化到 700m 秒,0-1 秒的占比目前在 80% 左右,80% 用户都可以在 1 秒内播视频。</p>    <h2>体验优化</h2>    <p><img src="https://simg.open-open.com/show/ff20d391ea1e21b96aa4edf820e3e6a5.jpg"></p>    <p>还有一个是用户比较关注的问题,观看视频时卡,观看一会卡了一下,loading 数据,loading 完以后又卡,这个体验非常差,我们希望所有的视频都不卡。</p>    <p><img src="https://simg.open-open.com/show/62af532553389d43aadc2b6bcf2e7860.jpg"></p>    <p><img src="https://simg.open-open.com/show/7c1f918810849b9097069a0445e7431f.jpg"></p>    <p>其实这有两个播放场景,一个是正常场景,边下边看,数据在下载。对于正常场景下载时会做一些带宽调整,在低速时会做切换 IP 的处理,比如说当前连通 IP 的耗时比较久的话,会做一些处理,也会对网络进行速度限制。</p>    <p><img src="https://simg.open-open.com/show/24941d19175f943b06fc5bab88d2dd8b.jpg"></p>    <p>针对 Seek 场景,用户拖动,如果文件缓存系统是顺序存储系统的话,必然会造成拖到这里时,后面的缓存数据没有办法下载到系统里面来。只要用户每次拖动,拖动后的下载数据没法存到硬盘上来。</p>    <p><img src="https://simg.open-open.com/show/2ef75747f26216f4811944950be297c6.jpg"></p>    <p>我们就对存储做了一次重构,支持文件空洞。会按照一兆的方式进行文件碎片划分,这就是视频的数据,每一兆就是个文件分片,通过它的 Key 和文件进行存储,这样好处是可以分段存储,可以允许逻辑空洞,拖动的话也可以在后面存储,也不依赖数据库,通过文件名可以知道是从哪个位置到哪个位置的存储。这样淘汰缓存高效一点,可以制定更灵活的缓存策略。可以淘汰更低粒度的文件,比如 seek 之后的文件可以保留,还可以对文件加密。</p>    <p><img src="https://simg.open-open.com/show/f4ae8dca769fa9e8475e7d82fec90f7c.jpg"></p>    <p>产生卡顿的用户里面,90% 是因为进行拖动,拖动之后又没有缓存数据,所以这里有可能导致缓存。统计效果也是比较明显的,上了分片缓存之后,之前的缓存概率是 4.6% 左右,最后下降到 0.48%,基本上看不到发生缓冲的场景。</p>    <p><img src="https://simg.open-open.com/show/edb425e669a533b22a486f7d2e17ce1d.jpg"></p>    <p><img src="https://simg.open-open.com/show/074951aae9c1ec0a4b3491686ea3875d.jpg"></p>    <p>成功率优化,也是比较关键的指标。成功率优化没有捷径,可能是 Case by Case 各个击破。针对错误进行编码,有几百个错误码,每一个错误码捞 log 去看,错误码原因进行上报,每次进行循环一个个错误码进行解决。</p>    <p><img src="https://simg.open-open.com/show/f5d3f014e862729a9add862e74630789.jpg"></p>    <p>DNS 劫持是比较多的,会劫持你的请求。这个是在国内比较常见的劫持,有的小运营商按 URL 劫持视频内容,可能直接污染 DNS 让你查找不到 CDN,这是比较多的,还有一些网络不稳定的影响导致。更高级的直接污染视频内容,让视频内容是错误的。</p>    <p><img src="https://simg.open-open.com/show/4b299cfa672e88ad41210f2e0edbb2ce.jpg"></p>    <p>播放比较多的可能是一些编码的原因,手机采集出来的视频在低端手机上播不出来,我们会对这些视频进行修复。</p>    <p><img src="https://simg.open-open.com/show/db356897a1684bcad3b1c3d070a60729.jpg"></p>    <p>逻辑上的问题,因为播放器是有状态机的,开发人员比较多,每个人过来加一个逻辑的话,会导致播放状态出现问题。</p>    <p>我们解决播放器错误的方法:HOOK 播放器接口与回调,实现播放器状态机,监控插放器 API 的调用是否合法,不合法直接告警或 Crash。帮助开发快速定位问题,同时减轻测试同事的负担,封装成 UI 组件,使其它开发不必理解播放器。</p>    <p><img src="https://simg.open-open.com/show/0a5982be51342ed8f2463f8a4fc5af56.jpg"></p>    <p>最终优化的成果是这样的,下载成功率优化前是 97.1%,优化后是 99.9%。播放成功率优化前是 97.0%,优化后是 99.9%。首次缓冲耗时优化前是 1.95s,优化后是 0.7s。二次缓冲概率优化前是 4.63%,优化后是 0.48%。数据还是很可观的。</p>    <p> </p>    <p>来自:http://36kr.com/p/5084585.html</p>    <p> </p>