FLV Video解析

Flash Video 简称FLV,目前国内大部分视频分析网站都是采用这种格式。
它的主要是由 File Header + File Body 构成。 如下图所示

FLV 文件总览

FLV Header 构成

FLV Header

字段字节数描述
Signature3固定字节 0X46 4c 56 对应ASCII 的FLV
Version1版本号
TypeFlags1类型标识。 前5个bit是类型标志预留字段,必须是0; 第6个bit音频类型标志(TypeFlagsAudio); 第7个bit是类型标志预留字段,必须是0; 第8个bit视频类型标志(TypeFlagsVideo)。(0x05,也就是 00000101,表示既有音频也有视频。0x01 只有视频)
data offset4版本号为1,值固定为9

FLV Body 构成

FLV body 由PreviousTagSize + Tag 构成,而tag 又分为 3种类型,分别是
Script(脚本)、Video(视频)、Audio(音频)

PreviousTagSize 解析

PreviousTagSize 为固定的4个字节,表示前面一个tag 的值

FLV Tag 解析

FLV tag 由 TagHeader + tag Data 构成

Tag Header

Tag Header为固定的11 个字节,其内部由以下几个字段构成

字段字节数描述
TagType10x12 : Scipt 0x09 :视频 0x08:音频
DataSize3数据长度
TimeStamp3相对于第一帧的时间戳,单位为毫秒,第一帧总为0
TimeStampExtender1时间戳的补充字段
StreamID30

tag Header

所以后面的一个 PreviousTagSize = 前一个dataSize + 11;

Tag Data
Script data

Script Tag,一般都是flv文件的开头才有一个。它包含两个AMF(Action Message Format)包,第一个AMF包封装了" onMetaData ",第二个AMF包封装了诸如视频图像长宽,文件长度,视频帧率,音频比特率,位深等等。
在这里插入图片描述
上图中0x08 字节,表示 Value 字段是数组类型

Video Data

Tag Data 是由 FrameTypeCodecID 以及VideoData 或者AVCVIDEOPACKET构成,AVCVIDEOPACKET只存在第一个video tag 中。
下图是视频的首个 Tag,它一定是由 11个字节的Header + frameType(0x17,0x27)+AVCVIDEOPACKET 组成
Video Tag 0
下面是Tag Data 3个字段的描述:

0x17 : 1个byte 对应8 bits, 0x17 转为0001 0111 ,分别对应的是截图中的frameTypeCodecID.
FrameType 数值对应的值意味着 (0001 = 1)
1-- keyframe
2 – inner frame
3 – disposable inner frame (h.263 only)
4 – generated keyframe

CodecID 数值对应的值意味着 (0111 = 7)
2 – seronson h.263
3 – screen video
4 – On2 VP6
5 – On2 VP6 with alpha channel
6 – Screen video version 2
7 – AVC (h.264)

所以我们可以判断在传输非关键帧的时候 FrameType + CodeCID 组成的值为0x27

AVCVIDEOPACKET 解析

AVCVIDEOPACKET 解析

字段字节描述
AVCPACKETType10:AVC sequence header 1:AVC NALU 2:AVC end of sequence
Composition Offset3合成时间。 AVCPacketType==1,表示 合成时间(单位毫秒); 否则为0
VideoData2如果AVCPacketType=0数据部分为AVCDecoderConfigurationRecord; 如果AVCPacketType=1,数据部分为1个或多个NALU; 如果AVCPacketType==2,数据部分为空

关键的AVCDecoderConfigurationRecord 数据构成

字段字节描述
版本10x01版本号为1
编码规格3sps[1]+sps[2]+sps[3]
NALU 的长度10xff
SPS个数10xE1
SPS长度2整个sps长度
SPS的内容n整个sps
PPS个数10x01
PPS长度2整个pps长度
PPS内容n整个pps内容

组装的相关代码见下:

    const char *sps = videoFrame.sps.bytes;
    const char *pps = videoFrame.pps.bytes;
    NSInteger sps_len = videoFrame.sps.length;
    NSInteger pps_len = videoFrame.pps.length;

    body = (unsigned char *)malloc(rtmpLength);
    memset(body, 0, rtmpLength);

    body[iIndex++] = 0x17;
    body[iIndex++] = 0x00;

    body[iIndex++] = 0x00;
    body[iIndex++] = 0x00;
    body[iIndex++] = 0x00;

    body[iIndex++] = 0x01;
    body[iIndex++] = sps[1];
    body[iIndex++] = sps[2];
    body[iIndex++] = sps[3];
    body[iIndex++] = 0xff;

    /*sps*/
    body[iIndex++] = 0xe1;
    body[iIndex++] = (sps_len >> 8) & 0xff;
    body[iIndex++] = sps_len & 0xff;
    memcpy(&body[iIndex], sps, sps_len);
    iIndex += sps_len;

    /*pps*/
    body[iIndex++] = 0x01;
    body[iIndex++] = (pps_len >> 8) & 0xff;
    body[iIndex++] = (pps_len) & 0xff;
    memcpy(&body[iIndex], pps, pps_len);
    iIndex += pps_len;
普通Video Data 解析

讲完第一个特殊的VideoData, 其他所有的VideoData 都是由AVPACKETTYPE + CompsitionTime offset + Data(去除startCode 的有效图像数据)构成。
普通的VideoData 数据

具体的iOS 侧代码组装可见:LFLIiveKit
FLV 分析工具需要使用Windows 下的 FLV Analyzer

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值