网易新闻从0到1的短视频性能优化之路

本文阐述了网易新闻客户端在段视频性能方面的优化思路、过程及结果,作到了小投入高产出算法

本文做者:Re(网易传媒技术团队)缓存

1、前言

在过去的2018年,短视频开始占据互联网愈来愈多的流量。爆红的短视频社交应用自没必要说,经过短视频来获取新闻资讯、观看音乐专辑、甚至在电商平台观看商品介绍也已经成为愈来愈多用户的选择。安全

网易新闻客户端做为一个资讯类产品,也在逐渐增长视频形式的内容来知足用户的需求。而随着视频的内容的增长,视频体验也变得愈来愈重要。若是视频的观看给用户形成了困扰,那么就会增长流失用户的风险。服务器

为此咱们在过去的一年中对视频的性能进行了持续的优化,虽然期间遇到过不少困难,但也所以收获了宝贵的经验。咱们但愿将这个过程当中的经验和思考分享出来,一方面是做为一个阶段性的总结,另外一方面也但愿能对你们有所帮助和启发。markdown

在这篇文章中,咱们将围绕如下几点来分享咱们的经验与思考网络

  • 如何明确优化的方向与重点并发

  • 客户端上有哪些提高性能的手段框架

  • 如何结合具体状况进行技术选型性能

  • 客户端外咱们作了哪些优化优化

  • 数据导向的重要性及对咱们的帮助

2、明确方向

短视频做为网易新闻中的一个功能,是重点但不是所有。在优化上咱们没有不停试错的成本,因此抓住重点与方向很重要,这样才能在有限的成本中达到最好的效果,一旦跑偏那么会浪费大量的时间和人力。

流程分析

系统地了解视频的播放流程是有助于咱们把握方向的,站在一个全局的角度对视频播放进行分析也更容易发现其中的问题。因此咱们先将须要优化的过程拆解成几个独立的过程,分析这些过程各自的特色,而后结合咱们的目标和条件去进行选择性的优化。

生产流程

在了解视频的播放流程前,咱们能够先看看视频是如何生成的。

  • 数字化

    曾经普遍流行的模拟摄像机输出的是模拟信号,由于计算机只能处理0和1,因此须要将模拟信号转换为数字信号,这个过程就叫作数字化。虽然如今数字摄像机和手机已经成为主流,能够直接输出数字信号,可是这些设备内部的光感元件本质上输出的仍是模拟信号,因此这个过程仍是存在的,只是绝大多数状况下咱们不须要去关心它。

  • 编码

    原始数字视频的数据量是至关大的。若是不进行压缩,经过现有的网络传输能力是难以流畅的在线播放的,即便是存储也会变得很是不便。因此咱们须要经过压缩来高效的存储数字视频的数据,这个过程就叫作编码。常常看到的 H264(AVC)、H265(HEVC)就是常见的视频编码,AAC 则是一种常见的音频编码。

  • 封装

    咱们一般意义上的“视频”,其实包含了视频数据和音频数据,有时还会包含多音轨或者字幕。因此咱们须要一个容器可以将视频和音频等数据打包传输存储,而且可以保证它们在时间上的同步。将以上这些元素打包进一个容器中的过程就叫作封装,而咱们常常提到的 MP四、MKV、TS 等等这些其实都是一种封装格式。

  • 协议

    这里的流媒体协议指的是 HLS 、DASH 这些基于 HTTP 的动态自适应协议。在直播风头过去后,这些流媒体协议仍然活跃在不少点播场景中。并非全部的视频都须要而且能够经过流媒体协议来下发,可是这些流媒体协议的动态自适应等特色在一些场景下能够帮助咱们得到更大的优化空间。

播放流程

在了解了视频的生产流程后,再看播放流程就相对简单了。若是说视频的生产是将数据一步步封装组合的话,那么视频的播放就是将数据一步步拆解还原。

咱们将客户端获取视频数据的过程也加进来,那么一个视频在手机上播放会经历如下这些步骤。

  • 读取

    获取视频的数据,数据的来源能够是网络、磁盘或者内存。

  • 缓冲

    通常状况下,读取的速度是大于播放器消费的速度的,咱们能够将已经读取但播放器还没有消费的数据存储在内存中,这样当 I/O 速度有所波动时能够必定程度上避免对观看体验的影响。这个过程就叫作缓冲。

  • 解协议

    若是咱们读取的是流媒体协议,好比 HLS、DASH 这种,那么咱们还须要进行解协议的操做。按照索引文件的规则去读取相应的视频文件,但若是咱们读取的已是 MP4 这种容器文件的话,那么就不存在这一步了。

  • 解封装

    视频、音频等数据都封装在了容器文件中,所以要想解析视频和音频就须要将它们从封装容器中提取出来。按照封装格式的规则进行数据提取的过程能够称做解封装。

  • 解码

    在解封装后咱们拿到了视频和音频的编码数据,接下来须要将它们解码还原成视频和音频的原始数据。

  • 渲染

    最后咱们就能够将视频和音频进行输出从而进行观看了。

在了解了基本的播放流程后,就须要结合目标进行具体分析,看看在这个播放的流程中哪些过程是值得咱们重点关注的。

目标分析

在网易新闻客户端上咱们是以秒开率、卡顿率、失败率三个指标来衡量性能。

秒开率

秒开率的优化重点和首屏平均时间是不同的。秒开率不只仅要求的是速度,也衡量着播放器的稳定性。

当总体水平提高到必定阶段后,首屏平均时间关注的仍然是中坚用户,由于他们的占比最大,优化的效果对于均值的提高最明显;但秒开率更须要关注的是那些性能较差的用户,由于只有这部分的用户性能提高了,秒开率才能提升。

因此对于秒开率来讲,“读取”阶段最为关键。数据默认状况下都是从网络读取,而网络的时间是很是不可控的。恶劣的网络环境下加载时间很容易就会超过1秒,所以这里有着很大的优化空间。

卡顿率

卡顿率的计算方式虽然有不少种,可是衡量的东西都是同样的。若是咱们的带宽跟不上码率,又没有提早在内存中缓冲到足够的数据的话,就会形成卡顿的升高。数据的读取和缓冲的策略会对卡顿有着较明显的影响。

失败率

视频播放失败的缘由则有不少,多是网络上的错误,也多是本地缓存文件的异常,又或者硬件解码失败等等。除了缓冲,理论上每一个步骤都有可能致使播放失败。

综合上面的分析,咱们能够大体把重点与方向锁定在读取与缓冲阶段,而其他阶段则是当咱们须要优化失败率或者遇到瓶颈时须要考虑的。

3、技术实现

在肯定了重点与方向后,接下来就是方案了。要想提升秒开率,首先想到的会是预加载。

预加载

预加载做为最多见的优化手段,能够在网络畅通、流量充裕的状况下提早将数据缓存到本地,有效避免弱网时加载视频的等待。在网易新闻客户端上,预加载的各类策略能够为咱们带来接近 10% 的秒开率绝对值的提高,能够提及到了很是重要的做用。

不过虽然预加载简单好用,在实现的过程当中仍是存在着不少咱们须要注意的细节,若是不加以注意不只会让效果大打折扣,还会带来不少问题与麻烦。

控制预加载的大小

不一样于文章的文本数据,视频中有视频数据、音频数据、元数据等信息,要大的多。

举个例子来讲的话,假设咱们如今但愿预加载一个视频时长 34 秒且清晰度较好,固定码率是 800Kbps 左右,那么这个视频的大小就是 800Kbps / 8 * 34 / 1024 = 3.4M。消耗 3.4M 流量去加载一个不必定会被消费的内容是很浪费的,更况且实际使用中会发不少预加载请求,这个消耗将是巨大的。

磁盘消耗

过多的数据首先会占用到大量磁盘的空间。若是预加载的文件在磁盘中占用太多空间会直接影响到用户的手机使用,但若是占用的空间较少又会致使磁盘频繁的删除和写入。

流量消耗

大量的数据在流量上也会是一笔很大的开销。对于用户来讲,预加载会形成他们的流量浪费,因此咱们应该在 WiFi条件下才开启预加载。对于公司来讲数据量过多一样会致使成本升高,这是由于不少时候咱们都会借助商用 CDN 来提高性能,而 CDN 是按流量计费,因此流量的浪费就等于资金的浪费。

合适的大小

要避免这些问题,最好的办法仍是控制每一个视频预加载的数据量在一个合适的大小。这个大小的值取决于视频的起播缓冲量,简单来讲就是须要加载多少时间的视频数据后才能渲染出首屏画面。咱们的预加载至少要大于这个起播缓冲量才能发挥做用

若是一个播放器须要5s的数据才能起播,那么咱们的预加载数据量就须要至少可以播放5s的视频才行。不然当点击视频播放时,预加载的数据量不够起播,那么仍是得去网络继续下载数据,就又会受到网络环境的影响了。

对于不一样时长、不一样编码、不一样播放器播放的视频,这个须要下载的大小是不同的。咱们能够在后台提早计算好这个大小,经过接口告诉客户端

切换播放器的输入流

既然要作到部分数据的预加载,那么就不可避免的要涉及到流的切换。假设一个视频总长度34秒,咱们预加载了前2秒,那么咱们须要完成的任务就是前2秒的视频去读取本地文件,然后32秒的数据去经过网络请求。

不少播放器都不支持在一次播放内进行流的切换,因此咱们须要本身去实现这个逻辑。但不少时候播放器为了保证自身的稳定性都会进行封装,不要说解码、渲染等过程,即便是读取过程也没有暴露给外界。最多见的就是 Android 和 iOS 平台上的系统播放器了,它们虽然使用简单方便,可是不易扩展,内部对于咱们来讲基本上就是一个黑盒,从读取到渲染都是在播放器内部完成的。

若是咱们没法去定制播放器的读取流程,那么切换播放器的输入流就无从谈起,预加载也就没法落地。这时摆在咱们面前的只有两条路,一条是选择一个能够支持定制读取流程的播放器,另外一条则是对播放器进行“欺骗”的本地代理了。

本地代理

经过本地代理咱们可让播放器觉得本身一直在读取“网络数据”,可是这个“网络数据”其实是咱们的本地代理服务器提供的。咱们能够在代理服务器处进行缓存、切换流等逻辑,这样就能够在不改变播放器行为的前提下改变播放器的输出结果。

要实现本地代理咱们须要在客户端本地创建服务器,监听 localhost 的指定端口,并将全部的视频请求都指向这个端口。这样本地代理服务器就能够拦截客户端的请求从而进行定制和改造了。

本地代理的优点在于对原有代码几乎是无入侵的,须要作的仅仅是将本来要传给播放器的 url 包装成指向本地代理服务器的 url 就好了。可是这个方案一样存在着缺点,咱们须要处理许多细节问题,好比代理服务器中断后的端口更新、拖拽形成的 range 请求的特殊处理、缓存文件存在但内容损坏时的容错等等,稍有不慎可能就会形成视频的播放失败等问题。

提高预加载的命中率

光是实现预加载是不够的,咱们还须要让预加载发挥出最大价值。提升预加载的命中率能够不只能提高性能,还能下降成本

要实现这个目标咱们须要了解用户在当前页面接下来可能会消费什么内容,而这个预测是须要创建在数据的基础之上的。不一样产品、不一样业务下用户的行为均可能有所不一样,所以咱们须要结合数据在具体场景下去具体分析。

好比网易新闻最一开始有两个入口能够进入视频播放页。分别是新闻栏目和视频栏目。最一开始咱们想固然的在视频栏目进行预加载,这样进入视频播放页的时候就能够直接使用已加载的数据,可是上线后效果并不理想。 分析过数据后咱们发现进入视频播放页的大部分流量其实都来自新闻栏目,而视频栏目进入的占比则不多。而在增长了新闻栏目的预加载后,数据确实获得了明显的提高。

相似的场景还有不少,好比保持预加载的顺序和自动播放的顺序相同、优先下载热门的视频等等。任什么时候候咱们都应该优先预加载用户最可能播放的内容

下降预加载的反作用

虽然预加载带来的好处显而易见,可是若是处理很差也会带来一些麻烦。

处理播放器和预加载请求的冲突

首先预加载做为一个单独的网络请求,是有可能跟播放器的网络请求冲突的。而冲突的结果,若是是不一样的视频,则会抢占带宽;若是是相同的视频,根据你的实现,可能会没命中缓存或者发生异常。

所以咱们须要作的是当播放器加载视频时停掉预加载的请求,并去判断是否有缓存文件。当播放器空闲时,再继续队列中的预加载。

限制预加载的资源占用

若是预加载的并发数若是过多,会占用过多带宽和系统资源,影响到其余的业务和功能。所以由一个单线程依次执行预加载队列中的任务是比较合适的。

让预加载请求和页面生命周期绑定

当退出页面时,咱们应该中止并清空队列中属于这个页面的请求,由于这些视频极可能已经没有机会被播放了。

若是咱们只是暂时离开了一个页面,那么挂起这个页面发起的预加载请求是比较合适的。由于极可能咱们进入的页面会有新的预加载请求,继续以前页面的请求会让咱们新的预加载请求没法第一时间开始执行。

除此之外还有不少细节的问题咱们能够进行处理,这些细节虽然提高有限,可是聚沙成塔也能有显著的效果。

缓存

预加载本质上就是一种提早的缓存,只是其写数据的时机和逻辑能够不依赖于播放器。而缓存虽然与播放器息息相关,可是比预加载要更加泛用,好的缓存机制能够带来续播、重播等场景的体验提高。

在优化缓存时咱们能够参考其余的缓存机制,好比图片缓存等等。它们之间既有类似之处也有差别和不一样,咱们能够对于其中类似的部分能够进行借鉴,而对于不一样的部分进行优化改进。

缓存的切片

图片缓存中咱们一般会以url做为key,将完整的图片数据做为value保存起来。当所占空间到达上限时经过一些淘汰算法进行部分缓存的清除,好比经常使用的LRU。但若是咱们在使用MP4视频时仍然使用这种方式缓存,就可能遇到一些咱们不但愿出现的场景。

如今用户打开了一个已经缓存过的视频,在观看了几秒钟后就关闭了,这种状况老是很常见,好比这是一个信息流中自动播放的视频。这个时候视频的最近使用时间被更新了,但其实它是一个用户不感兴趣的内容。 根据缓存策略,这个文件的清除顺序会被日后排。前几秒由于被播放过,日后被清除是能够被接受的,可是后几分钟没有看过的内容,由于跟前几秒属于同一个文件,就也被日后清除,显然对其余文件不太公平。这会影响到其余缓存文件的存活时间。

因此咱们应该将本地的缓存文件切片,在缓存的key中增长一个时间片断维度来区分同一个视频的不一样时间片断,让真正被最近使用的文件才最晚被清除。这能够让视频得到更细的淘汰粒度,从而提升缓存的命中率

每一个切片的大小没有严格的要求,可是都有一个统一的上限,好比最可能是500KB。这会带来另外一个好处就是在处理 seek 时逻辑会变得简单。当发生拖拽时咱们只须要结束当前文件的写入,新建立一个文件进行顺序写入操做就好了。

创建多级缓存模型

图片缓存的另外一个特色,则是咱们常常会用到多级缓存模型。最基础的三级缓存根据IO速度的不一样,分为内存、磁盘、网络。有时候针对业务特色,可能会发展出四级等模型,根据重要性再次进行区分。

那么视频是否是也能够借鉴一样的思路呢。前面咱们已经分析过视频的大小,将视频完整的放在内存中确定不现实,但跟预加载同样只加载前几秒的数据仍是可行的。

首屏数据

经过前面的预加载和缓存切片,咱们至少能够将一个完整的视频文件分为首屏数据和内容数据。

首屏数据即预加载下载的数据,即大于或等于起播时间长度的数据。 内容数据则是除首屏数据之外的全部数据,固然内容数据也是能够再切分的,这里咱们先简单地将内容数据看成一个总体看待。

三级缓存

将首屏数据放到内存中能够得到更快的IO速度,在遇到磁盘性能较差的手机或者磁盘IO密集的环境时也能将波动尽量下降。

视频的秒开很大程度上取决与首屏数据的读取速度,所以稳定快速的首屏数据获取能够进一步保证视频的秒开。

四级缓存

若是咱们磁盘上的淘汰策略是LRU,则会将最近最少使用的文件切片清除。 但在不少状况下,即便某个首屏数据没有被使用过,它的重要性也可能比使用过的内容数据更高。由于用户看过的视频不必定会去看,可是页面上看到的未播放过的视频是有可能会去点击的。

基于这种特色咱们能够换一种淘汰算法,好比跟LRU策略相反,将播放过的视频优先淘汰,由于可能咱们会认为用户对于看过的视频不会再感兴趣。但这种场景是不能一律而论的,好比重播场景这种方式就明显不适用,因此具体的策略还得根据数据分析来进行决定。

若是咱们不想去考虑那些复杂的问题仍然使用LRU的话,在磁盘层再分出一级缓存出来演化成四级缓存是另一种方案。

这里的二三级缓存虽然没有速度的差别,可是在优先级上是有区分的。当磁盘空间不足时,会优先清空三级缓存中的内容。首屏数据获得保留,从而能够为下次的播放提供秒开的条件。

不论几级缓存,其目的都是同样的,都是为最重要的数据提供尽量快的IO速度

缓冲控制

在多级缓存模型中,能够经过增长了内存缓存来获取更快的IO速度。而在播放器内部其实也存在着一个基于内存的缓存,虽然它只能缓存播放器正在加载的视频,可是保证了视频播放的流畅性。咱们将这个播放器内部的内存缓存称为缓冲。

缓冲的控制在优化中一样起到了举足轻重的做用。网易新闻客户端早期使用的是系统播放器,在Android 6.0 如下的系统播放器默认的起播缓冲量是5秒数据,这个时间在弱网下会大大增长首屏的时间,在替换播放器并优化了这个时间后咱们的秒开率直接提高到了 80%。在卡顿率上,各类缓冲策略的调整帮助咱们下降了1%的绝对值,至关于卡顿次数减小了30%。因此,缓冲的控制是咱们不能忽视的。

让播放器能第一时间播放

单纯的下降起播缓冲量好比从5s降到1s已经能够看到明显的效果了,可是咱们能够将这个值计算的再精细些。

如今绝大部分的视频编码格式都是 H264,在 H264 的传输单元中包含三种帧,其中I帧具有完整的图像信息能够独立解码,P帧须要参考以前已经处理的帧,B帧则既须要参考以前的帧,也须要参考后面的帧。两个I帧之间的图像序列称为一个GOP(Group of Pictures)。

若是咱们能够在转码时保证视频的第一帧是I帧,那么一个I帧的数据加上当前视频格式的元数据,这些就是咱们起播视频所须要的最小大小。

这个大小按照咱们以前说的能够在后台提早计算好,而后下发给客户端,播放器在播放前配置好,从而保证视频的第一时间渲染。

两个起播缓冲量

“起播的缓冲量越低,咱们就能够越早的渲染画面,优化效果就越好”,这句话并非彻底正确的。

首先,当这个时间小于I帧的数据时,再小也是没有效果的,由于解码器无法还原出一个完整的画面。

其次,起播缓冲量在不一样场景下起到的做用是不同的。当首次播放时,较低起播缓冲量的缓冲量能够帮助咱们快速打开视频。但当缓冲区见底从新加载到足够数据时,当即播放反而可能会给用户更差的体验。想象一下当你在高铁上打开手机想经过视频来打发时间,却发现视频播一帧卡一下,这种感受是很难受的。

若是咱们将起播缓冲量分为首屏起播缓冲量和卡顿起播缓冲量的话,那么前者大小能够是咱们以前分析的首个I帧数据,然后者的配置则应该结合具体的用户场景进行分析。

缓冲区的限制

在网易新闻中有着不少自动播放的场景来帮助用户更低成本的观看视频,可是这不必定是对全部用户都是有帮助的。虽然提供了关闭自动播放的选项,仍然会出现自动播放了用户不感兴趣内容的场景,当出现这种状况时用户都会选择手动关闭掉视频。

试想一下若是咱们的缓冲区没有上限,发生上述场景时极可能在用户思考的短短几秒内就已经加载完了完整的视频。随后用户关闭它而且再也不观看了,那么后续下载的那些数据都将成为浪费。

所以咱们不能在播放后就无止境的加载,而应该在加载到了足够数据后暂停缓冲,当缓冲区的数据快要不足时在从新开启这个任务。咱们能够将这个停的节点做为缓冲区的上限,将重启缓冲任务的节点做为缓冲区的下限。

缓冲模型

结合上面的分析,咱们了解到有四个节点是咱们比较关心的,经过这四个节点,能够组成一个缓冲模型。

首屏起播缓冲量表示首次播放时只有到达这个数据量时才能开始渲染。卡顿起播缓冲量表示进入缓冲区数据见底致使画面中止,从新加载到足够数据容许播放时的缓冲量。缓冲区的上下限则分别定义了缓冲该什么时候中止和从新开始。

缓冲的自适应

在前面咱们说到以I帧的数据量进行首屏起播,这是最理想的状况。可是并非全部用户在这个最理想的配置下都能得到最理想的体验。

当弱网环境下,咱们很快的加载出了I帧的数据,渲染出了画面,可是画面很快就又停住了。这是由于咱们的带宽跟不上码率,因此后续的数据尚未下载下来,随后用户就会开始播一帧卡一下的场景了。

这时候咱们须要对不一样网络状态下的播放进行针对性的调整。咱们可让上面模型中的参数变得更加智能。好比当带宽较低时,咱们能够适当的延长首屏的起播缓冲量、当频繁发生卡顿时,咱们须要适当增大卡顿的起播缓冲量等等。

了解了方案后剩下的就是实现了。对于一些播放器来说,这些可能只是一个简单的参数配置问题;对于另外一些播放器来说,可能须要本身去实现这个模型;但还有那么一部分播放器,你拿着优化方案却根本无从下手,由于它们根本不支持定制。若是你是最后这种状况,那么或许你应该从新考虑技术的选型了。

4、技术选型

技术选型是至关重要的。它不只决定了优化的上限,同时也影响着方案的实现

之因此放在后面说,是由于若是一上来就讲,未免会显得有些空洞。若是没有实际遇到问题,很难能体会到不一样技术上的差别和特色。可是若是你完整的阅读了前面的内容,应该已经可以理解这一点了。

播放器的选择

在上面的优化中,感觉最明显的就是播放器的选择了。若是咱们的需求超出了播放器的能力范围,那么任何优化作起来都会变的很困难。因此咱们先来看看播放器的选型。 客户端上能够使用的播放器有不少,咱们能够大体分为如下三类

理论上讲,越偏底层的播放器,上限也就越高,可是要承担的风险也就越大。 因此在选择时咱们应该结合本身的目标和条件,进行合适的选择。

网易新闻的播放器

以网易新闻举例,咱们当时所处的环境有如下一些特色。

  • 在视频优化上能投入的人力很是少。而且在优化的同时还得兼顾业务需求等等其余事情,这意味大刀阔斧的底层改造很难在短时间看到成果。

  • 业务迭代快。这就须要咱们的播放器须要足够的稳定,有着很强的健壮性。若是常常性的 ANR 或者 Crash ,会浪费大量的时间排查与定位,大大下降业务效率。

  • 咱们客户端团队中还缺乏经验丰富的 C/C++ 开发。这种状况下很难在底层快速实现定制化需求,同时也会有着很大的风险,也不利于以后的工做交接和维护。

这种状况下咱们在 Android 平台上选择使用 ExoPlayer。做为 Google 研发并普遍应用在国外诸多 App 上的播放器框架,ExoPlayer 有着稳定、可扩展等优势。对上述提到的不少优化项好比预加载、缓存、缓冲模型都有着很好的支持,基于 Java 的实现也能让咱们高效安全的进行定制与扩展,完美契合了咱们当前阶段的需求。

在 iOS 平台上咱们则继续使用着系统播放器。平台的优点让 iOS 的播放表现比 Android 更加稳定,再加上系统对预加载、起播缓冲配置等特性的支持,基本能知足咱们当下的需求。因此 iOS 上咱们在不替换播放器的前提下进行了播放器预建立、本地代理等优化,在保证稳定性的前提下提高了性能。

这套方案虽然一样存在着一些制约,可是对于现阶段的咱们来讲倒是最合适的。在知足咱们性能需求的同时,避免了成本问题与风险问题。

选择合适的技术

除了播放器,咱们还会遇到不少技术上的选择,咱们须要作的是找到最切合本身业务的技术。

若是应用常常播放番剧电影这种长视频,那么使用MP4格式会由于moov信息过大而消耗太多的解析时间。这时能够考虑使用 HLS 或者 DASH 等流媒体协议下发切片文件。

若是视频播放时常常会有满屏的礼物动画,那么当动画的计算和软解码的播放器一块儿抢占CPU资源时就很容易在低端手机上卡顿。这个时候使用硬解码会更加的合适。

若是没有完善的兼容方案就盲目的上线H265,极可能原本之前能播放视频的用户如今都没法进行观看了。即便用户能播放出来,也可能由于解码时间变长了而成为负优化。

相似这些场景还有不少,一句话总结的话,就是技术的选型不能脱离业务的场景

5、其余的优化

咱们上面讨论了不少客户端上的优化,可是说到底客户端只是整个视频播放过程当中的一个环节。

除了客户端,视频的播放还会通过视频的生成、转码、CDN的调度等过程。在这些过程当中存在着一些咱们须要注意的地方,它们极可能会在较大程度上影响着视频的性能,可是却没有太多优化成本。

避免MP4的二次请求

MP4 文件由一个个 box 组成,其中有一个叫 moov 的 box,存储着播放 MP4 视频必不可少的信息。 在下发 MP4 资源时咱们要确保这个 moov 在文件的前面。由于在不少时候,生成的 MP4 的 moov 会默认追加在文件末尾,这时若是播放器直接播放会在找不到 moov 时二次请求文件末尾,从而影响播放速度。

若是咱们的视频生成来源是不可控的,在后台进行视频的统一转码是颇有必要的。

切片文件的优化

若是视频资源是经过 HLS 或者 DASH 协议下发的切片文件,那么咱们能够考虑在切片文件上进行优化。

默认转码下,每一个切片的时长和码率都是相同的。咱们能够将首个切片的时长和码率下降,从而让首屏的数据变小,获取更快的首屏打开速度。在首屏以后让切片时长和码率随着进度的增长从低到高逐渐提高,使用户可以播放体验从快速趋向于平稳。

与CDN配合的优化

预加载能够下降客户端的首屏时间,一样也能够下降 CDN 回源形成的延时。若是 CDN 提早从源站预取了热门的视频,就能够保证边缘节点第一时间提供数据。而且在咱们前几个切片文件缩小后,将策略调整为预取热门视频的前几个切片文件能够在相同的存储空间下缓存更多的热门视频。

CDN 有时会由于成本问题没法保证全部的视频文件都缓存在固态硬盘上,这时咱们须要优先在固态硬盘上缓存每一个视频的首个切片,避免硬盘的IO速度对视频秒开的影响。前几个切片文件缩小也有助于咱们在固态硬盘上存放更多的视频,更大程度的进行覆盖。

多CDN的调度

在优化早期咱们的视频业务只使用一家 CDN,而咱们和 CDN 又常常会同时进行一些优化或调整,因此当性能出现波动时,会出现多个变量同时存在的场景,很难去定位性能影响的缘由。尤为是出现一些难以解释且难以定位的问题时,会花费至关多的时间去排查分析。因而咱们选择接入多家 CDN,这不只在必定程度上帮助了咱们定位问题,在容灾等方面也让咱们有所受益。

在接入多 CDN 之后,咱们发现不一样 CDN 的技术细节是有所差别的,对不一样场景下的优化经验也不同。好比一样的视频经过不一样 CDN 下发,在不一样平台、不一样清晰度等环境下的数据表现会出现各有优劣的状况。根据这个特色,咱们综合历史数据的表现去动态调度用户访问的 CDN 资源,从而让用户能过得到最好的体验。

除此之外的优化还有不少,相比端上的优化,客户端外的优化更多的是须要沟通与配合。当咱们可以明确共同的目标、积极地互相配合、高效地沟通与解决问题,那么取得的效果将会比单方的努力要好的多。

6、数据导向

有句古话叫作“兵马未动,粮草先行”。若是将开展优化项目比做行军打仗,那么数据收集就是战争中的粮草。没有粮草战争没法进行下去,而没有数据支撑优化工做也将没法展开下去。数据能够说是优化的前提

衡量结果

没有数据支撑,咱们不知道本身的优化是否起到了效果,也不知道本身的思路方向是否正确。 经过直观感觉去衡量优化结果是很危险的,它极可能让你产生错误的判断,从而得出错误的结论。因此若是你打算开始作优化,进行性能的埋点上报是首先须要作的。它能够确保你的第一次优化效果也可以经过数据体现出来。

经过数据咱们能够了解到哪些工做起到了做用,哪些优化又是可有可无的。当咱们抓住了重点,就能够朝着这个方向进行突破而不会跑偏。能够说数据不只能帮助咱们衡量结果,也能指导咱们从此的方向。

排查问题

进行数据的上报只是第一步。网易新闻客户端在早期虽然上报了数据,但在后台只有一个简单的平台展现。条件筛选须要提早约定好、数据在显示上也会有所延时。那时候出了问题咱们不能第一时间发现,多维度的分析也须要自行跑脚本去处理原始数据。

后来咱们的后台小伙伴对性能平台进行了改造,支持了多维度条件的筛选,数据的实时计算等功能。在那之后,出现问题咱们能够第一时间从网络状态、系统版本、渠道等各个维度进行排查,大大提升了咱们的效率。

举例来讲,有一天咱们发现秒开率从早上7点开始就断崖式降低。咱们经过多维度的筛选,定位到一秒率的降低集中在同一个视频上,而这个视频有着远远高出其余视频的播放量。经过分析这个视频,咱们发现这个视频是当天的热点视频,其播放量和其余产品数据是相吻合的,而由于这个视频自己的码率较高,致使首屏加载速度较慢,从而拉低了平均的秒开率。

7、结尾

如今,网易新闻客户端短视频的秒开率已经达到了 94%,卡顿率 1.4%,失败率 0.14%。在这个过程当中有过各类因素的限制,也有过各类意外的发生,可是咱们都一一克服并实现了进一步的提高。咱们的优化虽是从0开始,但还远远没有达到1的程度,所以咱们的优化之路也将仍将继续。2019年,咱们会在优化的道路上继续探索,在咱们力所能及的范围内为用户带来最好的体验。

相关文章
相关标签/搜索