当前位置:网站首页>flv文件结构解析
flv文件结构解析
2022-08-02 03:34:00 【刚入视频监控行业的菜鸡】
FLV文件格式相对于MP4,简单很多。
FLV Header(9Bytes) + FLV Bodya比特: 1:有音频; 0:无音频 v比特: 1:有视频; 0:无视频 如果音视频都有这个字节为0x05‘F’|‘L’|‘V’|0x01|0b00000a0v| 0x00 00 00 09|
| |
版本字节一般为0x01 头长度 固定为9FLV Body由一系列的Tag组成,每个tag的结构如下:
{ 0x00000000| tag_header0| tag_data0 } | {tag_size0| tag_header1 | tag_data1 } | {tag_size1| tag_header2 | tag_data2 } |…
tag_size(n) = tag_data_size(n-1) + 11
解析完一个tag后,读取下4个字节,可以比较下看是不是前帧完全解码完毕。
除了可以验证码流外,还有什么样的好处促使FLV格式采用这种方式呢?不太清楚。0x00000000| { tag_header0| tag_data0 | tag_size0} | { tag_header1 | tag_data1 | tag_size1} |... Tag body也可以这样看,编码时按照: 数据头 数据体 数据大小 三部分来划分,更适合一些。下面各个tag都是按照这个结构来写的。Tag header 11Bytes
|1Byte Tag类型 | 只支持3类, 0x08音频; 0x09视频;0x12脚本
|3Byte data_size数据区长度 | 纯数据长度,不包括头信息的15字节
|3Byte timestamp 时间戳 | 最终的时间戳 = (timestamp_ex<< 24) | timestamp
|1Byte timestamp_ex扩展时间戳 | 最终时间戳的高8位。不知道为什么定义成这样,可能是因为标准扩展
|3Byte StreamID | 总为0Tag Data data_size字节
|Tag数据段,长度为data_size… | 音视频或者脚本数据。
|4Byte PreviousTagSize | 是前一个Tag数据长度,第一个Tag此数据段为0.视频Tag
视频数据的第一个字节定义视频信息:
高4比特定义帧格式:1 关键帧; 2 内部帧(非IDR帧);3可丢弃内部帧(仅对H.263有用)
低4比特定义编码器:2:H.263, 4: VP6, 7:H264; …
对于264的视频FLV,这个字节一般为 0x17或者0x27.音频tag
音频数据的第一个字节定义视频信息:
高4比特定义音频编码格式:0 Linear PCM, 1: ADPCM, 2: MP3, 10:AAC …
第4,3两比特定义采样率: 0 5.5KHz, 1 11KHz, 2 22KHz, 3 44KHz. 对于AAC该值总为3
第2比特定义采样大小: 0 8比特,1 16比特
第1比特定义声道数: 0 单声道,1 立体声脚本tag
理论上不需要解析脚本Tag就可以解码FLV文件,它只是提供了一些信息记录。
脚本Tag里面的类型比较多,格式也不一样。
Number 类,记录一个8字节double数据。|0x00|8字节data|.
Boolean类,记录一个1字节布尔型数据。|0x01|1字节data|.
String类,记录一个变长字符串数据。 |0x02|2字节 字符串长度 N| N字节字符串内容|.
注意读取完字符串后加一个’\0’字符串结束符号。因此字符串申请的时候,长度为N+1.
ECMA array type, 记录一些数据对。|0x08| 4字节 数组长度 N|2字节 字符串长度 m1 | m1字节字符串内容|1字节 data1 type | X字节 data1 | ... |2字节 字符串长度 Nm| Nm字节字符串内容|1字节 dataN type| X字节 dataN| 有N个数据对 元素名 (长度|数据) 元素值(类型|数据) 一般用这个记录一些音视频信息,例如: 0x0008 "duration" 0x00 8字节double 0x0005 "width" 0x00 8字节double 0x0006 "stereo" 0x01 1字节boolean型Strict array type类,记录一组数据。
|0x0A|4字节 数组长度 N| 1字节 data1 type| X字节 data1 | …
|1字节 dataN type| X字节 dataN|
有N个数据, 每个数据的类型 数据值
一般会用这个类记录关键帧的偏移地址和对应的pts值。类型都是 Number类,即X=8字节double型
Object type, 记录对象数据。一般用它来做keyframes的数据存储起始。
5.keyframes字段
FLV没有像mp4一样定义stbl,FLV文件如果做快进,seek等操作会比较麻烦。
业内通用做法是在脚本Tag里面增加keyfrmes object类。一般定义为:
|00 09| 9字节 “keyframes”|00 0D| 13字节 “filepositions”|0A| 4字节关键字数目 N|00|8字节 关键帧1偏移地址| …
|00|8字节 关键帧N偏移地址|
|00 05| 5字节 “times” |0A| 4字节关键字数目 N|00|8字节 关键帧1时间| …
|00|8字节 关键帧N时间|
有了各个关键帧的偏移地址和时间,做Seek操作的时候就方便的多。
读取8字节double型,这个牵扯浮点型的存储结构问题,蛮罗嗦,没看明白,但找到下面一段代码可以实现转换。
uint64_t v = get_8bytes();
if(v+v > 0xFFEULL<<52) return 0.0/0.0;
double x = ldexp(((v&((1LL<<52)-1)) + (1LL<<52)) * (v>>63|1), (v>>52&0x7FF)-1075);FLV结构里面,数据长度有3字节和4字节限制,不会像Mp4一样出现8字节长度。
3字节最大表示16M数据,4字节最大是4G数据。
一个Video Tag里面的NALU长度不能超过16M字节。
边栏推荐
- Process (in): process state, process address space
- Compatible with C51 and STM32 Keil5 installation method
- Altium Designer基础知识
- STM32 CAN 介绍以及相关配置
- 逆序对数量与归并排序
- 2020 - AAAI - Image Inpainting论文导读《Learning to Incorporate Structure Knowledge for Image Inpainting》
- 剑指Offer 31.栈的压入、弹出
- 所有子字符串中的元音 —— LeetCode - 2063
- 剑指Offer 32.Ⅲ从上到下打印二叉树
- 最第k大的数的一般性问题
猜你喜欢
随机推荐
AD Actual Combat
unity 代码拆分图集
Lightly:新一代的C语言IDE
字符串哈希
增量编译技术在Lightly中的实践
TeamCode 产品 UI 全新升级,快来体验吧
【操作系统】线程安全保护机制
Pylon CLI 低成本的本地环境管控工具应用实例
LT8918L LVDS转MIPI芯片技术支持资料
Comparison between Boda Industrial Cloud and Alibaba Cloud
判断回文
STM32 CAN 介绍以及相关配置
Introduction and mock implementation of list:list
【Connect the heart rate sensor to Arduino to read the heart rate data】
步兵相关连接
408-Binary tree-preorder inorder postorder level traversal
【LeetCode】Sum
Altium Designer Basics
二进制中1的个数
STM32F4 CAN 配置注意的细节问题









