FLV 文件格式分析

前言

flv 是 flash video 的缩写,是 Adobe Flash payler 支持的一种流媒体播放格式。flv 是一种层级格式,除了一个 flv header 外,剩下全是由 一个个 tag 组成。tag 是由 tag 头和 tag 数据组成。tag 类型分为音频、视频、脚本,一共三种类型。每一种数据类型又有自己的 tag 头。本文下来就简单分析一下 flv 文件格式。

FLV 文件头格式

FLV 文件格式分析_第1张图片

FLV 文件有 9 个字节的文件头,文件以 3 字节签名 0x46、0x4C、0x 56 开始,分别是 ‘F’、’L’、’V’ 三个字母的 ascii 编码。版本号是 1。文件头中还有 flag 标记,表面是否有音频、视频 tag。

下来以音频、视频为例,分析一下 FLV 格式的 header、tag。

音频 tag 格式

FLV 文件格式分析_第2张图片

如上图,除了 9 字节的公共文件头外,body 部分就是一个个 tag 组成的。每一个 tag 都有 15 字节的 tag 头。字段说明如下:

  • PreviousTagSize,是 4 字节长度,表面之前的 Tag 的长度,包含了 tag 头和 tag 数据。第一个 tag ,此值是 0。
  • TagType,是 1 字节长度。音频:8, 视频:9
  • DataSize , 是 3 字节长。flv tag 的数据长度,其实如图里 audio tag 头及其数据长度。
  • Timestamp,是 3 字节长。时间戳,貌似 flv 播放需要。
  • TimestampExtended, 是对 Timestamp 长度的扩展,当时间长度 3 字节不能表示的时候,启用扩展字段。
  • StreamID ,3 字节长,都填 0.

flv tag 的 body 部分其实就是音频的 tag 部分了,图中每一个字段都有简单说明。具体每一个参数都有很多取值,取值的详细说明参考 [1] 中标明的 flv 规范音频 tag 部分。

对于 AACPacketType = 0 的情况,音频数据是 AudioSpecificConfig 格式,此格式在 ISO/IEC 14496-3 2009 中第一,可惜下载不到此文档。可以参考 wiki 给的格式:

Audio Specific Config:

5 bits: object type
if (object type == 31)
    6 bits + 32: object type
4 bits: frequency index
if (frequency index == 15)
    24 bits: frequency
4 bits: channel configuration
var bits: AOT Specific Config

如果是 AACPacketType = 1 的情况,那么后续数据都是 AAC 格式了。

视频 tag 格式

FLV 文件格式分析_第3张图片

视频 tag 格式和音频格式 flv 文件头、flv tag 头都相同,不再说明。video tag 也不再详细说明,可以参考 [1] 中标明的 flv 规范视频 tag 部分。

这里需要说明一下的是,当 flv 包含的是 h264 的时候,CodecID 值是 7。在 H264 视频流开始的第一个 NALU 数据,需要发送 SPS、PPS 类型的数据。此时,AVCPacketType 会填 0,SPS/PPS 是包含在 AVCDecoderConfigurationRecord 结构中,格式如下:

aligned(8) class AVCDecoderConfigurationRecord {
  unsigned int(8) configurationVersion = 1;
  unsigned int(8) AVCProfileIndication;
  unsigned int(8) profile_compatibility;
  unsigned int(8) AVCLevelIndication;
  bit(6) reserved = ‘111111’b;
  unsigned int(2) lengthSizeMinusOne;
  bit(3) reserved = ‘111’b;
  unsigned int(5) numOfSequenceParameterSets;// SPS 个数
  for (i=0; i< numOfSequenceParameterSets; i++) {
    unsigned int(16) sequenceParameterSetLength ;// SPS 字节长度
    bit(8*sequenceParameterSetLength) sequenceParameterSetNALUnit;
  }
  unsigned int(8) numOfPictureParameterSets;
  for (i=0; i< numOfPictureParameterSets; i++) {
    unsigned int(16) pictureParameterSetLength;// PPS 自己长度
    bit(8*pictureParameterSetLength) pictureParameterSetNALUnit; // PPS bit 流
  }
  if( profile_idc == 100 || profile_idc == 110 ||
  profile_idc == 122 || profile_idc == 144 )
  {
    bit(6) reserved = ‘111111’b;
    unsigned int(2) chroma_format;
    bit(5) reserved = ‘11111’b;
    unsigned int(3) bit_depth_luma_minus8;
    bit(5) reserved = ‘11111’b;
    unsigned int(3) bit_depth_chroma_minus8;
    unsigned int(8) numOfSequenceParameterSetExt;
    for (i=0; i< numOfSequenceParameterSetExt; i++) {
      unsigned int(16) sequenceParameterSetExtLength;
      bit(8*sequenceParameterSetExtLength) sequenceParameterSetExtNALUnit;
    }
  }
}

关于此格式,详细参考 H.264-AVC-ISO_IEC_14496-15 5.2.4.1 节。

如果是后续的视频图像 slice ,那么 AVCPacketType 都会设置为 1。

总结

本文我们描述了 flv 文件头格式,AAC 和 AVC 的 flv tag。如果以 flv 格式推送 rtmp 流,AAC 和 AVC 都要加上 audio tag 和 video tag,但是图中标明的FLV TAG 头没有包含。

本文算是 flv 格式学习的笔记、总结吧。flv 格式虽然结构简单,但是也有很多字段,每一个字段取值也有很多,这些细节需要参考具体的规范。

你可能感兴趣的:(rtmp,rtmp)