微博客户端播放器的演进之路

640?wx_fmt=jpeg


近年来新浪微博围绕着快速上线、快速启播、成本节约、稳定性等问题对客户端播放器进行了一系列优化,以求为用户提供更好的服务体验。本文来自新浪微博高级多媒体工程师刘文在LiveVideoStackCon 2018音视频技术大会中的演讲,并由LiveVideoStack整理而成。


文 / 刘文

整理 / LiveVideoStack


大家好,我是来自新浪微博的刘文。今天给大家分享的题目是微博客户端短视频播放器的演进之路。在这里主要给大家介绍一下为了更好的服务业务,我们是如何对播放器的体验进行改善、优化的。


主要内容包括以下三部分:


1、微博短视频业务介绍;

2、基于漏斗模型的体验优化;

3、画质提升优化;


一、 微博短视频业务介绍


如下图所示,短视频在这几年的大爆发我们都是有目共睹的。从2015年底,就Facebook和Snapchat来说,它们的日均播放量都已经达到了65亿以上。从那时开始,国内也有很多公司开始跟进,开始布局自己的短视频业务,微博也是从那个时候开始加入了短视频业务。


640?wx_fmt=png640?wx_fmt=png

 

如上图所示,从2016年至今,中国短视频的市场规模增长速度是非常之快的。那么经过这几年的发展,微博短视频业务的形态是什么样的呢?

 

640?wx_fmt=png


从目前来说,微博的短视频业务主要包括两种形式:微博视频和微博故事。微博视频存在于信息流和推荐流,当用户滑动到视频内容时,触发自动播放,主动为用户播放视频的内容。微博故事主要是竖版视频,有独立入口,主要用来分享用户最近24小时内发生的故事。


那么,针对上述两个业务场景,我们的播放器技术做了哪些事情呢?


二、 基于漏斗模型的体验优化


1、业务指标


为了服务好业务,我们首先要思考业务的核心指标是什么?

 

640?wx_fmt=png


业务的核心指标是有效播放,有效播放指的是大于3秒的视频播放,这是播放器优化中的一个重要指标。


2、漏斗转化模型


业务指标有效播放存在这样一个漏斗转化模型,包括从曝光到播放再到有效播放。

 

640?wx_fmt=png


有效播放首先来自于所有的播放,而播放又来自于对视频内容的曝光,那么在有效播放的指标转换过程中,从播放器的角度看我们可以在哪些环节来开展一些优化进而实现指标的提升呢? 我们一层层来看。


3、播放转化率提升

 

640?wx_fmt=png


首先,我们来考虑漏斗模型的第一层,从曝光到播放阶段怎么提升播放转化率。我们上线了自动播放业务。自动播放指的是在信息流里碰到视频就自动播放,也就是只要曝光就触发播放。从理论上来说,如果我们上线了这个功能,那么曝光到播放的转化率就是百分之百。要上线这个功能,我们必须先要解决一些基本的体验问题。

 

640?wx_fmt=png


自动播放在业务上面临哪些挑战呢?


第一,自动播放涉及到多个视频间的频繁切换,这样一来,它对视频基本体验的要求是UI不卡顿。第二,对于已经播放过的视频,当再次播放时,我们希望它能延续上一次播放结束的地方继续播放(续播),对于续播我们要求它的播放是准确的,这样才能够保证良好的体验。第三,在信息流、视频流滑动的过程中,对于单个视频自动播放有可能会引发重复播放,对于重复播放我们要求不会造成用户数据的浪费。在实际上线这个功能时,上述问题我们都需要一一解决。

 

640?wx_fmt=png


为了解决这些问题,我们的解决办法是什么呢?


第一,为了解决UI卡顿的问题,我们将所有播放器API异步化。第二,为了保证续播的准确性,我们支持了视频的精确seek。其中为了提升精确seek效率,参考了iOS播放器的接口设计,支持seek前后容差的设定,并且对非参考B帧不进行解码,尽可能的减少精确seek中的解码消耗。第三,为了不浪费用户的流量,对于重复播放,我们设计了具有缓存能力的下载模块。

 

640?wx_fmt=png


下载模块的工作原理是代理播放器的IO。此外,我们需要考虑点播场景下的用户行为特点,用户的seek拖拽会造成缓存文件出现空洞,下载模块必须支持分片缓存管理, 如下图所示。

 

640?wx_fmt=png


最终的下载模块建立在分片缓存文件管理的基础上,包括接口层、IO管理、缓存文件系统。通过播放器代理接口接入到播放器,解决了自动播放过程重复下载浪费的问题。

 

640?wx_fmt=png


2015年,我们实现这个功能的灰度上线,我们对实验效果进行了对比统计,播放量增加了四倍,但带宽成本也增加了两倍。

 

640?wx_fmt=png


由于带宽成本太高,我们无法实现全量上线这个功能。从播放器的角度来说,我们应该尽可能的避免流量的浪费。在自动播放场景下,流量浪费的形成原因和发生的规模是什么样子的呢?


由于下载没有限速。在自动播放的过程中,数据加载过快,已经的播放进度远远小于已经下载的进度,如果用户没看完视频很早退出,就会存在很大的下载浪费。如下图所示。


640?wx_fmt=png 

在用户观看的过程中,他们会筛选自己喜欢的内容播放。通过日志统计发现,有60%的视频播放时长是小于3秒的,也就存在大量的播放早退现象。所以,在自动播放场景下,视频播放存在大量的下载浪费。

 

640?wx_fmt=png


为了解决这个问题,我们必须进行一定的下载限速。下载限速的规则如下图所示:

 

640?wx_fmt=png


当播放器播放时长小于3秒时,只加载5s的数据;当播放时长小于视频总时长的15%时,加载15s的数据;当播放时长大于视频总时长的15%时,不限制下载。 


640?wx_fmt=png


在2016年上半年,我们通过解决自动播放功能带来的基本体验问题以及成本过高的问题,实现了自动播放功能的全量上线,促成了漏斗模型中从曝光到播放的转化。


4、有效播放转化率提升


再来看漏洞模型的第二层,我们需要努力实现播放到有效播放的转化。

 

640?wx_fmt=png


首先,我们要回答播放最终都可能会转变成什么?然后看哪些部分是可以减少,并向有效播放转化的。播放最终会转变成三种状态:异常、取消播放和成功播放。

 

640?wx_fmt=png


异常可以细分为播放错误和崩溃两种状态,一般是由网络出现问题或者播放器出现bug导致的,这是比较严重的体验中断行为是我们必须要处理的。取消播放指的是用户等了一段时间后,视频没播出来,用户取消了观看。可以细分为等待播放时间小于1秒和等待时间大于1秒两种状态。等待时间小于1s的取消,我们认为是快速滑动中自动播放产生的无效播放,这部分没办法去缩减。等待大于1s的,是用户想看但是由于加载慢最后选择了放弃。这部分我可以通过秒开优化去转化。成功播放包括小于3s的播放和大于3s的播放。小于3s的播放,我们认为是对播放的内容不敢兴趣。这部分播放器优化切入的点很有限 。


通过对播放转化的分析,我们确认了连续性和加载速度两个体验维度的优化。其中观看连续性指的是错误率与crash率的处理。尽量促成播放在1S内成功加载。


一)加载速度优化


在加载速度上我们使用PSR1(Play Success Rate 1 second)也就是1秒内成功开播的百分比作为我们的指标。为了找到加载过程的耗时点,我们进行日志打点分析,并把加载时间分为IO时间和处理时间两个部分。经过上线分析,发现首帧加载时间为2s,大部分时间是IO消耗。

 

640?wx_fmt=png


IO主要包括网络IO和本地IO,而网络IO与本地IO对比是很慢的。因此,减少启播过程中网络IO,是提高首帧时间的有效方法。考虑到用户观看视频的内容筛选行为,很多播放是小于3s的,我们对即将播放的视频做了3s预先加载

 

640?wx_fmt=png


为了减少预加载对播放的影响,我们需要将预加载和播放中的下载统一在一起进行管理,为此对播放器下载模块进行了重构。


640?wx_fmt=png


对于启播过程中的处理时间,虽然占比小,但是还是有优化的空间。处理过程主要包括解析、解码和控制三个步骤。为了优化处理的速度,对于解析过程,我们采取忽略帧率估计、避免重复解码的策略;对于解码过程,我们采取了解码器异步初始化;对于控制过程,我们采用首帧解码后即显示和buffer延迟的策略。

 

640?wx_fmt=png


通过对IO时间和处理时间的优化,加载时间优化到了450ms,PSR1值从80%提升到了93%。

 

640?wx_fmt=png640?wx_fmt=png


二)连续性优化


连续性优化主要包括两个方面:错误率和Crash率。这两类问题没有什么统一的处理标准和方法,只能一个个解决。为了提升效率,必须依靠一个强大的日志系统来进行分析,如下图所示。

 

640?wx_fmt=png


第一,降低错误率;

 

640?wx_fmt=png


对于错误而言,错误信息的梳理很重要,包含错误码和播放trace。其中,错误码比较简洁、利于统计。播放trace记录了单条播放中,核心步骤的执行情况,对于单个错误的分析非常有效。通过一个个的解决,我们的错误率从开始的平均0.5%降低到了0.2%以下。

 

640?wx_fmt=png


第二,降低Crash量;

 

640?wx_fmt=png


在Crash上,我们花了很多的精力,难点在于由内存问题导致的诡异堆栈。为了快速定位问题所在,一方面我们主要是通过内存分析工具来帮助发现内存的一些隐患;另一方面,对于一些不容易出现的问题,我们通过在压力环境下模拟堆栈发生的逻辑来提高它的复线率。最终,我们的Crash率得到了控制,每千万次播放的Crash量从450多次降到了4次。

 

640?wx_fmt=png


5、小结


总结一下有效播放转化率提升的过程,我们主要是围绕漏斗转化模型来开展优化工作,包括从曝光到播放和从播放到有效播放两个阶段。从曝光到播放过程主要优化的是基本体验和成本过高的问题,从播放到有效播放过程主要优化的是观看连续性和加载速度。


640?wx_fmt=png


回顾我们之前的思路,为了更好的服务业务,我们主要从用户体验的连续性和加载速度两个维度开展优化。这两年随着带宽条件的改善,客户对画面质量的要求也越来越高,视频画面质量提升将是趋势。 画面质量体验的好坏对业务的影响也会越来越大,所以画面质量优化是我们目前一个重点方向。下面给大家介绍下我们质量提升方案的选择与初步尝试。


三、 画质提升优化

 

640?wx_fmt=png


我们都知道提升画质会导致码率上升,要改善画质我们是不是把所有视频内容的码率都提升就可以了呢?答案肯定是不行的。如果我们集中提高码率会导致卡顿上升,这主要是因为码率和网速之间的不匹配造成的。


从所有用户的角度看,假设用户的带宽分布如下图所示,一种清晰度不可能适应所有用户的带宽 。

 

640?wx_fmt=png


从单个用户的角度看,用户观看视频的过程中,网络是波动的,提供一种清晰度是没法满足单个用户的单次播放的。

 

640?wx_fmt=png


因此,如果我们有多种分辨率,而且我们可以根据用户的带宽给它匹配当时他能播放的最高码率,那么这样的话,我们就可以既保证基本的流畅性体验,又可以尽可能的提升画面质量。

 

640?wx_fmt=png


所以,我们的画质提升方案是基于多码率的自适应码率方案,这就需要播放器有自适应码率切换的能力。在这个过程中,我们需要解决两个问题:支持多码率协议播放和码率自适应切换能力。


一)支持多码率协议


现在工业界的多码率协议主要有苹果的HLS、微软的MSS和标准化组织定义的DASH等,其中DASH相对来说更加通用,是国外很多大厂目前也正在使用这个协议, 所以我们采用DASH作为我们支持的对象。

 

640?wx_fmt=png


在支持这个协议播放的过程中,我们对加载速度进行了优化。因为DASH的起播还是相对比较复杂的,音视频是分离的,单个fmp4请求包含了多个segment请求。一方面,我们把多个segment请求进行合并;另外一方面,我们对音视频的fmp4请求进行了并发处理。通过这样的优化,目前为止Dash在线上的播放PSR1和我们普通视频的PSR1的值是相近的。

 

640?wx_fmt=png


二)码率自适应切换能力


对于自适应码率切换,现在已经上线了手动切换,而自动切换还处于实验室阶段。这里主要说一下手动切换。

 

640?wx_fmt=png


手动切换主要解决切换这个动作平滑性的问题。思想就是在切换实时性和平滑性间做一个折中,损失一定的实时性来保证切换动作的平滑性。 具体而言,其实就是利用正在播放的清晰度的缓存时间,准备下一个清晰度的播放。


四、 总结

 

640?wx_fmt=png


总的来说,播放器服务业务的过程,就是对播放器体验优化的过程。体验优化的方向大家的做法都是类似的,包括加载速度、连续性和画面质量。不同的就是我们如何围绕着业务的需求去思考我们什么时间做什么优化。



640?wx_fmt=jpeg


点击【阅读原文】或扫描图中二维码了解更多LiveVideoStackCon 2019 上海 音视频技术大会 讲师信息。

猜你喜欢

转载自blog.csdn.net/vn9PLgZvnPs1522s82g/article/details/87834850