详解视频封装格式之FLV

        在我之前的一篇文章(什么是视频封装格式和编码格式)中有整理了一下常见的视频封装格式,在这篇文章中,我们重点剖析一下FLV这种视频封装格式的具体情况。

一、FLV 的总体结构

        FLV 是一种非常常见的音视频封装,尤其是在流媒体场景中经常用到。FLV 封装是由一个个 Tag 组成的。Tag 又分为视频 Tag、音频 Tag 和 Script Tag,分别用来存放视频数据、音频数据和 MetaData 数据。

        下图是FLV 的总体结构图:

        其总体格式如下:

 二、FLV Header

        FLV Header 占用 9 个字节。前 3 个字节是文件的标识,固定是 FLV。之后的 1 个字节表示版本。在之后的 1 个字节中的第 6 位表示是否存在音频数据,第 8 位表示是否存在视频数据,其他位都为 0。最后的 4 个字节表示从文件开头到 FLV Body 开始的长度,一般就是等于 9。

三、FLV Body

        在 FLV Header 之后就是 FLV Body 了,这就是存放主要数据的地方,放置着一个个 Tag。在每一个 Tag 前面都有一个 4 字节的 Previous Tag Size,表示前一个 Tag 的大小,方便往回倒。再之后就是具体的 Tag 了。Tag 又是由 Tag Header 和 Tag Data 组成,其中 Tag Header 占用 11 个字节。

        其中最重要的是时间戳,因为播放的速度还有音视频同步都需要依赖这个时间戳的值。时间戳占用 3~4 字节,如果 3 字节不够的话,则需要使用 1 字节的扩展时间戳作为时间戳的高 8 位。还需要注意的一个点就是,时间戳的单位是 ms。RTP 的时间戳单位是 1/90000 秒,MP4 的时间戳是可以自定义的。这个时间戳的单位也是至关重要的。

        接下来就是 Tag Data 数据了。Tag Data 有 Script、音频和视频。首先来看一下 Script Tag 的 Data。这个 Tag 存放的是 MetaData 数据,主要包括宽、高、时长、采样率等基础信息。

        Script Data 使用 2 个 AMF 包来存放信息。第一个 AMF 包是 onMetaData 包。第 1 个字节表示的是 AMF 包的类型,一般是字符串类型,值是 0x02,之后是 2 字节的长度,一般长度总是 10,值是 0x000A。之后就是 10 字节长度字符串了,值是 onMetaData。

        第二个 AMF 包的第一个字节是数组类型,值是 0x08,紧接着 4 个字节为数组元素的个数。后面即为各数组元素的封装,数组元素为元素名称和值组成的对。常见的数组元素如下表所示:

         音频 Tag Data 的第一个字节表示音频的编码方式、采样率和位宽等信息,如下图所示。之后就是音频数据了。

         视频 Tag 的第 1 个字节包含了这个 Tag 的视频帧类型和视频编码方式,格式如下图:

        对于 H264 数据,紧接着会有 4 字节的 AVC Packet Type 格式,如下图所示:

        其中最重要的就是 CTS。这个是什么意思呢?这是因为 H264 有 B 帧这种类型,涉及到显示时间戳 PTS 和解码时间戳 DTS。前面 Tag Header 里的时间戳就是 DTS,PTS 等于 DTS + CTS,这个需要注意一下。接下来就是存放具体的视频数据。

        如果 AVC 包类型是 0,则数据格式如下图所示:

        如果 AVC 包类型为 1,则数据格式如下图所示: 

        以上便是对于FLV 封装的详解。

猜你喜欢

转载自blog.csdn.net/weekend_y45/article/details/125400311