QQ空间十亿级视频播放技术优化揭密

企业动态
QCon是由InfoQ主办的全球顶级技术盛会,每年在伦敦、北京、东京、纽约、圣保罗、上海、旧金山召开。自 2007年 3月份首次举办以来,已经有超万名高级技术人员参加过QCon大会。QCon内容源于实践并面向社区,演讲嘉宾依据热点话题,面向 5年以上工作经验的技术团队负责人、架构师、工程总监、高级开发人员分享技术创新和最佳实践。

 4月18日QCon性能优化面面观专题会议上,腾讯研发总监王辉以“十亿级视频播放技术优化揭秘”为主题,用QQ空间的日均播放量一年内从***突破到十亿级所面临的严峻考验为切入点,为大家分享视频团队在视频组件的整体架构、优化效果衡量、带宽优化、秒开优化、缓冲优化、成功率优化等六个方面的技术实践。

 

王辉:大家早上好!我叫王辉,来自腾讯,从2009年开始从事QQ空间技术研发,近期主要关注手机短视频、视频直播、AI智能硬件。很高兴能在QCon上与大家一起分享和交流。我今天的话题是“十亿级视频播放技术优化揭密”。主要介绍我们团队在去年一年短视频风口上,我们的视频播放量从5000万到十亿级过程中的一些技术实践,希望我的介绍能给大家做一些借鉴和参考。

 

众所周知,短视频去年是一个风口,起因是来自Facebook 2015年Q3的财报,财报表明在Facebook平台上每天有80亿次短视频播放,给Facebook带来了强劲的广告收入,正是这个数据给国内核心大公司和创业公司带来的一些新的突破口。其实短视频已经不是一个新的概念,从2006年开始国内就有很多公司在做短视频。随着Facebook吹起短视频风,去年在短视频行业有近百款应用出现,中国网民里面每5个里面就有1个是短视频的用户,短视频成为互联网的流量入口。

QQ空间也在这个风口中,从2015年11月份的每天5000万视频播放量,经过一年的耕耘细作,徒增到2016年12月份的10亿量级,现在还在不断增长。

我的演讲主要是按照我们产品迭代的几个关键步骤展开:

首先是快速上线,2015年我也是跟随着大家的体验快速上线了新短视频的体验。

其次面临的是成本问题,在做的过程中做了一些成本的优化工作。

然后是体验优化。在解决成本问题之后,短视频的观看体验要做到***。比如说视频的秒开、不产生缓冲、不卡、成功率的提升。

快速上线

 

在开始之前,我先介绍一下我们的团队职责,我们团队负责手机QQ和手机QQ空间两个APP,每个APP有iOS和Android两个团队,一共四个团队,四个团队负责两个APP。在这个项目中,我们四个团队要针对两个平台实现四套逻辑,这里的效率是存在一定的问题。

关于短视频体验,在这之前,我们也只是做到能播放而已,没有做很精细的工作,并且这里的产品观感体验也不是很一致,也不是很好。

技术上,之前也只是做很基础的架构,直接由播放器连接服务器下载数据,达到能播放就可以。之前我们没有积极去做这个事情,导致播放成功率低、失败原因未知、不支持边下边播、缓冲时间比较长等问题,流量浪费也比较严重。在产品上要解决的,是在整个APP里面把所有产品的体验做到一致,比如说每个功能的观看体验,视频浮层的体验,统一观看体验也为我们项目清除了很多障碍。

 

而这里的技术上的要点是非常关键的,***个是边下边播,这是基础的要求,是为了加快视频播放速度。第二个是流量的控制,这么大的平台,之前只是做5000万的播放量,如果没有流量控制的云策略,可能到后面流量是无法把控的。第三,刚才讲到团队的现状,团队要负责两个APP,这里要做代码复用,不可能再像之前一样四个团队维护四套代码,第四,我们支持第三方的视频源。第五,需要完善监控上报,对业务知根知底。


 

可以看到,完成核心技术要点最核心的一点是如何控制视频的下载,传统的方式是播放器直接塞播放地址给播放器,它就可以直接播放,这其实是一个黑盒。我们在中间加了一个本地代理,播放器与服务器的数据请求,我们完全可以把控。在这个过程中,比如说播放器要数据时,可以给它更多的数据,这样能解决它缓冲的问题。有了这层代理之后,架构也更清晰一点。


 

基于这样的架构,在MODEL一层做一些业务的逻辑,在VideoController这一层做控制视频的播放和下载。有了下载代理之后,就可以通过代理管理下载,在APP里面有很多的视频请求,VideoProxy可以管理这些请求,做流量控制,做预加载,还可以做优先级调度和做监控上报,下载逻辑层则主要关注怎么优化服务器,对接缓存管理层,同时我们抽象出了一个数据层,我的数据源可以是HTTPDataSource,也可以读本地,也可以是来来自腾讯视频的数据源,也可以是第三方APP的数据源,协议层主要是HTTP、HTTPS、HTTP2的解决。

在VideoController的逻辑里,其实都可以放到C层来实现,这样安卓和iOS完全可以通用,这一层的逻辑可以在QQ和QQ空间两个APP里面使用,相当于是我们一套逻辑可以完全复用,不用再开发四套逻辑,我们团队的职能也做了相应调整,之前可能是按团队划分,四个团队负责四个终端,现在可能是按FT的方式划分做视频的团队,iOS做视频的团队可能负责QQ和QQ空间里的业务,安卓也是如此。直播的FT也可以这样划分,iOS的负责iOS的两个APP,安卓的负责安卓的两个APP,这样代码复用更清晰一点,我的团队更专注一点。视频的团队专注视频的研发。

监控上报,肯定是不可缺少的,这是一个成熟的项目必备的要素。

***, 问题定位,老板跟用户反馈说我这个视频播不了,要有一套成熟的问题定位的方式。

第二, 耗时统计,用户播放这个视频花多长时间播出来,这也是要了解到的。

第三, 成功率统计,外网用户播放视频的成功率是多少?还要通过实时报警,才能及时知道外网发生一些故障。


 

传统的捞Log方式大家都有,但是这种方式效率太低,需要等用户上线之后才能捞到Log,Log捞到之后还得花时间去分析。我们做法的是在关键问题上做一些插装,把每一类错误和每一个具体的子错误都能定义出来,这样一看错误码就知道播放错误是由什么原因导致的。还可以把每次播放视频的链路所有关键流水上报到统计系统里来,每一次播放都是一组流水,每一条流水里面就包含了例如***缓冲发生的Seek,或下载的链接是多少,下载的时间是多少,有了这些流水之后,用户反馈播放失败,我首先可以用流水看发生了什么错误?错误在哪一步?每一步信息是什么?几秒钟就可以定位到问题。

有了这个数据上报之后,还可以做一些报表。比如说可以做错误码的报表,有了报表之后就可以跟进哪个错误是在TOP的,负责人是谁,原因是什么,都可以看到。

我们也有自己实时的曲线,可以看到各项数据的情况。在告警方面,基于成功率和失败率的统计,进行实时告警。一出现错误码,微信立即可以收到提醒,提醒说是什么原因导致这次告警,全自动。

成本优化

上线一个月之后,一个坏消息一个好消息。好消息是播放量涨了4倍,坏消息是带宽涨了6倍。带宽优化是每个做视频的人必须要面临的问题,我们也分析这个过程中的原因,发现因为改为边下边播之后用户观看视频的意愿比较强,用户有挑选心理,不是每个视频都去看,看了一下之后不喜欢就划走了,之前下载的那部分其实是浪费的。

如果之前不做限速的话,一点开视频就疯狂的下数据,带宽有多大就下多少的数据,这样浪费很严重。

 

我们采取的***个策略是进行流量控制。在高峰期播放到第10秒时,预下载N秒数据,下载到N秒就停下来。然后,可以做多级限速。一开始不限速,下载到合适时机做1倍码率限速。高峰期时预加载的数据会少一些,防止高峰期时带宽占用明显,这是初级的策略。最终我们也有码率切换的策略。这对用户的观看体验影响比较大,这也是之前必备的一个策略。

上线这个策略之后,对带宽的优化还是比较明显的。在高峰期时从18:00到凌晨1点带宽下降25.4%,这个是我们不断灰度最终确定的值。这个值会影响播放缓冲,因为数据少的话必定会卡顿,在卡顿之间和流量之间取了一个***值,最终是25.4%。

但这样肯定是不够的,因为流量涨的还是很明显的,我们想到H.265,压缩率相对于H.264提升了30%-50%,但它的复杂度也是呈指数级上升。复杂度导致它的编解码耗时更长,占用资源也更长。如果把H.265用在客户端上的话,可能要评估一些点,比如说在编码上面,现在手机上没有做H.265硬件支持的,相对于H.264的耗时3-7倍,之前耗时可能是10分钟,而现在可能需要到70分钟左右。解码的硬件支持H.265的也很少,耗时差不多是一样的。解码是可行的,你可以采用软解的方式,这个带来的问题是CPU占用非常高,可能之前H.264占20%的CPU,H.265占70%、80%左右,带来的问题是发热和耗电。

结论,解码是可行的,但是编码不用考虑,在移动客户端不可行的情况下,那编码就要放在后台来做了。

 

为了解决如何在我们手机上能够解码的问题,对手机的解码能力做一次评估。我在合适的时机做一次大规模的浮点数运算,将数据上传到后台服务器进行云适配。如果当前的指数满足H.265条件的话,可以给你下载H.265视频给你播放。从而保证软件解码柔性可用,针对视频源规格按机型适配降级,保证用户视频播放体验。

经过我们的统计,外网上有94%的手机还是支持H.265解码的。支持1080P手机的解码占46%。


 

编码只能在后台做,如果在视频后台进行全面编码的话,是不现实的。因为编码复杂度呈指数级上升,拿后台服务器进行编码也是不可行的。我们的做法是只用热点视频进行后台转码,不是所有视频都去编码,对观看量在TOP N的视频进行编码,只需要编码少量的视频就可以带来流量优化效果,因为TOP N就占了全网80-90%的流量。

因为热点视频的热点转化很快,可能前几分钟是热点,后几分钟就不是热点,因为社交网络的传播非常快。我们给后台的要求是转码速度一定要快,在之前没有优化时,转一个10分钟的视频要半个小时左右。后来我们做了分布式处理之后,转10分钟的视频只用两三分钟。一些短视频最长5分钟左右,只要监测到这个视频很热的话,1分钟之内就能转出来,就是H.265了。

 

同样,在H.265编码器上做了一些优化,比如说编码速度和码率的都会有提升。

上线H.265优化之后,我们的带宽进一步下降,节省了31%左右。

秒开优化

带宽问题解决之后,面临的下一个问题是体验优化。用户最想要的是视频能立马播出来。我们定了一个秒开技术指标,只要这个视频从到我的视野范围,到视频播出来之间的耗时在一秒以内。这也是对标Facebook的体验,Facebook一打开动态,视频是能立即播出来的,不需要等待就能播,这个体验其实很顺畅。核心的流程主要是三个步骤:1、客户端的耗时;2、下载数据;3、等待播放。

这里主要有两个大的耗时点,***下载视频数据耗时;第二个是客户端的耗时,下载视频数据耗时的话,主要是下载数据量和下载的速度。

 

这里有一个很直接的问题,播放器需要下载多少数据才能播放?我们可以看一下MP4,MP4其实是一个比较灵活的容器格式,每个东西都是用Box表达的,每个Box又可以嵌入到另外一个Box。MP4主要由MOOV和Mdata组成,MOOV是囊括了所有的视频关键信息,肯定是先把MOOV下载完之后才能找视频数据才能播起来。不巧的是,在我们外网会发现有5%左右用户上传的视频,它的MOOV是在尾部的。后来也发现,有很多安卓手机比如说山寨机,一些摄像头处理的厂商可能比较偷懒,因为他们只有在你采集完信息之后才能知道他所有的信息,他可能把所有的信息放在尾部。对于MP4来说,一开始把头部下载了,下载头部时可能找不到这个MOOV,就猜测这个MOOV在尾部,我可能就有一次请求去探测这个头部到底在哪?这个探测的话基本做法是去尾部探测。如果MOOV在其他地方的话,这次播放肯定是失败的。现在主流的系统都是去尾部进行一次探测。

比如安卓某些手机是无法自定义Range,那就需要下载完整个文件才能播放。我们的处理方式,用户在后台做一次转码修复,客户端采集后做一次转码修复。

再看一下Mdata,这是视频的原数据。目前大部分是H.264编码,H.264通过真预测的方式来进行视频编码,这里有一个GOP概念,也是在直播里面经常谈的。一般的视频需要下载歌完整的GOP数据才可以播,可以看到在这个里面需要下载多少数据才能播呢?每个播放器的行为也不一样。大家可以看到iOS要下载一个完整的GOP才可以播。像FFmpegBasedPlayer的话我可能只需要关键帧就可以播出来。安卓是比较尴尬的一个系统,在6.0级以下,可能需要5秒视频数据才可以播起来。如果说是需要下载5秒数据才可以播起来的话,那肯定是非常慢的。我们这里的一个策略会采用FFmpegBasedPlayer自己来做解码,这里要关注功能性和耗电的问题。

解决了Mdata之后,你会发现如果我的数据在头部,拿关键信息进行播放的话,其实我播放的数据量非常小的。

 

对于下载优化的话,会有一个防盗链的请求,通过HTTP拿到真实的才可以下载数据。在手机上执行HTTP请求是非常耗时的,这里我们走私有长连接通道做这个事情。

关于优化下载链路,这里也是谈的比较多的,一般也是直接输出IP地址,利用IP地址做跑马的策略,兼顾性能的效率,这个是用的比较多的方式。

进一步思考,按照普遍600K码率的话,我们统计到现在APP上面下载的平均速度是400K左右,这样计算的话,可能在安卓上面播放一个视频的话,需要将近0.9秒左右才可以下载到你需要的数据。如果码率再进一步提升的话,可能会更大,这其实我们也做了一些场景分析,会发现我们是社交网站,它有好友动态,视频在好友动态里播放,或者是在视频浮层里播放,我们的选择是预加载的策略,这也是常见的策略。我们会在当前看的这条动态时会预加载后面视频的关键信息,比如说会加载头部信息和需要播放的数据,来进行预加载。比如说在播放当前视频时,我的视频在加载一定数据之后会加载下一秒预加载数据,这些都可以做到的。

预加载有一个问题,我们之前踩了一个坑,可能预加载视频时还是要优先图片的。视频当然重要,但是社交网络上的图片也更重要,可能在预加载视频时会考虑到图片的一些任务,还有视频封面之类。

优化效果也是比较明显,经过刚才几个策略,一个是我们对头和播放器的处理,我们对防盗链的处理,还有对下载链路的处理和预加载,这样我们的耗时大幅度减少了,之前是1.8秒降到0.6秒左右。客户端的性能也是让人容易忽视的问题,发现有些用户虽然有视频的缓存,但是播起来还是很慢,这其实是客户端性能的影响。因为视频涉及到的BU和流程比较多,在这个过程中还要更关注到客户端的影响,要分析下客户端是哪些在抢占你的视频播放资源,我们之前犯过一些错误,md5会卡住一些流程,或者是HttpParser会阻止你的任务,会导致视频播放更慢。

在优化视频播放过程中,我们在4月份也做直播。直播这里面插入个事情,我们要播放直播的视频流,是HLS的视频,在好友动态里面可以观看直播的内容。HLS在安卓上面体验非常差,因为安卓3.0之后对HLS基本没有做的优化工作,这里每次安卓上播放HLS需要等待6-9秒。分析发现它的处理也不是很得当,因为安卓系统请求链路较长,串行下载,需要下载3-4片TS才能启动播放,下载3个分片的话,耗时就会很久。之前提到我们这里有代理,有了代理之后做事情方便很多了,通过里获取M3U8,解析M3U8里面有哪些文件,可以做并行下载,只让他下载一次M3U8,这样下载速度大幅度提升。回到刚才架构上,有了下载代理层的话,你可以做HLS的加速和管理,可以加入HLS的视频源。

 

HLS缓冲耗时也是很明显的,之前需要6秒左右,现在1.6秒左右就可以播起来。整体从之前的2秒左右现在优化到700m秒,80%用户都可以在1秒内播视频。

 

还有一个是用户比较关注的问题,观看视频时卡,观看一会卡了一下,loading数据,loading完以后又卡,这个体验非常差,我们希望所有的视频都不卡。其实这有两个播放场景,一个是正常场景,边下边看,数据在下载。对于正常场景下载时会做一些带宽调整,在低速时会做切换IP的处理,比如说当前连通IP的耗时比较久的话,会做一些处理,也会对网络进行速度限制。

 

针对Seek场景的话,如果用户拖动的话,文件缓存系统是连续存储系统的话,必然会造成拖到这里时,后面的缓存数据是没有办法下载到系统里面来的。

 

我们就对存储做了一次重构,支持文件空洞。会按照一兆的方式对文件进行碎片划分,好处是我可以分段存储,我可以允许逻辑空洞的,拖动的话也可以在后面存储,也不需要数据库,我可以知道这是从哪个位置到哪个位置的存储。这样淘汰缓存也高效一点,并可以制定更灵活的缓存策略。这里可以淘汰更低密度的文件,还可以做的事情是对文件加密。这里产生卡顿的用户里面,90%是因为进行拖动,拖动之后又没有缓存数据,所以这里有可能导致发生缓冲。统计效果也是比较明显的,上了分片缓存之后,之前的缓存概率是4.6%左右,***下降到0.48%,基本上看不到发生缓冲的场景。

成功率优化,也是我们比较关键的指标。成功率优化没有捷径,可能是Case by Case各个击破。之前我们进行编码,有几百个错误码,错误码原因进行上报,每次进行循环,一个个错误码进行解决。下载常见的错误码,DNS劫持是比较多的,一些网络运营商会劫持你的请求。

 

这个在国内是比较常见的劫持,有的小运营商按月会劫持你的视频内容,可能直接污染你的DNS让你查找不到CDN,这是比较多的,还有一些网络不稳定的影响导致。更隐藏的会直接污染你的视频内容,让你视频内容是错误的。播放比较多的可能是一些编码的原因,刚才提到一些手机采集出来的视频在低端手机上播不出来,我们会对这些视频进行修复。

逻辑上的问题,因为播放器有状态的,可能开发人员比较多,每个人过来加一个逻辑的话,会导致播放状态出现问题。

我们做的播放器错误解决方法:

HOOK播放器接口与回调,实现播放器状态机,监控插放器API的调用是否合法,不合法直接告警或Crash。帮助开发快速定位问题,同时减轻测试同事的负担,封装成UI组件,使其它开发不必理解播放器。

 

最终优化的成果是这样的,下载成功率优化前是97.1%,优化后是99.9%。播放成功率优化前是97.0%,优化后是99.9%。***缓冲耗时优化前是1.95s,优化后是0.7s。二次缓冲概率优化前是4.63%,优化后是0.48%。数据还是很可观的。

我的演讲基本是这些,欢迎大家关注我们团队的公众账号,也会分享一些技术文章。

谢谢大家!

提问:刚才您提到已经开始尝试用265了,能透露一下265你们播放的在整体中占多大的比例?

王辉:现在热视频里面80%都是H.265。10亿里面会有70%、80%左右。

提问:推进的还是挺靠前的。刚才你提到要判断手机的H.265能力,用大规模的浮点运算,首先我先了解一下你们用的什么浮点运算的Mark?其次,为什么要用浮点运算?其实视频编解码里面几乎全部都是整数运算。

王辉:浮点运算能代表你这个手机性能,其实我们是评估性能的,不是评估H.265转码,如果性能达到的话,解码也是可以达到的。

提问:如果想针对解码做评估的话,我建议整数运算。你可以确认一下,首先视频编解码的标准规定是没有浮点运算,不同的编解码时限可能会插入少量的浮点运算,大部分是整数运算。

王辉:我们初步做的时候是判断手机有没有运算能力来做的浮点运算判断。

主持人:感谢各位嘉宾的提问,感谢王辉老师给大家带来的讲解。

责任编辑:Jane 来源: 51CTO
相关推荐

2021-12-31 07:27:12

阿里UC音视频

2013-01-08 11:00:06

YouTubeAJAXCSS

2022-06-21 14:41:38

播放器适配西瓜视频

2017-03-29 14:38:05

高可用视频调度秒拍

2015-11-04 12:23:56

ICT服务华为

2017-10-25 20:42:13

频播放量秒拍链路优化

2022-06-20 05:59:35

5G技术音视频技术安卓系统

2021-11-24 15:16:02

Quick阿里云操作系统

2015-09-09 11:08:48

qq空间可拉伸头部

2009-05-22 10:11:19

2015-08-07 15:32:19

欢迎界面仿微信仿qq空间

2020-08-19 12:29:35

留存分析数据工具

2018-12-18 13:41:40

2023-03-09 11:41:16

2011-08-10 15:58:58

iPhone视频

2022-08-16 17:37:06

视频播放器鸿蒙

2014-10-20 09:55:02

2014-07-16 16:14:13

2015-10-27 11:14:03

qq腾讯95后

2023-03-06 09:09:56

视频Edge浏览器
点赞
收藏

51CTO技术栈公众号