微博客户端播放器的演进之路
近年来新浪微博围绕着快速上线、快速启播、成本节约、稳定性等问题对客户端播放器进行了一系列优化,以求为用户提供更好的服务体验。本文来自新浪微博高级多媒体工程师刘文在LiveVideoStackCon 2018音视频技术大会中的演讲,并由LiveVideoStack整理而成。
文 / 刘文
整理 / LiveVideoStack
大家好,我是来自新浪微博的刘文。今天给大家分享的题目是微博客户端短视频播放器的演进之路。在这里主要给大家介绍一下为了更好的服务业务,我们是如何对播放器的体验进行改善、优化的。
主要内容包括以下三部分:
1、微博短视频业务介绍;
2、基于漏斗模型的体验优化;
3、画质提升优化;
一、 微博短视频业务介绍
如下图所示,短视频在这几年的大爆发我们都是有目共睹的。从2015年底,就Facebook和Snapchat来说,它们的日均播放量都已经达到了65亿以上。从那时开始,国内也有很多公司开始跟进,开始布局自己的短视频业务,微博也是从那个时候开始加入了短视频业务。
如上图所示,从2016年至今,中国短视频的市场规模增长速度是非常之快的。那么经过这几年的发展,微博短视频业务的形态是什么样的呢?
从目前来说,微博的短视频业务主要包括两种形式:微博视频和微博故事。微博视频存在于信息流和推荐流,当用户滑动到视频内容时,触发自动播放,主动为用户播放视频的内容。微博故事主要是竖版视频,有独立入口,主要用来分享用户最近24小时内发生的故事。
那么,针对上述两个业务场景,我们的播放器技术做了哪些事情呢?
二、 基于漏斗模型的体验优化
1、业务指标
为了服务好业务,我们首先要思考业务的核心指标是什么?
业务的核心指标是有效播放,有效播放指的是大于3秒的视频播放,这是播放器优化中的一个重要指标。
2、漏斗转化模型
业务指标有效播放存在这样一个漏斗转化模型,包括从曝光到播放再到有效播放。
有效播放首先来自于所有的播放,而播放又来自于对视频内容的曝光,那么在有效播放的指标转换过程中,从播放器的角度看我们可以在哪些环节来开展一些优化进而实现指标的提升呢? 我们一层层来看。
3、播放转化率提升
首先,我们来考虑漏斗模型的第一层,从曝光到播放阶段怎么提升播放转化率。我们上线了自动播放业务。自动播放指的是在信息流里碰到视频就自动播放,也就是只要曝光就触发播放。从理论上来说,如果我们上线了这个功能,那么曝光到播放的转化率就是百分之百。要上线这个功能,我们必须先要解决一些基本的体验问题。
自动播放在业务上面临哪些挑战呢?
第一,自动播放涉及到多个视频间的频繁切换,这样一来,它对视频基本体验的要求是UI不卡顿。第二,对于已经播放过的视频,当再次播放时,我们希望它能延续上一次播放结束的地方继续播放(续播),对于续播我们要求它的播放是准确的,这样才能够保证良好的体验。第三,在信息流、视频流滑动的过程中,对于单个视频自动播放有可能会引发重复播放,对于重复播放我们要求不会造成用户数据的浪费。在实际上线这个功能时,上述问题我们都需要一一解决。
为了解决这些问题,我们的解决办法是什么呢?
第一,为了解决UI卡顿的问题,我们将所有播放器API异步化。第二,为了保证续播的准确性,我们支持了视频的精确seek。其中为了提升精确seek效率,参考了iOS播放器的接口设计,支持seek前后容差的设定,并且对非参考B帧不进行解码,尽可能的减少精确seek中的解码消耗。第三,为了不浪费用户的流量,对于重复播放,我们设计了具有缓存能力的下载模块。
下载模块的工作原理是代理播放器的IO。此外,我们需要考虑点播场景下的用户行为特点,用户的seek拖拽会造成缓存文件出现空洞,下载模块必须支持分片缓存管理, 如下图所示。
最终的下载模块建立在分片缓存文件管理的基础上,包括接口层、IO管理、缓存文件系统。通过播放器代理接口接入到播放器,解决了自动播放过程重复下载浪费的问题。
2015年,我们实现这个功能的灰度上线,我们对实验效果进行了对比统计,播放量增加了四倍,但带宽成本也增加了两倍。
由于带宽成本太高,我们无法实现全量上线这个功能。从播放器的角度来说,我们应该尽可能的避免流量的浪费。在自动播放场景下,流量浪费的形成原因和发生的规模是什么样子的呢?
由于下载没有限速。在自动播放的过程中,数据加载过快,已经的播放进度远远小于已经下载的进度,如果用户没看完视频很早退出,就会存在很大的下载浪费。如下图所示。
在用户观看的过程中,他们会筛选自己喜欢的内容播放。通过日志统计发现,有60%的视频播放时长是小于3秒的,也就存在大量的播放早退现象。所以,在自动播放场景下,视频播放存在大量的下载浪费。
为了解决这个问题,我们必须进行一定的下载限速。下载限速的规则如下图所示:
当播放器播放时长小于3秒时,只加载5s的数据;当播放时长小于视频总时长的15%时,加载15s的数据;当播放时长大于视频总时长的15%时,不限制下载。
在2016年上半年,我们通过解决自动播放功能带来的基本体验问题以及成本过高的问题,实现了自动播放功能的全量上线,促成了漏斗模型中从曝光到播放的转化。
4、有效播放转化率提升
再来看漏洞模型的第二层,我们需要努力实现播放到有效播放的转化。
首先,我们要回答播放最终都可能会转变成什么?然后看哪些部分是可以减少,并向有效播放转化的。播放最终会转变成三种状态:异常、取消播放和成功播放。
异常可以细分为播放错误和崩溃两种状态,一般是由网络出现问题或者播放器出现bug导致的,这是比较严重的体验中断行为是我们必须要处理的。取消播放指的是用户等了一段时间后,视频没播出来,用户取消了观看。可以细分为等待播放时间小于1秒和等待时间大于1秒两种状态。等待时间小于1s的取消,我们认为是快速滑动中自动播放产生的无效播放,这部分没办法去缩减。等待大于1s的,是用户想看但是由于加载慢最后选择了放弃。这部分我可以通过秒开优化去转化。成功播放包括小于3s的播放和大于3s的播放。小于3s的播放,我们认为是对播放的内容不敢兴趣。这部分播放器优化切入的点很有限 。
通过对播放转化的分析,我们确认了连续性和加载速度两个体验维度的优化。其中观看连续性指的是错误率与crash率的处理。尽量促成播放在1S内成功加载。
一)加载速度优化
在加载速度上我们使用PSR1(Play Success Rate 1 second)也就是1秒内成功开播的百分比作为我们的指标。为了找到加载过程的耗时点,我们进行日志打点分析,并把加载时间分为IO时间和处理时间两个部分。经过上线分析,发现首帧加载时间为2s,大部分时间是IO消耗。
IO主要包括网络IO和本地IO,而网络IO与本地IO对比是很慢的。因此,减少启播过程中网络IO,是提高首帧时间的有效方法。考虑到用户观看视频的内容筛选行为,很多播放是小于3s的,我们对即将播放的视频做了3s预先加载
为了减少预加载对播放的影响,我们需要将预加载和播放中的下载统一在一起进行管理,为此对播放器下载模块进行了重构。
对于启播过程中的处理时间,虽然占比小,但是还是有优化的空间。处理过程主要包括解析、解码和控制三个步骤。为了优化处理的速度,对于解析过程,我们采取忽略帧率估计、避免重复解码的策略;对于解码过程,我们采取了解码器异步初始化;对于控制过程,我们采用首帧解码后即显示和buffer延迟的策略。
通过对IO时间和处理时间的优化,加载时间优化到了450ms,PSR1值从80%提升到了93%。
二)连续性优化
连续性优化主要包括两个方面:错误率和Crash率。这两类问题没有什么统一的处理标准和方法,只能一个个解决。为了提升效率,必须依靠一个强大的日志系统来进行分析,如下图所示。
第一,降低错误率;
对于错误而言,错误信息的梳理很重要,包含错误码和播放trace。其中,错误码比较简洁、利于统计。播放trace记录了单条播放中,核心步骤的执行情况,对于单个错误的分析非常有效。通过一个个的解决,我们的错误率从开始的平均0.5%降低到了0.2%以下。
第二,降低Crash量;
在Crash上,我们花了很多的精力,难点在于由内存问题导致的诡异堆栈。为了快速定位问题所在,一方面我们主要是通过内存分析工具来帮助发现内存的一些隐患;另一方面,对于一些不容易出现的问题,我们通过在压力环境下模拟堆栈发生的逻辑来提高它的复线率。最终,我们的Crash率得到了控制,每千万次播放的Crash量从450多次降到了4次。
5、小结
总结一下有效播放转化率提升的过程,我们主要是围绕漏斗转化模型来开展优化工作,包括从曝光到播放和从播放到有效播放两个阶段。从曝光到播放过程主要优化的是基本体验和成本过高的问题,从播放到有效播放过程主要优化的是观看连续性和加载速度。
回顾我们之前的思路,为了更好的服务业务,我们主要从用户体验的连续性和加载速度两个维度开展优化。这两年随着带宽条件的改善,客户对画面质量的要求也越来越高,视频画面质量提升将是趋势。 画面质量体验的好坏对业务的影响也会越来越大,所以画面质量优化是我们目前一个重点方向。下面给大家介绍下我们质量提升方案的选择与初步尝试。
三、 画质提升优化
我们都知道提升画质会导致码率上升,要改善画质我们是不是把所有视频内容的码率都提升就可以了呢?答案肯定是不行的。如果我们集中提高码率会导致卡顿上升,这主要是因为码率和网速之间的不匹配造成的。
从所有用户的角度看,假设用户的带宽分布如下图所示,一种清晰度不可能适应所有用户的带宽 。
从单个用户的角度看,用户观看视频的过程中,网络是波动的,提供一种清晰度是没法满足单个用户的单次播放的。
因此,如果我们有多种分辨率,而且我们可以根据用户的带宽给它匹配当时他能播放的最高码率,那么这样的话,我们就可以既保证基本的流畅性体验,又可以尽可能的提升画面质量。
所以,我们的画质提升方案是基于多码率的自适应码率方案,这就需要播放器有自适应码率切换的能力。在这个过程中,我们需要解决两个问题:支持多码率协议播放和码率自适应切换能力。
一)支持多码率协议
现在工业界的多码率协议主要有苹果的HLS、微软的MSS和标准化组织定义的DASH等,其中DASH相对来说更加通用,是国外很多大厂目前也正在使用这个协议, 所以我们采用DASH作为我们支持的对象。
在支持这个协议播放的过程中,我们对加载速度进行了优化。因为DASH的起播还是相对比较复杂的,音视频是分离的,单个fmp4请求包含了多个segment请求。一方面,我们把多个segment请求进行合并;另外一方面,我们对音视频的fmp4请求进行了并发处理。通过这样的优化,目前为止Dash在线上的播放PSR1和我们普通视频的PSR1的值是相近的。
二)码率自适应切换能力
对于自适应码率切换,现在已经上线了手动切换,而自动切换还处于实验室阶段。这里主要说一下手动切换。
手动切换主要解决切换这个动作平滑性的问题。思想就是在切换实时性和平滑性间做一个折中,损失一定的实时性来保证切换动作的平滑性。 具体而言,其实就是利用正在播放的清晰度的缓存时间,准备下一个清晰度的播放。
四、 总结
总的来说,播放器服务业务的过程,就是对播放器体验优化的过程。体验优化的方向大家的做法都是类似的,包括加载速度、连续性和画面质量。不同的就是我们如何围绕着业务的需求去思考我们什么时间做什么优化。
点击【阅读原文】或扫描图中二维码了解更多LiveVideoStackCon 2019 上海 音视频技术大会 讲师信息。
微博客户端播放器的演进之路相关推荐
- 播放器技术演进与探索,Web开播系统的技术演进,大屏终端音视频播放,音视频效果插件开放平台建设...
播放器技术演进与探索 Topic <QPlayer2播放器-用扩展性支撑起未来需求> 陈军奇 七牛云 资深开发工程师.播放器负责人 随着这些年音视频的应用场景越来越丰富,用户对于播放器能 ...
- 流媒体服务器 客户端播放器方案推荐
https://github.com/jacke121/stream-rtsp 使用说明: 貌似把rtsp转为webrtc,但是没有把图片编码为webrtc: Example config.json ...
- 【Android工具】更新手机视频流媒体客户端播放器OPlayer
微信关注 "DLGG创客DIY" 设为"星标",重磅干货,第一时间送达. 之前分享的"安卓魔力播放器moliplayer绿色无广告(2.8.10.83 ...
- linux dlna 客户端,UPNP/DLNA(客户端)播放器推荐?
问题描述 由于VLC稳定/VLC夜间构建/Totem与Coherence插件都没有正常工作我正在寻找一种替代方案来观看使用minidlna作为服务器从我的希捷dockstar流式传输的媒体. 唯一有效 ...
- SoundCloud的web播放库Maestro演进之路
Maestro是一款用于处理SoundCloud Web播放的库,它在soundcloud.com.SoundCloud移动网站.网页插件.Chromecast和Xbox应用中每天成功处理数千万次的播 ...
- android ijkplayer使用_Ijkplayer、ExoPlayer、VLC播放器综合比较
VLC Media Player VLC 是VideoLAN 计划所研发的工程,最早预1996年开始,是一个完全的跨平台播放器,适合Windows.Mac OS.Linux.Android.iOS等系 ...
- Web端H.265播放器研发解密
音视频编解码对于前端工程师是一个比较少涉足的领域,涉及到流媒体技术中的文本.图形.图像.音频和视频多种理论知识的学习,才能够应用到具体实践中,本团队在多媒体领域深耕两年多,才算是有一定产出,我们自研w ...
- Web端H.265播放器研发解密 1
音视频编解码对于前端工程师是一个比较少涉足的领域,涉及到流媒体技术中的文本.图形.图像.音频和视频多种理论知识的学习,才能够应用到具体实践中,本团队在多媒体领域深耕两年多,才算是有一定产出,我们自研w ...
- 视频【解码】原理(播放器原理),音视频同步等
1.视频编码格式:H264, VC-1, MPEG-2, MPEG4-ASP (Divx/Xvid), VP8, MJPEG 等. 2.音频编码格式:AAC, AC3, DTS(-HD), True ...
最新文章
- KVM(Keyboard、Video、Mouse)
- maven零基础从配置到运行helloworld(java maven helloworld)
- Dr. Evil Underscores(异或最大值最小)
- neo4jcypher基本语句
- 用 GDB 调试Linux下的C程序
- Spring : Spring的ApplicationContext接口
- es match 查询时间段_elasticsearch 笔记二 之基础查询
- Front End Developer Questions 前端开发人员问题(二)
- 代价函数的作用(2)--机器学习
- win10 笔记本 右下角出现 天气的解决办法
- 荣耀pro无线路由器配置成无线交换机
- 体脂手环、体脂秤等产品的体脂测量原理及技术方案分析
- 《爬虫》爬取谷歌网页“人脸”图片
- 爬虫技术(01)神箭手爬虫初学案例解读
- cs6制作拼图游戏 dreamweaver_Dreamweaver制作拼图步骤
- Android热更新,android组件化通信
- 微信公众号文章中的图片处理有哪些技巧?看这篇就够了。
- JAVA毕业设计华北地区阔叶林木叶部病虫害图像管理系统计算机源码+lw文档+系统+调试部署+数据库
- JVM 深入笔记(1)内存区域是如何划分的?
- 修改hosts文件(win10版)
热门文章
- C++17中那些值得关注的特性
- SpringBoot 中 @RequestBody的正确使用方法
- chrome浏览器最小字号解决方案
- CSS3 box-reflect 属性
- Cool!15个创意的 CSS3 文本效果【下篇】
- 《MFC dialog中加入OpenGL窗体》
- 有没有通过代码退出程序的方法--官方解答
- CodeForces - 1445E Team-Building(可撤销并查集)
- UVa10410 Tree Reconstruction(bfs+dfs确定二叉树)
- 【项目源码分享】基于C++实现的小型数据库(Windows/Linux环境)