一、flv文件结构

flv文件由flv header 和flv body组成。

二、flv header

Header 部分记录了FLV的类型、版本、流信息、Header 长度等。一般整个Header占用9个字节,大于9个字节则表示头部信息在这基础之上还存在扩展数据。Header 的头部信息排布如下所示:

三、flv body

Body 是由一个个Tag组成的,每个Tag下面有一块4个字节的空间,用来记录这个Tag 的长度。这个后置的PreviousTagSize用于逆向读取处理,表示的是前面的Tag的大小,对于FLV版本0x01来说,数值等于 11 + Tag的DataSize(tag header总是11个字节)。其结构排布如下:

1.tag

每个Tag 也是由两部分组成的:Tag Header 和 Tag Data。Tag Header 存放了当前Tag的类型,数据长度、时间戳、时间戳扩展、StreamsID等信息,然后再接着数据区Tag Data。

2.tag header

tag header的排布如下:

3.tag data

Tag Data分成 Audio,Video,Script 三种。

1)Audio Tag Data

音频的Tag Data又分为 Audio Tag Header 和 Data 数据区,其排布结构如下图所示:

AudioTagHeader通常占用1个字节,AAC编码则会多出一个AACPacketType的字节,用于表示AAC的序列头还是裸数据。
其中,前4bits表示SoundFormat,其数值对应声音格式,如下:
0 - Linear PCM, platform endian
1 - ADPCM
2 - MP3
3 - LinearPCM,little endian
4 - Nellymoser 16-kHz mono
5 - Nellymoser 8-kHZ mono
6 - Nellymoser
7 - G.711 A-law logarithmic PCM
8 - G.711 U-law logarithmic PCM
9 - reserved
10 - AAC
11 - Speex
14 - MP3 8-kHz
15 - Device-specific sound

第5、6bit 表示SoundRate,数值对应采样率,对于AAC来说,总是3:
0 - 5.5kHz
1 - 11kHz
2 - 22kHz
3 - 44kHz

第7bit 表示采样大小:
0 - snd 8 bit
1 - snd 16 bit

第8bit 表示音频声道数,对于AAC来说,总是1:
0 - sndMono
1 - sndStereo

audio Data数据区,根据SoundFormat的数值来确定,如果SoundFormat = 10,则Data数据区是AAC编码部分,其他声音类型,则根据具体格式进行解析。

针对AAC编码,音频Data数据区的定义如下:
AACPacketType = 0 时,表示AAC序列头,也就是AudioSpecificConfig, AACPacketType = 1 时,表示AAC的裸流,也就是AAC Raw frame data。

AudioSpecificConfig 只出现在第一个Audio Tag中,结构如下:

AudioSpecificConfig() {     audioObjectType;                              5bitssamplingFrequencyIndex;                 4bitsif  ( samplingFrequencyIndex == 0xf ) {samplingFrequency;                         24bits}channelConfiguration;                           4bitssbrPresentFlag = -1;if  ( audioObjectType == 5 ) {extensionAudioObjectType = audioObjectType;sbrPresentFlag = 1;extensionSamplingFrequencyIndex;            4bitsif ( extensionSamplingFrequencyIndex == 0xf )  {extensionSamplingFrequency;             24bits}audioObjectType;                            5bits} else {extensionAudioObjectType = 0;}if ( audioObjectType == 1 || audioObjectType == 2 ||audioObjectType == 3 || audioObjectType == 4 ||audioObjectType == 6 || audioObjectType == 7 ) {GASpecificConfig();}if ( audioObjectType == 8 )  {CelpSpecificConfig();}if ( audioObjectType == 9 ) {HvxcSpecificConfig();}if ( audioObjectType == 12 ) {TTSSpecificConfig();}if ( audioObjectType == 13 || audioObjectType == 14 ||audioObjectType == 15 || audioObjectType == 16 ) {StructureAudioSpecificConfig();}if ( audioObjectType == 17 || audioObjectType == 19 ||audioObjectType == 20 || audioObjectType == 21 ||audioObjectType == 22 || audioObjectType == 23 ) {GASpecificConfig();}if ( audioObjectType == 24 ) {ErrorResilientCelpSpecificConfig();}if ( audioObjectType == 25 ) {ErrorResilientHvxcSpecificConfig();}if ( audioObjectType == 26 || audioObjectType == 27 ) {ParametricSpecificConfig();}if ( audioObjectType == 17 || audioObjectType == 19 ||audioObjectType == 20 || audioObjectType == 21 ||audioObjectType == 22 || audioObjectType == 23 ||audioObjectType == 24 || audioObjectType == 25 ||audioObjectType == 26 || audioObjectType == 27 )  {epConfig;                                      2bitsif ( epConfig == 2 || epConfig == 3 ) {ErrorProtectionSpecificConfig();}if ( epConfig == 3 ) {directMapping;                               1bitif ( ! directMapping ) {/* tbd */}}}if ( audioObjectType == 28 ) {SSCSpecificConfig();}if ( extensionAudioObjectType != 5 && bits_to_decode() >= 16 ) { syncExtensionType;                                          11bitsif ( syncExtensionType == 0x2b7 ) {extensionAudioObjectType;                                 5bitsif ( extensionAudioObjectType == 5 ) {sbrPresentFlag;                                        1bitif ( sbrPresentFlag == 1 ) {extensionSamplingFrequencyIndex;                     4bitsif ( extensionSamplingFrequencyIndex == 0xf ) {extensionSamplingFrequency;                      24bits}}}}}
}

AudioSpecificConfig 简化格式如下:

audioObjectType               5bits    编码结构类型,AAC-LC为2
samplingFreguencyIndex        4bits    音频采样率索引值
channelConfiguration          4bits    音频声道数
GASpecificConfigframeLengthFlag           1bits    标志位,用于表明IMDCT窗口长度,为0dependsOnCoreCoder        1bits    标志位,用于表明是否依赖corecoder,为0extensionFlag             1bits    扩展标志位,选择了AAC-LC,这里必须为0

其中,samplingFreguencyIndex 对应关系如下:

0 - 96000
1 - 88200
2 - 64000
3 - 48000
4 - 44100
5 - 32000
6 - 24000
7 - 22050
8 - 16000
9 - 12000
10 - 11025
11 - 8000
12 - 7350
13 - Reserved
14 - Reserved
15 - frequency is written explictly

AAC裸流AAC Raw frame data,即AAC音频原始数据,不包括AAC头数据ADTS。

如果是MP3 编码部分,audio 数据区直接为 MP3 头 + MP3 原始数据。

2)Video Tag Data

Video Tag 由一个字节的Video Tag Header 和 Video数据区部分组成。

Video Tag Header

Video Tag Header通常由一个字节构成,前4bit表示类型,后4bit表示编码器Id。

Video Tag Data

Video数据区部分格式不确定。对于H264/AVC编码部分,Video数据区排布如下:

其中,AVCsequenceheader只有出现在第一个Video Tag,只有一个。为了能够从FLV中获取NALU,必须知道前面的NALU长度所占的字节数,通常是1、2、4个字节,这个内容则必须从AVCDecoderConfigurationRecord中获取,这个遵从标准ISO/IEC 14496-15的5.2.4小节。AVCDecoderConfigurationRecord 的结构如下:

aligned(8) class AVCDecoderConfigurationRecord {unsigned int(8) configurationVersion = 1;  //版本号unsigned int(8) AVCProfileIndication;     //sps[1],即0x67后面那个字节unsigned int(8) profile_compatibility;     //sps[2]unsigned int(8) AVCLevelIndication;      //sps[3]bit(6) reserved = '111111'b;unsigned int(2) lengthSizeMinusOne;     //NALUnitLength的长度减1,一般为3  bit(3) reserved = '111'b;unsigned int(5) numOfSequenceParameterSets;    //sps个数,一般为1for ( i=0; i<numOfSequenceParameterSets; i++ ) {unsigned int(16) sequenceParameterSetLength;  //sps的长度      bit(8*sequenceParameterSetLength) sequenceParameterSetNALUnit;}unsigned int(8) numOfPictureParameterSets;      //pps个数,一般为1for ( i=0; i<numOfPictureParameterSets; i++) {unsigned int(16) pictureParameterSetLength;   //pps长度   bit(8*pictureParameterSetLength) pictureParameterSetNALUnit;}
}

其中,lengthSizeMinusOne + 1 = NALU长度字段所占字节数。

3)Script Tag Data

当TagType = 0x12时, 这个Tag就是Script tag。Script Tag一般只有一个,是FLV文件的第一个Tag,用于存放FLV文件信息,比如时长、分辨率、音频采样率等。所有的数据都是以数据类型 + (数据长度) + 数据格式出现,数据类型占1个字节,数据长度看数据类型是否存在,后面才是数据。数据排布如下:

其中SCRIPTDATAOBJECTEND和SCRIPTDATAVARIABLEEND为0x000009,用于标记对象和数组类型的结尾。

SCRIPTDATASTRING结构为:

StringLength    2bytes
StringData      String

SCRIPTDATALONGSTRING结构为:

StringLength  4bytes
StringData    String

ECMA array type结构为:

ECMAArrayLength   4bytes
StringLength      2bytes
StringData        String
DataType          1byte
Data              不定长
SCRIPTDATAVARIABLEEND

Object type结构为:

StringLength  2bytes
StringData    String
DataType      1byte
DataVale      不定长
SCRIPTDATAOBJECTEND  

Strict array type结构为:

ArrayNum    4bytes
DataType    byte
DataValue   不定长

如果类型为String,后面的2bytes为字符串的长度(Long String是4bytes),再后面才是字符串数据;如果是Number类型,后面的8bytes为Double类型的数据;Boolean类型,后面1byte为Bool类型。

知道了这些后再来看看flv中的脚本,一般开头是0x02,表示String类型,后面的2bytes为字符串长度,一般是0x000a(“onMetaData”的长度),再后面就是字符串“onMetaData”。好像flv格式的文件都有onMetaData标记,在运行ActionScript的时候会用到它。后面跟的是0x08,表示ECMA Array类型,这个和Map比较相似,一个键跟着一个值。键都是String类型的,所以开头的0x02被省略了,直接跟着的是字符串的长度,然后是字符串,再是值的类型,也就是上面介绍的那些了。

onMetaData标签中包含的是流的信息,一般的信息包括:

43.FFmpeg学习笔记 - flv格式解析相关推荐

  1. 音视频学习(四、FLV格式解析)

    由于上一节使用到了rtmp推流,然后一直推一直出错,用rtmp推流的数据格式是FLV,所以这一节分析一下FLV的格式,补充补充知识. 4.1 FLV格式解析 4.1.1 FLV总体认识 FLV 是FL ...

  2. 音视频 FLV格式解析

    前言 本文介绍FLV封装格式,直播场景下拉流比较常见的是http-flv直播流,具有延时低.易传输等特点. 格式概览 总体上看,FLV包括文件头(File Header)和文件体(File Body) ...

  3. <四>关于flv格式解析

    关于ffmpeg这里插入一个章节-----关于flv格式的解析,因为在ffmpeg推流的过程中,最流行的就是将数据封装成flv格式,通过rtmp传输,所以搞明白flv的格式构成是十分有必要的,我可能会 ...

  4. FFmpeg学习笔记汇总

    第1章 FFmpeg简介 1.1 FFmpeg定义 FFmpeg既是一款音视频编解码工具,同时也是一组音视频编解码开发套件,作为编解码开发套件,它为开发者提供了丰富的音视频处理的调用接口. FFmpe ...

  5. Python3 爬虫学习笔记 C08【解析库 Beautiful Soup】

    Python3 爬虫学习笔记第八章 -- [解析库 Beautiful Soup] 文章目录 [8.1]关于 Beautiful Soup [8.2]Beautiful Soup 的基本使用 [8.3 ...

  6. Python3 爬虫学习笔记 C07 【解析库 lxml】

    Python3 爬虫学习笔记第七章 -- [解析库 lxml] 文章目录 [7.1]关于 lxml [7.2]使用 XPath [7.3]查找所有节点 [7.4]查找子节点 [7.5]查找父节点 [7 ...

  7. 安卓学习笔记30:解析XML与JSON

    文章目录 零.学习目标 一.解析XML (一)XML概述 (二)解析XML的方法 二.案例演示 - 读取解析XML (一)运行效果 (二)涉及知识点 (三)实现步骤 1.创建安卓应用[ReadPars ...

  8. CanOpen协议栈学习笔记1-帧格式,SYNC和NMT报文介绍

    前面已经记录过can协议,后面开始CanOpen协议栈学习.其实协议栈代码已经看过了,而且已经在开发板上跑过了.这里回过头来,重新看下之前遇到的坑,记录下学习笔记.下面均以标准帧为例 文章目录 1.C ...

  9. CoAP学习笔记——CoAP格式详解

    0 前言 CoAP是受限制的应用协议(Constrained Application Protocol)的代名词.在当前由PC机组成的世界,信息交换是通过TCP和应用层协议HTTP实现的.但是对于小型 ...

最新文章

  1. Java类加载机制详解【java面试题】
  2. 电容触摸屏GT911、GT928、GT9147的使用
  3. Visual Tracking:运行ECO模型的GPU版本
  4. Android开发中常见的设计模式
  5. Linux学习笔记-文件压缩与解压缩
  6. 微信10个实用技巧,值得收藏!
  7. mysql 不要统计null_浅谈为什么Mysql数据库尽量避免NULL
  8. 串口发送图片VGA显示
  9. 常用的限流框架都在这里了!
  10. 莫烦 Tensorflow
  11. wps纸张大小设置成A4_pdf两页合并一页a4,只需这招轻松搞定
  12. WMI服务是什么?Windows 7系统如何禁用WMI服务?
  13. powershell为所有用户卸载磁贴应用
  14. 网站建设:网站安全检测工具
  15. Qt Creator-设置代码的背景色和字体
  16. 最小值c语言编写自定义函数,C语言笔记55:自定义函数[老九学堂]
  17. jQuery打字练习小游戏代码带音效
  18. 从数据架构看生鲜电商的数据价值
  19. 计算机网络的产生与发展
  20. NTU-Coursera机器学习:VC Bound和VC维度

热门文章

  1. 面向对象:11、abstract关键字
  2. php添加一维数组,PHP将多维数组数组键附加到一维数组
  3. 猪的一生应当这样度过
  4. 404 bad request
  5. 6月5日,刘德华一行来到日本,举办了小型歌友会。
  6. 如果只让我推荐一本书。
  7. C语言程序设计 | 通讯录管理系统
  8. C盘空间不足如何清理以及磁盘重新分区 分区助手
  9. 移动支付新战场,App安全是最有力的武器
  10. python中wraps_python装饰器函数wraps