播放器相关问题:
- 业务耦合
- 成功率低
- 不支持边下边播,缓冲时间长
- 成本优化
- 问题定位难
- 不限速
- 非高峰时段,预下载N秒
- 高峰时段,预下载M秒
- 高峰期动态码率
- 压缩率提升 30%
- 相比H264,编码复杂度提升4倍,更消耗系统资源
- 编码时间更长
通过软解可以支持,但是CPU会占用较高,而且发热和耗电。
对解码能力进行评估,来通过机型打分控制是否使用H265以及是用360p还是480p。
但是H265全部切换成本较高,牵扯到转码成本以及存储成本,所以可以只对热点的视频去进行编码,这样少量的视频就可以带来可观的效果。
会有一个防盗链的请求,通过 HTTP 拿到真实的播放 URL 才可以下载数据。
但是在手机上执行 HTTP 请求非常耗时,这里走私有长连接通道做这个事情。
有关CDN相关可参考CDN及PCDN
能立即起播,不会产生缓冲。秒开很简单,预加载数据就行。不够快就预解封装、解码,还不够快就再加上预渲染。但是秒开又是最难的。 播放器初始化->业务逻辑->DNS解析->CDN下载数据->解码->渲染播放
“在所有环节中,短视频列表播放的体验非常重要。例如抖音,你会发现起播非常快,循环播放也很流畅。这是怎么做到的呢?这就是通过列表预加载技术实现的。常规的预加载是通过多个播放器来实现的,播放当前视频的时候去预加载下一个视频,这个方案的缺点是实现逻辑非常复杂,同时也消耗更多性能。所以,阿里云独创了列表播放器,通过简单的接口调用就可以实现列表的预加载播放。它有几个特点,首先是能够做到防卡顿的缓存策略,通过对缓存的管理,可以灵活控制卡顿期间的预缓存策略,同时优化缓冲的淘汰策略。第二是对滑动的流畅性针对性优化,保证每个视频停止的耗时在16毫秒以内。第三是采用了基于内存的预加载缓存技术,循环播放和秒开直接从内存读取数据,无需额外的文件操作。第四非常关键,是提供简单的接口,可以非常快速的实现短视频播放功能
预加载能减少首次缓冲时间,但是预加载不能和当前播放的视频抢下载带宽,需要达到一个合适的阈值再开始下载。
优先保证封面图等信息完成后再根据云控的当前缓冲的时长等信息来控制是否要启动预加载
提升视频加载速度的常见手段就是预加载 ,即在用户播放之前,预先下载好一部分数据,这样在视频开播的时候就不需要等待网络请求。这里面有两个挑战,一个是预加载需要下载多少数据才算够呢?下载多了,浪费带宽;下载少了,不够拿来开播,也就无法满足快开的要求。拿 MP4来说,要解码出首帧,首先需要解析完 moov (可以理解为 header),而 moov的大小则和视频的长度相关。所以需要针对不同的视频计算出不同的预加载大小。第二个是即便视频数据已经预先下载完毕,但在开播前播放器的创建,外壳 view的布局,内核中的 MP4 解封装、解码、渲染仍然会导致有数百毫秒级别的耗时,在全屏沉浸式的场景中仍然能被用户感知到加载过程。 为了实现极致的快开体验,我们实现了多实例的播放器,在预加载的基础上更极致地缩减开播耗时,实现了直出的开播体验。一般情况下,卡顿和视频清晰度是互斥的,清晰度越高,视频码率越高,用户越容易遇到缓冲卡顿。为了一个指标牺牲另一个指标是不被接受的。我们的视频内容在下发前会在云端预先转码成多档清晰度,并在端的播放器实现了一套在播放过程中基于用户的网络类型、平均网速、视频时长等指标动态升级或降级清晰度的策略,保证了绝大多数用户都能观看到匹配自己网络条件、最高清晰度的视频,在提升整体视频质量的同时守住了卡顿率。
-
预加载时机提前
利用滑动切换视频时,在滑动松手到滑动停止这段时间(300 毫秒),在保证滑动帧率的前提下,开启子线程预加载后面的视频,利用这 300 毫秒,预加载后面的视频流,保证本地起播。相比原先预加载时机是在滑动停止,当前视频起播后才预加载后面的视频,假设视频起播时间为 500 毫秒,则相比优化前,预加载时机提前了至少 800 毫秒,这是非常可观的提升。最后测试下来,也是此优化项对于缓存命中率的提升是最为明显的。
-
多播放器
空间换时间。双播放器方案原理比较简单,就是在当前视频起播之后,预准备下一个视频的播放器,两个播放器循环使用。下一个视频的播放器一旦准备好,加上视频流已加载到本地,则起播非常快,几乎是视频直出的效果。但由于播放器准备更耗时,用户滑到下一个视频时,并不能百分百保证此视频的播放器已准备好。
- 修改AndroidVideoCache进行预加载
- 线程池并发缓存并控制视频缓存优先级(线程池线程数为3,先加入的先缓存),一次预加载8个视频,item创建时开始预加载,item销毁时,取消预加载
- 等待下页第一个视频预加载完成,才会进入下一页视频,保证滑到的视频都是可以立马观看的。(一页视频为8个)
- 当前视频开始播放之后才会进行预加载
- 区分快滑慢滑两种模式,快滑时取消当前所有预加载,慢滑不取消,因为快滑大概率滑到一个未预加载的视频,慢滑大概率滑到一个已经预加载的视频,保证滑到视频尽快播放。
- 当视频播放后,根据滑动方向,会将取消的预加载进行恢复,正向滑动就恢复当前之后之后的预加载任务,反选滑动就恢复当前视频之前的预加载任务。
- 限制网速,当时视频还没播放的时候,会限制预下载的网速(慢滑不会取消预加载),通过让下载线程sleep来限制网速。
- ijkplayer起播参数配置。
- 视频压缩和处理(让视频参数都位于视频首部)。
很多手机为了偷懒,录制完视频后才知道视频信息,所以把moov放到末尾。对于moov放到视频最后的情况下,就要多一次seek,当从头开始解析的时候如果发现未找到moov信息,需要将其seek到尾部再去寻找,这样会导致起播慢。
针对这种情况可以采用后台做转码修复,客户端增加监控打点。
解析完MOOV后需要下载多少数据才可以起播呢?
- Android 6.0及以下 : 5秒视频数据
- Android 7.0及以上 : 一个GOP
- FFmpeg Based Player : 关键帧
播放端识别首个关键帧即启动播放,或者通过减小GOP间隔来提高加载速度;也是可以达到的。
有关DNS相关可参考DNS及HTTPDNS
IP竞速
DNS解析加快,通常,DNS解析,意味着要把一个域名为xxx.com解析成ip过程,平时请求网页,网络差,就会打开网页半天。
QOS(Quality of Service,服务质量)主要指网络环境下服务满足用户的程度,在视频服务的语境下也可认为是Quality of Streaming,即流媒体服务的质量。通常,QOS可以由一系列指标表达,如传输速度、响应时间、发送顺序、正确率等。就视频服务来说,QOS由多项约定俗成的技术指标构成,包括播放成功率、错误率、Re-buffer(卡顿)次数和时间、起始时间、快进响应时间、视频码率、延迟等。 通行的QOS指标大致可分为两类:
- 一类用于衡量用户可在多大概率上得到服务,如播放成功率和错误率。
- 另一类描述了用户所获取到服务的水平,如卡顿次数、时间、起始时间、快进时间、视频码率和延迟。
播放成功率描述了用户在尝试播放视频时启动成功的比率,可由所有成功开始播放的次数除以用户尝试的总数,常见于后端视频失效的情形。 播放错误率意在针对播放过程中至少单个视频或音频帧被播放的情况下发生的错误,可能的原因包括播放器崩溃、硬件关闭、网络断开等,需要用户干预才能恢复播放。 在视频服务质量日渐提升的今天,播放错误率出现的概率通常在千分之一以下甚至更低,用户最常见且容易不满的当属视频卡顿(也有人称之为缓冲率),即播放器无法即时得到流媒体传输的视频片段而需等待下载的情形。 卡顿可能短程的发生,也可能持续很长时间,根据一些公司的研究,用户在观看视频点播时遇到一次以上的卡顿,会导致观看时间缩短一半,对直播用户的影响还要更甚于此。卡顿指标即包含单位时间内的卡顿次数也包含卡顿累计时间的维度,优化卡顿时间的最常见的方式是利用CDN和码率自适应算法。
视频卡顿的一类特殊情形是起始播放时的卡顿,通常计算从用户点击播放到第一帧呈现在屏幕上为止的时间长度,因为获取最初可用的视频片段需要一定时间,包括后台服务准备资源、下载视频开始的片段、初始化软硬件等。 与播放过程中的卡顿不同,用户有等待数秒的心理预期,据调研2007年的大部分用户能接受10s以内的播放起始时间,但在2017年,5s的视频起始等待已被认为是非常糟糕的体验,中国许多视频服务商都提出了“秒开”的概念,力图将用户习以为常的起始时间固定在1s以内。另一类情形是快进时间,与起始时间非常类似,意指用户在点击快进后到视频呈现在屏幕之间的时间长度。 优化起始时间可以通过将起始视频片段预先置于CDN的边缘节点,降低起始码率,增加播放器初始化并行度,预先建立网络连接等方式。此外,播放器还可以通过插入片头动画,持续播放快进前的视频片段直至快进后的视频帧准备好等手段降低用户的主观等待时间。
用户观看视频的平均码率也是一项核心指标,用于反馈视频的清晰度程度,针对直播服务,节目延迟时间也是核心指标,没有人原因在观看足球比赛时,隔壁已经为进球欢呼,而自己的电视上球员尚未开始射门,通常的计算标准是节目应播出的时间与实际屏幕上播放时间的间隔。带来延迟的除软件处理速度、网络传输速度外,编码器,源服务器及CDN服务器带来的缓存队列,播放器中解码器和渲染硬件均会引入大小不同的延迟。
QOS数据由后台服务整合后将被应用于图表呈现、统计报告、分析优化、监控报警等用途,是产品、开发、运维、数据分析等团队依靠的基础。
为更好的分析特定问题,收集关于某一用户播放过程的全部信息并按时序加以呈现,可以有效地帮助理解因果关系,信息将包括用户行为、执行时间、下载计时、码率切换记录、错误类型、CDN节点位置、服务器日志甚至一些计算的中间结果,将可有效地推断例如开始播放较为缓慢或者某次卡顿如何发生的原因。例如:
xx:xx Player Seek Start
xx:xx Player Seek End
xx:xx New State: Buffering
....
Conviva在2011年的分享中提到以下观点,缓冲次数始终是最主要的影响用户体验的因素,在观看90分钟长度的OTT直播中,增加1%的缓冲比率将使用户减少3分钟的观看时间,同时认为,在直播过程中,平均码率的影响要比点播中更大。 在2016年的一篇文章中,研究者利用YouSlow的数据分析得到的看法是,缓冲对退出观看的影响比启动时间要高六倍。
视频公司在编码和传输上进行的优化,其指向的目标无疑是提升用户体验,或严格来讲,是获取更多的收入和利润。衡量编码或传输的优化表现,除了直接使用QOS指标如观看码率、启动时间、缓冲次数等,将其余QOE(Quality of Experience)指标连接则更可以直观地反应出成效。 不断优化表现直接与收入关联的主要原因是,收入统计通常计出多门且较为滞后,可采用的替代指标包括注册用户数、活跃用户数、视频观察市场、观看次数、播放占比、付费率、留存率、分享率、满意度等。
监控上报,肯定是不可缺少的,这是一个成熟的项目必备的要素。
- 问题定位,老板跟用户反馈说我这个视频播不了,要有一套成熟的问题定位的方式; 传统的捞Log方式大家都有,但是这种方式效率太低,需要等用户上线之后才能捞到Log,Log捞到之后还得花时间去分析。我们做法的是在关键问题上做一些插装,把每一类错误和每一个具体的子错误都能定义出来,这样一看错误码就知道播放错误是由什么原因导致的。还可以把每次播放视频的链路所有关键流水上报到统计系统里来,每一次播放都是一组流水,每一条流水里面就包含了例如首次缓冲发生的Seek,或下载的链接是多少,下载的时间是多少,有了这些流水之后,用户反馈播放失败,我首先可以用流水看发生了什么错误?错误在哪一步?每一步信息是什么?几秒钟就可以定位到问题。
有了这个数据上报之后,还可以做一些报表。比如说可以做错误码的报表,有了报表之后就可以跟进哪个错误是在TOP的,负责人是谁,原因是什么,都可以看到。
我们也有自己实时的曲线,可以看到各项数据的情况。在告警方面,基于成功率和失败率的统计,进行实时告警。
- 邮箱 :charon.chui@gmail.com
- Good Luck!