播放器成功率优化丨音视频工业实战

2023-02-14 16:42:03 浏览数 (2)

视频播放器是视频消费链路最核心的组件,针对播放器我们通常最关心的体验有:视频播放是否会出错视频起播速度是否够快视频播放过程中是否会出现卡顿;对于直播场景,我们还会关心:直播的延时是否比较低

这篇文章是音视频工业实战主题专栏中关于视频播放优化的第一篇,我们就从视频播放错误优化开始,来聊一聊视频播放体验优化的各种思路。

在谈优化之前,我们首先需要定义清楚指标:

  • 播放成功率,指的是在一次播放器生命周期中没有出现过错误的播放次数在所有播放次数中的占比。

指标定义好了,接下来我们要搞清楚在视频播放的过程中会经过哪些步骤,这样我们来优化播放成功率时才能有的放矢。

视频播放流程

我们可以看到视频从服务端到播放器播放的过程中会经过网络传输解封装音视频解码音视频同步音视频渲染等阶段,每个阶段遇到了问题都可能造成播放错误,下面我们就按这几个阶段划分来介绍一下相关播放成功率优化的思路:

1、网络传输问题优化

1.1、HTTPDNS

通常我们都是通过 HTTP/HTTPS 协议来请求存储在服务端的视频资源到客户端的播放器来播放的,在这个网络连接建立的过程中会经过 DNS 解析、TCP 建连、HTTP 响应等阶段。

DNS 解析这个阶段一般容易出现以下问题:

  • DNS 劫持问题。DNS 请求被劫持,从而指向错误的 IP 造成访问问题。
  • DNS 解析转发问题。解析转发是指运营商自身不进行域名递归解析,而是把域名解析请求转发到其它运营商的递归 LocalDNS 服务上的行为。这样会导致域名解析请求的来源 IP 就成了其它运营商的 IP,最终导致用户流量被导向了错误的 IDC(Internet Data Center),用户访问变慢或出问题。

为了解决这些问题,在现在的直播和短视频播放场景中,我们通常都会使用 HTTPDNS 替代 LocalDNS,一方面可以避免劫持,一方面也可以做直播和视频打开速度的优化。

HTTPDNS 的稳定性如果有保障,本身就会降低播放错误率。但这里需要注意一般我们通过 HTTPDNS 获取的 IP 地址是会在本地缓存的,如果手机发生网络切换,比如从 WIFI 切成了 4G 网络,这时候本地缓存的 IP 地址可能就不可用了,如果使用旧的 IP 来连接就可能播放报错,这时候要注意刷新 HTTPDNS 的缓存结果。

1.2、网络重连

网络建连的过程除了上面提到的 DNS 解析,还有 TCP 建连、HTTP 响应的过程,这些阶段如果发生网络抖动也会造成连接失败。

网络抖动造成建连失败是影响播放成功率的一种重要原因。通常因为网络原因而引起播放错误时,播放器会上报相应的错误码,这时候我们可以根据这些错误码针对性地对播放器进行刷新、重连来进行播放重试,并设置重试次数限制,通过这样的方式来尝试恢复播放。

网络重连的实现可以是在播放器底层的网络连接相关的模块,也可以是在播放器上层重新刷新整个播放器生命周期来完成。

2、视频格式问题优化

2.1、兼容更多的 Demuxer

有时候播放错误是因为播放器对视频格式支持的不够完善而造成的。由于生产视频的设备各异,也就造成了视频的格式有着不同的标准。视频的格式有很多种,常见的有 MP4、MOV、MKV、AVI 等等,要播放对应格式的视频就需要播放器集成解析该格式的 Demuxer。

如果在你的业务场景就是需要支持各种格式的视频的播放,那么就需要尽量集成各种格式的 Demuxer 来完成对不同格式的解析。通过 FFmpeg 可以比较方便来实现各种 Demuxer 的支持。但是这样一来也会造成客户端播放器包大小大大增加。

2.2、视频格式统一

对于点播视频而言,在允许的情况下,我们应该在服务端来尽量规范视频格式,比如我们可以配合播放器的实现对上传到服务端的视频进行统一的格式转封装,这样可以尽量减少播放器端因为对视频格式支持不够完善而引起播放错误。

此外,对于统一视频格式进行播放成功率的优化,成本会小很多。

而且,少了众多的 Demuxer,客户端的包大小也能减少很多。

3、视频编码问题优化

3.1、兼容更多的编码格式

和视频封装格式一样,视频编码格式也有好几种,比如 H.264、H.265、H.266、VP8、VP9、AV1 等等。此外,音频编码格式也有多种,比如 AAC、MP3、OPUS 等等。

如果在你的业务场景就是需要支持各种类型的视频播放,那就需要集成尽可能多的解码器来实现更好的兼容性,从而减少因为编码格式不支持导致的播放错误。

同样的,集成更多的解码器也会造成客户端播放器包大小大大增加,以及加大对应的维护成本。

3.2、编码格式收敛

在现在大部分的视频播放业务中,我们通常还是会把支持的视频编码和音频编码格式进行收敛,支持有限的几种即可,通常是 H.264、H.265、AAC。

对于不同来源的视频,在服务端对它们进行统一转码到支持的格式。在播放器客户端则只集成对应的解码器进行支持即可。随着视频编码格式统一,以及在服务端统一转码,一般就可以解决大部分视频编码不兼容导致的播放错误问题。

3.3、解码方式兜底

对于视频解码,除了使用软件解码器外,一般设备都会有专用的硬件解码器来支持。

这样一来,对于基于 FFmpeg 实现的播放器,在播放视频时,我们可以选择硬解或者软解的方式来对音视频数据进行解码。

一般而言,软解的稳定性要好于硬解,但是,软解对于 CPU、内存的消耗会更大,所以一般基于性能考虑还是会优先使用硬解。

有时候如果遇到硬解对视频格式支持的不够完善,可能会出现解码出错,这时候我们可以通过上报上来的错误判断是否是解码出错,然后针对性地选择切换到软解方式来尝试恢复播放。这种兜底的方案也可以在一定程度上优化播放成功率。

4、视频同步问题优化

4.1、音视频交错处理

经过了网络传输、音视频解封装、音视频解码,这就来到了音视频同步。

在音视频同步模块也是有可能出现播放错误的,这种情况可能是由于音频和视频的时间戳出现较大的差异,音频或视频单方大段堆积、交错不均匀,导致同步模块异常从而出现播放错误。

要解决音视频同步的问题,通常需要从生产侧来着手,在生产视频的时候就需要尽量对齐音频和视频的时间戳,避免出现跳变,并尽量进行均匀的交错。

5、视频渲染问题优化

5.1、视频色差问题优化

在渲染这个环节,通常容易出问题的是视频的颜色处理。

目前大部分视频使用的颜色空间有:BT.601、BT.709、BT.2020,这里面还有 Limit Range 和 Full Range 的不同,在渲染时则可能涉及到颜色空间的转换,如果相关的转换矩阵参数不对或者没有从视频中获取到正确的颜色空间,在做转换时都可能出问题而最终造成渲染的视频出现色差问题。通常这样的问题不会直接报错造成视频无法播放,但是也会给用户带来异常的播放体验。

要优化这些问题,需要从视频中获取正确的颜色空间信息以及 Limit Range 和 Full Range 类型,并使用正确的转换矩阵来适配渲染支持的颜色格式。

颜色空间是一个比较基础又比较复杂的概念,可以看看颜色空间发展简史,这里我们就不做过多介绍了。

5.2、视频画面角度兼容

有的视频在生产出来的时候,会带一个 rotate 旋转角度,比如下面这个视频:

代码语言:javascript复制
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/test/rotation-90.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2mp41
    encoder         : Lavf58.26.101
  Duration: 00:00:03.33, start: 0.000000, bitrate: 8701 kb/s
    Stream #0:0(und): Video: hevc (Main) (hvc1 / 0x31637668), yuv420p(tv, bt709), 1920x1080, 8690 kb/s, 30 fps, 30 tbr, 19200 tbn, 19200 tbc (default)
    Metadata:
      rotate          : 90
      handler_name    : Core Media Video
    Side data:
      displaymatrix: rotation of -90.00 degrees
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, mono, fltp, 1 kb/s (default)
    Metadata:
      handler_name    : Core Media Audio

在渲染的视频如果没有进行兼容处理,也会导致渲染的画面出现旋转等问题。

解决这样的问题,通常可以在服务端进行统一格式转码时根据 rotate 的参数将视频处理成不带旋转角度的,从而兼容大部分的播放场景。

当然,播放器也可以对 rotate 参数进行兼容,即从视频中获取 rotate 信息,在渲染时对画面进行对应角度的旋转适配。

5.3、视频画面比例兼容

在有些视频中,我们可以看到 PAR、SAR、DAR 等信息,它们的含义如下:

  • PAR(Pixel Aspect Ratio),单个像素的宽高比。大多数情况像素宽高比为 1:1,是一正方形像素。如果不是 1:1,则为长方形像素。常用的 PAR 有:1:1、10:11、40:33、16:11、12:11。
  • SAR(Sample Aspect Ratio),采样纵横比。表示横向的像素点数和纵向的像素点数的比值,即我们通常提到的分辨率的宽高比。比如 VGA 图像 SAR 是 640/480=4:3,D-1 PAL 图像 720/576=5:4 等。
  • DAR(Display Aspect Ratio),显示宽高比。即最终播放出来的画面的宽高比。比如常见的 16:9、4:3 等。缩放视频也要按这个比例来,否则会使图像看起来被拉伸了。

有 PAR、SAR、DAR 信息的原因通常可能是这个视频是用电视制式的设备录制的。我们的视频制式按照录制设备可以分为计算机制式和电视制式。计算机制式的 PAR 常为 1:1,而电视制式的 PAR 通常不是 1:1,电视制式又分为 NTSC 或 PAL 制式,它们的 PAR 又可能不同。

比如下面这个视频:

代码语言:javascript复制
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/Users/samirchen/Desktop/Samples/1080.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.29.100
  Duration: 00:00:13.61, start: 0.000000, bitrate: 5068 kb/s
    Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 4938 kb/s, 25 fps, 25 tbr, 120k tbn, 50 tbc (default)
    Metadata:
      handler_name    : xxx
    Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 126 kb/s (default)
    Metadata:
      handler_name    : xxx
   8.06 A-V: -0.023 fd=   7 aq=   24KB vq=  507KB sq=    0B f=0/0

PAR、SAR DAR 三者的关系是:PAR x SAR = DAR,所以播放器标准的播放流程,应该是先找视频容器格式也就是 container 中的 DAR,按这个比例来显示视频,进行播放;如果没有 DAR 的话,则使用 SAR 进行视频显示。

小结

上面我们从网络传输解封装音视频解码音视频同步音视频渲染等阶段介绍了视频播放可能会遇到的错误以及优化思路,这里的介绍当然并不全面,欢迎大家关注我们,我们后续会持续进行补充和完善。

- 完 -

0 人点赞