音视频之解析flv文件实战

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010339039/article/details/89018384

参考文章看的是
http://www.360doc.com/content/16/1013/17/474846_598171645.shtml

测试文件

相关文件和部分工具

csdn下载链接

cuc_ieschool.flv

使用相关工具如下:
float2hex.exe(二进制转double的工具)

对比工具:
FlvAnalyzer

二进制文件分析工具
Uedit32.exe
在这里插入图片描述

flv文件头(9+4 B)

在这里插入图片描述
前三个字节 flv ,1 是版本 , 第五个字节(1/4/5) , 1 video , 4 audio , 5 video and audio

脚本tag(script tag 11 B)

扫描二维码关注公众号,回复: 5782300 查看本文章

在这里插入图片描述
第一个B , tag type , 若 8 audio , 9 video , 0x12 metadata
3B body size (00 02 27)
3B timestamp
1B ,00
3B StreamId

amf0:数据中的保存方式都是使用amf来序列化,本质上就是把int,double,String,都是用二进制存储的,读取的时候要能知道他分别是什么数据
比如0x01就是boolean类型,后面的一位就是判断ture,false的。
如果0x02代表string ,后面两个字节代表这个String有长,后面的就是String的内容。

在这里插入图片描述
第一个AMF包(1+2+10 = 13B)
在这里插入图片描述

00 0A ,代表这个String有10个字节
后10 B ,就是这个String 的内容 “onmetadata”

第二个AMF包
在这里插入图片描述

0x08 是amf0中的MixedArray 相当于map,key-value 键值对
0x19表示元素个数 25个
那么后面的元素都是使用key-value的方式存储
主要是存储一些基本信息,比如duration,width,height,samplerate,一些视频音频的基本信息数据。

元素“duration”(19B)
在这里插入图片描述

0x00 ,0x08长度 后8B “duration”
紧跟的一个字节0x00就是后面的数据类型(number)占用8个字节的double类型。
这个时候使用浮点转换工具
float2hex.exe
得知是34.159秒

元素“width”(16B)
在这里插入图片描述
0x00 0x05 ,长度5 也就是 “width”
0x00 是number ,转换的512(像素)

元素height(17B)
在这里插入图片描述
0x00 , 0x06 长度 “height”
0x00 number 转换为 288(像素)

元素“videodatarate”(24B)

在这里插入图片描述
0x00 0x0D 13个长度videodatarate
视频码率为 179kb/s

元素framerate(20B)

在这里插入图片描述
0x09 长度 就是“framerate”
0x00 number

元素videocodecid(23B)

在这里插入图片描述
0x0c 12个元素“videocodecid”
0x00 number
转换得 7 (视频的编解码器) , 因为有个对应表

元素audiodatarate(24B)

在这里插入图片描述
0x0d 就是audiodatarate的长度
0x00 number
音频码率

元素audiosamplearate(26B)
在这里插入图片描述
0x0f 16 audiosamplearate的长度
0x00 number
采样率 44100

元素“audiosamplesize”(26B)
在这里插入图片描述
0x0f audiosamplesize的长度
0x00 number
采样深度 16位

元素stereo(10字节)
在这里插入图片描述

0x06 stereo的长度
后1B ,AMF0中的bool类型
最后1B ,0是单声道。1是双声道

元素audiocodecid
在这里插入图片描述
0x0c audiocodecid 的长度
0x00 number
音频的编解码器 2

元素metadatacreator
在这里插入图片描述
0x0f metadatacreator 的长度

0x02 amf 中的String

0x00 0x03长度为3

内容是iku ,好像是用来标识视频中的数据是谁处理的

元素haskeyframes
在这里插入图片描述
0x0c 字符串的长度
0x02是amf中的字符串
0x00 , 0x04 是字符串长度 内容是true

元素hasvideo
在这里插入图片描述
0x08 字符串长度
0x02 是amf 中的String
0x00 0x04是长度 对应的true

元素hasaudio
在这里插入图片描述
同上。

元素hasmetadata
在这里插入图片描述
道理同上
元素canseektoend
在这里插入图片描述
同上,用来判断是否可以滑动。
元素datasize
在这里插入图片描述
元素大小用string保存的932906
元素videosize
在这里插入图片描述
Videosize大小是787866

元素audiosize
在这里插入图片描述
Audiosize元素大小140052

元素lasttimestamp
在这里插入图片描述
应该是最后一帧的时间戳
元素lastkeyframetimestamp
在这里插入图片描述
Lastkeyframetimestamp = 30 是最后一帧关键帧的时间戳

元素lastkeyframelocation
在这里插入图片描述
最后关键帧的位置886498

元素encoder
在这里插入图片描述
内容是Lavf55.19.104

元素filessize

在这里插入图片描述

文件大小,转换得1358127B , 也就是实际文件大小

这应该是metadata结束标志
在这里插入图片描述

0x00 ,0x00 空字符串

0x09 Amf end of object

在这里插入图片描述

Previous tag size
在这里插入图片描述
内容是376
第一个videotag(11B)

在这里插入图片描述
0x09是tagtype 9是video , 0x08是audio , 0x12metadata
后3B 是bodysize ,
后3B是TimeStamp
后1B是timestampExtend
后3B 是StreamId

Video tag 数据部分固定的前5个字节

在这里插入图片描述
0x17 的二进制是 10111 ,高四位是frametype , 低四位是codecid

10111 向左移动4位,就是frametype = 1 , 那么codeid是7

后1B,是看是什么数据类型。
0:avc序列头 ,那么后面的数据就是sps ,pps部分
1:avc nalu单元 ,后面的数据部分就是nalu单元
2:avc序列结束。低级别avc不需要

后3B 如果avc packet类型为1,那么这3B为cts偏移。

见下图

在这里插入图片描述

接下来就是previous tag size(4B)
在这里插入图片描述
前一个tag的大小共 56 字节,body size(45)+ tag header(11) = 56

第一个audioTag
在这里插入图片描述

0x08 是tag type 。0x08 是audio

3B body size
3B 是TimeStamp
1B 是timeStampExtended
3B Stream ID

接下来数据部分的第一个字节

4位是音频格式
2位采样率
1位采样大小
1位声道

见下图
在这里插入图片描述

手动解析效果如下:
在这里插入图片描述

解析代码在

文件解析代码如下 FlvParse.cpp

猜你喜欢

转载自blog.csdn.net/u010339039/article/details/89018384