筑龙网下载的文件格式是php_FLV 文件格式分析

前言

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

FLV 文件头格式

80d9cdd1284c9c9ad93d822eaf0faa96.png

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

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

音频 tag 格式

92c356fd2b7e19c060e273568db86ed4.png

如上图,除了 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 格式

4de4a01e90e2ec231e827af2fc2beb13.png

视频 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 格式虽然结构简单,但是也有很多字段,每一个字段取值也有很多,这些细节需要参考具体的规范。

如果想结合具体 flv 文件,学习 flv 格式,那么可以参考[2]中提到的文章,作者分析的非常详细。

参考

[1] https://www.adobe.com/content/dam/acom/en/devnet/flv/video_file_format_spec_v10.pdf

[2] https://www.cnblogs.com/lidabo/p/9018548.html

[3] https://wiki.multimedia.cx/index.php/MPEG-4_Audio

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值