FLV文件主要由两部分组成:header和body。

1.header

header部分记录了flv的类型、版本等信息,是flv的开头,一般都差不多,占9bytes。具体格式如下:

文件类型 3 bytes “FLV”
版本 1 byte 一般为0x01
流信息 1 byte 倒数第一位是1表示有视频,倒数第三位是1表示有音频,倒数第二、四位必须为0
header长度 4 bytes 整个header的长度,一般为9;大于9表示下面还有扩展信息

2.body

body部分由一个个Tag组成,每个Tag的下面有一块4bytes的空间,用来记录这个tag的长度,这个后置用于逆向读取处理,他们的关系如下图:

2.1.Tag

每个Tag由也是由两部分组成的:Tag Header和Tag Data。Tag Header里存放的是当前Tag的类型、数据区(Tag Data)长度等信息,具体如下:

名称 长度 介绍
Tag类型 1 bytes 8:音频
9:视频
18:脚本
其他:保留
数据区长度 3 bytes 在数据区的长度
时间戳 3 bytes 整数,单位是毫秒。对于脚本型的tag总是0
时间戳扩展 1 bytes 将时间戳扩展为4bytes,代表高8位。很少用到
StreamsID 3 bytes 总是0
数据区(data) 由数据区长度决定 数据实体

2.2.Tag Data

数据区根据Tag类型的不同可分为三种,音频数据、视频数据和脚本数据。

2.2.1.音频数据

第一个byte是音频的信息,格式如下。

名称 长度 介绍
音频格式 4 bits 0 = Linear PCM, platform endian
1 = ADPCM
2 = MP3
3 = Linear PCM, little endian
4 = Nellymoser 16-kHz mono
5 = Nellymoser 8-kHz mono
6 = Nellymoser
7 = G.711 A-law logarithmic PCM
8 = G.711 mu-law logarithmic PCM
9 = reserved
10 = AAC
11 = Speex
14 = MP3 8-Khz
15 = Device-specific sound
采样率 2 bits 0 = 5.5-kHz
1 = 11-kHz
2 = 22-kHz
3 = 44-kHz
对于AAC总是3
采样的长度 1 bit 0 = snd8Bit
1 = snd16Bit
压缩过的音频都是16bit
音频类型 1 bit 0 = sndMono
1 = sndStereo
对于AAC总是1

SoundData

UI8[size of sound data]

if SoundFormat == 10

AACAUDIODATA

else

Sound data—varies by format

第2byte开始就是音频流数据了。

AACAUDIODATA

AAC sequence header存放的是AudioSpecificConfig结构,该结构则在“ISO-14496-3 Audio”中描述。AudioSpecificConfig结构的描述非常复杂,这里我做一下简化,事先设定要将要编码的音频格式,其中,选择"AAC-LC"为音频编码,音频采样率为44100,于是AudioSpecificConfig简化为下表:

举例

下面蓝色的为AudioSpecificConfig部分:

000001e0h: 00 00 00 00 00 AF 0011 90 00 00 00 0F 09 00 02; .....?.?......

根据AudioSpecificConfig结构的定义:

  • audioObjectType = (0x11 & 0xF8) >> 3 <- 取前5bit,结果为2
  • samplingFrequencyIndex = ((0x11 & 0x7) << 1) | (0x90 >> 7)<- 取后4bit,结果为3
  • channelConfiguration = (0x90 >> 3) & 0x0F <- 取后4bit,结果为2
  • frameLengthFlag = (0x90 >> 2) & 0x01<- 取后1bit,结果为0
  • dependsOnCoreCoder = (0x90 >> 1) & 0x01 <- 取后1bit,结果为0
  • extensionFlag = 0x90 & 0x01 <- 最后1bit,结果始终为0

AudioSpecificConfig部分参数含义见:

https://wiki.multimedia.cx/index.php?title=MPEG-4_Audio

2.2.2.视频数据

和音频数据一样,第一个byte是视频信息,格式如下:

名称 长度 介绍
帧类型 4 bits 1: keyframe (for AVC, a seekable frame)
2: inter frame (for AVC, a non-seekable frame)
3: disposable inter frame (H.263 only)
4: generated keyframe (reserved for server use only)
5: video info/command frame
编码ID 4 bits 1: JPEG (currently unused)
2: Sorenson H.263
3: Screen video
4: On2 VP6
5: On2 VP6 with alpha channel
6: Screen video version 2
7: AVC

VideoData

If CodecID == 2

H263VIDEOPACKET

If CodecID == 3

SCREENVIDEOPACKET

If CodecID == 4

VP6FLVVIDEOPACKET

If CodecID == 5

VP6FLVALPHAVIDEOPACKET

If CodecID == 6

SCREENV2VIDEOPACKET

if CodecID == 7

AVCVIDEOPACKET

AVCVIDEOPACKET

AVCDecoderConfigurationRecord

AVC sequence header就是AVCDecoderConfigurationRecord结构,该结构在标准文档“ISO-14496-15 AVC file format”中有详细说明。

举例

上图并非自己画的,因此遗漏了sequenceParameterSetLength,pictureParameterSetLength

下面蓝色的部分就是 FLV 文件中的 AVCDecoderConfigurationRecord 部分:

00000130h: 00 00 00 17 00 00 00 00 01 4D 40 15 FF E1 00 0A ; .........M@.?. 
00000140h: 67 4D 40 15 96 53 01 00 4A 20 01 00 05 68 E9 23 ; gM@.朣..J ...h? 
00000150h: 88 00 00 00 00 2A 08 00 00 52 00 00 00 00 00 00 ; ?...*...R......

根据 AVCDecoderConfigurationRecord 结构的定义:

  • configurationVersion = 01
  • AVCProfileIndication = 4D
  • profile_compatibility = 40
  • AVCLevelIndication = 15
  • lengthSizeMinusOne = FF <- 非常重要,是 H.264 视频中 NALU 的长度,计算方法是 1 + (lengthSizeMinusOne & 3),实际计算结果一直是4
  • numOfSequenceParameterSets = E1 <- SPS 的个数,计算方法是 numOfSequenceParameterSets & 0x1F,实际计算结果一直为1
  • sequenceParameterSetLength = 00 0A <- SPS 的长度
  • sequenceParameterSetNALUnits = 67 4D 40 15 96 53 01 00 4A 20 <- SPS
  • numOfPictureParameterSets = 01 <- PPS 的个数,一直为1
  • pictureParameterSetLength = 00 05 <- PPS 的长度
  • pictureParameterSetNALUnits = 68 E9 23 88 00 <- PPS

2.2.3脚本数据

该类型Tag又通常被称为Metadata Tag,会放一些关于FLV视频和音频的元数据信息如:duration、width、height等。通常该类型Tag会跟在File Header后面作为第一个Tag出现,而且只有一个。结构如图5所示。

图5.Script Tag Data结构

第一个AMF包:

第1个字节表示AMF包类型,一般总是0x02,表示字符串。第2-3个字节为UI16类型值,标识字符串的长度,一般总是0x000A(“onMetaData”长度)。后面字节为具体的字符串,一般总为“onMetaData”(6F,6E,4D,65,74,61,44,61,74,61)。

第二个AMF包:

第1个字节表示AMF包类型,一般总是0x08,表示数组。第2-5个字节为UI32类型值,表示数组元素的个数。后面即为各数组元素的封装,数组元素为元素名称和值组成的对。常见的数组元素如表7所示。

脚本Tag一般只有一个,是flv的第一个Tag,用于存放flv的信息,比如duration、audiodatarate、creator、width等。

首先介绍下脚本的数据类型。所有数据都是以数据类型+(数据长度)+数据的格式出现的,数据类型占1byte,数据长度看数据类型是否存在,后面才是数据。
其中数据类型的种类有:

  • 0 = Number type
  • 1 = Boolean type
  • 2 = String type
  • 3 = Object type
  • 4 = MovieClip type
  • 5 = Null type
  • 6 = Undefined type
  • 7 = Reference type
  • 8 = ECMA array type
  • 10 = Strict array type
  • 11 = Date type
  • 12 = Long string type

如果类型为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被省略了,直接跟着的是字符串的长度,然后是字符串,再是值的类型,也就是上面介绍的那些了。

FLV文件格式官方规范详解相关推荐

  1. rtmp官方协议详解

    标准规范学习: rtmp消息结构,包括几个部分: 时戳:4  byte,单位毫秒.超过最大值后会翻转. 长度:消息负载的长度. 类型ID:Type Id 一部分ID范围用于rtmp的控制信令.还有一部 ...

  2. USB Type C规范详解

    USB Type C规范详解 目前USB Type C接口应用非常广泛,可以传输DP,USB,PCIE,音频等信号,已经不是纯粹的用来传输USB信号了,即USB Type C摆脱了和USB的从属关系, ...

  3. java 注释 超链接_java_Java代码注释规范详解,代码附有注释对程序开发者来 - phpStudy...

    Java代码注释规范详解 代码附有注释对程序开发者来说非常重要,随着技术的发展,在项目开发过程中,必须要求程序员写好代码注释,这样有利于代码后续的编写和使用. 基本的要求: 1.注释形式统一 在整个应 ...

  4. php psr2规范,php标准规范详解

    本文主要和大家分享php标准规范详解,希望能帮助到大家. psr0:自动加载标准已经被 psr4 替代,可以了解下 1. 强制:完全限定命名空间和类的格式:\\(\)* 2. 强制:每个命名空间必须有 ...

  5. flv.js php,flv.js的使用详解

    这次给大家带来flv.js的使用详解,使用flv.js的注意事项有哪些,下面就是实战案例,一起来看一下. Bilibili相信大家都不会陌生,而 Flv.js 就是由 bilibili 网站开源的 H ...

  6. wav文件格式分析与详解

    wav文件格式分析与详解 WAV文件是在PC机平台上很常见的.最经典的多媒体音频文件,最早于1991年8月出现在Windows 3.1操作系统上,文件扩展名为WAV,是WaveFom的简写,也称为波形 ...

  7. Power BI 之 DAX语法规范详解1

    文章预览: Power BI 之 DAX语法规范详解 1 前言 表构造函数{()} Lookupvalue函数 Related函数: Relatedtable函数 筛选引擎Calculate 单条件筛 ...

  8. 银联8583报文规范详解

    银联8583报文规范详解 自己的理解 转载的内容 自己的理解 转载的内容 以下来自转载地址 https://www.jianshu.com/p/203ed7f632cf 一.什么是8583报文规范? ...

  9. 认识ps基本功能和代码规范详解

    11.19认识ps基本功能和代码规范详解 在学习ps中需基本熟悉ps快捷键,快捷键能大大提高我们工作的效率,节省时间.在我们常用的ps快捷键有 新建图形文件:Ctrl + N 新建图层:Ctrl + ...

  10. 音视频编解码 文件格式 协议内容详解

    编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间.尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析.应用开发.释放license收费等等 ...

最新文章

  1. 什么是自组织特征映射网络?
  2. Linux操作系统下双网卡路由表配置
  3. python基础 dict和set
  4. CSS3的几个变形案例……
  5. local variable 'xxx' referenced before assignment
  6. camera(24)---camera 客观测试 Imatest教程--噪声测试
  7. Gartner:2020年数据与分析领域的十大技术趋势
  8. 日历php 价格 库存,jQuery web 组件 后台日历价格、库存设置的代码
  9. 防止IE不支持console.log报错
  10. Java多线程编程(3)--线程安全性
  11. python机器学习案例系列教程——模型评估总结
  12. java se面试题_Java SE 8面试问答(第1部分)
  13. 人力资源管理系统详细设计说明书
  14. 通过TXT文件批量制作ITF-14条码
  15. oracle报无效数字解决笔记
  16. 金蝶设置盘盈盘亏单据权限
  17. 坚果的2022年终总结
  18. Github标签管理
  19. html css before,详解 CSS 属性 - :before :after
  20. matlab分析数据 楼层对房价的影响

热门文章

  1. JDK 8和Java 8的下载与安装
  2. 配音鸭 是什么 从哪儿进入 如何使用 手把手指南来了
  3. 新装的台式机新装WIN7系统启动时卡在开机动画如何解决?
  4. 基于Vue结合高德地图api做的一个坐标拾取组件
  5. Oracle 10g 安装教程
  6. mysql中计算月份函数_MySQL几个计算时间的函数汇总
  7. MATLAB 积分 上限为变量,matlab 求定积分,积分的上限是变量,函数带有其他参数
  8. java 包导入快捷键_Java导入包的快捷键
  9. OCR图像识别与汽车后市场
  10. 线程池(python)