首页 关于 微信公众号
欢迎关注我的微信公众号

点播视频格式的选择

视频格式的基本介绍

这两年短视频成了内容创业的风口,各种短视频应用、短视频创作者异军突起,遍地开花,迅速成为各种 App 的重要甚至是主要的内容呈现形式。

短视频是一种点播形式的视频,点播视频的格式有挺多种的,比如:AVI、MKV、RM、FLV、MP4 等等,这些都是指的视频的封装格式。

关于视频的一些基础概念可以看看这篇关于视频的一些概念

在 PC Web 时代,由于 Flash 插件极高的覆盖率,FLV 是使用非常广泛的一种视频格式,被几乎所有的视频网站支持并作为主要的点播视频格式所使用。但是,随着 App 时代的到来以及 H5 的兴起,Flash 插件逐渐被抛弃,同时随着 H.264 编码技术的普及、手机等硬件设备的升级,MP4 逐渐崛起成为了使用较为广泛的点播视频格式。

但是,MP4 也有个问题,它的文件格式比较复杂,所以处理成本较高,而且由于索引表复杂度高,所以通常当视频时长大于 5 分钟时,MP4 文件在线播放时加载速度会比较慢。所以,在长视频场景,通常还会使用苹果公司力推的 HLS 协议:

但是,作为时长通常为一两分钟或者几十秒的短视频场景,MP4 仍然是一个不错的选择。

播放器在网络点播场景下去请求 MP4 视频数据,需要先获取到文件的 moov 信息,解析出该文件的编码、帧率等信息后才能实现边下载数据,边送给解码器进行解码,最后通过渲染层将解码后的数据播放出来。

需要注意的是,我们有时候会遇到所请求的 MP4 短视频播放非常缓慢,这时候你就需要看看这个文件的 moov 数据块是不是被编码在了 MP4 文件尾部,这种情况会导致播放器只有下载完整个文件后才能成功解析并播放这个视频。对于这种视频,我们最好能够在服务端将其重新编码,将 moov 数据块转移到文件头部,保证播放器在线请求时能较快播放。比如 FFmpeg 的下列命令就可以支持这个操作:

ffmpeg -i bad.mp4 -movflags faststart good.mp4

此外,需要注意的是,在通过网络请求 MP4 视频文件进行边下载边播放时,由于接收到的每帧音视频数据是需要根据时间戳来决定何时送入解码器解码,以及何时显示,如果时间没到只能等待。尤其是当视频编码存在 B 帧时,解码时间戳 DTS 与显示时间戳顺序 PTS 通常不一致,这时候就会出现已经下载好的一帧数据可能还不能立即解码和显示,需要等待其依赖的数据下载完成和解码完成。这时在播放的过程中就可能因为网络抖动而出现播放卡顿。

关于音视频时间戳的概念,可以看一下理解音视频 PTS 和 DTS

MP4 格式解析

如上文介绍,MP4 是现在用的比较多的视频封装格式,它为了播放流式媒体的高质量视频而专门设计的,以求使用最少的数据获得最佳的图像质量。但是它的文件格式复杂,索引慢,时长较长的 MP4 视频在线播放时加载较慢。那么它的格式到底有着怎样的特点呢?

MP4 文件的数据都是封装一个又一个的名为 Box 的单元中,一个 MP4 文件由若干个 Box 组成,Box 有不同的类型,Box 中又可以包含其他 Box。

下面的图是对 MP4 文件结构的基本描述:

image

MP4 文件由许多 Box 或 FullBox 组成。其中,每个 Box 包含了 Header 和 Data。FullBox 是 Box 的扩展,其包含的 Header 增加了 version(8bits) 和 flags(24bits) 部分。

Header 部分包含了 size 和 type 部分。size 用于描述整个 Box 的长度,type 用于描述 Box 的类型。当 size 为 0 时,表示这是文件中最后一个 Box;当 size 为 1 时,表示 Box 长度需要更多 bits 来描述,这时在后面会定义一个 64bits 的 largesize 来描述 Box 的长度。当 type 是 uuid 时,代表 Box 中的数据是用户自定义扩展类型。

Data 部分是 Box 的实际数据,可以是纯数据也可以是更多的子 Boxes。

当一个 Box 的 Data 部分是一系列子 Boxes 时,这个 Box 又可称为 Container Box。

由于 MP4 文件的 Box 类型非常多,http://mp4ra.org/atoms.html 列出了当前注册过的一些 Box 类型,这么多的 Box 类型要完全支持还是很复杂的。好在大部分 MP4 文件不会包含这么多的 Box 类型,常见的主要是:ftyp、moov、mdat 三种。

image

关于 MP4 文件格式更加完整的信息参见:MP4 格式文档

操作 MP4 文件

Seek

那么我们如果对 MP4 文件做 Seek 操作呢?步骤如下:

分割 MP4 文件

通过上面对 Seek 操作的介绍,我们不难发现其实我们可以将一个 MP4 文件中的所有关键帧的信息提取出来,也就是获得这个 MP4 文件的「关键帧列表」。在这个基础上我们就可以对 MP4 文件进行分割了,把大文件分割成小文件。这样对于优化 MP4 长视频的网络点播,是一种思路。

分割 MP4 文件的步骤大致如下:

Blog

Opinion

Project