全称FLASHVIDEO,是一种新的视频格式,主要的特点是文件小、加载速度快。
flv的结构相对简单,可以通过下图来初步了解其组成:
flv = flv header(9字节) + flv body
flv header = Signature(3字节) + Version(1字节) + Flags(1字节) + DataOffset(4字节)
flv body = PreviousTagSize0 + Tag1 + PreviousTagSize1 + Tag2 + ... + PreviousTagSizeN-1 + TagN
flv header示例:
flv body主要由PreviousTagSize和Tag组成,有以下约定:
flv tag分为3种类型:
字段 | 大小 | 含义 |
---|---|---|
TagType | 1字节 | tag类型。 音频:0x08 视频:0x09 script data:0x12 |
Datasize | 3字节 | tag data的大小 |
Timestamp | 3字节 | 该tag的时间戳 |
TimestampExtended | 1字节 | 时间戳扩展字节。当24位数值不够时,该字节最高位将时间戳扩展为32位 |
StreamID | 3字节 | 总为0 |
TagData | 不定 | 取决于TagType |
FrameType + CodecID总共为1个字节。
字段 | 大小 | 含义 |
---|---|---|
FrameType | 前4位 | 帧类型 1:key frame (如h264的I帧) 2:inter frame(如h264普通帧) 3:disposable inter frame 4:generated keyframe 5:video info/command frame |
CodecID | 后四位 | 编码id 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 | 不定 | 视频数据,与CodecID相关。 2:H263VIDEOPACKET 3:SCREENVIDEOPACKET 4:VP6FLVVIDEOPACKET 5:VP6FLVALPHAVIDEOPACKET 6:SCREENV2VIDEOPACKET 7:AVCVIDEOPACKE(h264媒体数据) |
AVCVIDEOPACKE
当 CodecID 为 7 时,VideoData 为 AVCVIDEOPACKE,为H.264媒体数据。
AVCVIDEOPACKE 的定义如下:
字段 | 大小 | 含义 |
---|---|---|
AVCPacketType | 1字节 | 0:AVC sequence header 1:AVC NALU 2:AVC end of sequence |
CompositionTime | 3字节 | 如果AVCPacketType=1,则为时间cts偏移量;否则,为0 |
Data | 不定 | 1)AVCPacketType=0,则为AVCDecoderConfigurationRecord 2)AVCPacketType=1,则为NALU(一个或多个) 3)AVCPacketType=2,则为空 |
示例:
SoundFormat + SoundRate + SoundSize + SoundType = 1字节
字段 | 大小 | 含义 |
---|---|---|
SoundFormat | 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 |
SoundRate | 2 bits | 采样率,对AAC来说,永远等于3 0:5.5-kHz 1:11-kHz 2:22-kHz 3:44-kHz |
SoundSize | 1 bits | 采样精度,对于压缩过的音频,永远是16位 0:snd8Bit 1:snd16Bit |
SoundType | 1 bits | 声道类型,对Nellymoser来说,永远是单声道;对AAC来说,永远是双声道; 0:sndMono 单声道 1:sndStereo 双声道 |
SoundData | 不定 | 如果是AAC,则为 AACAUDIODATA; |
AACAUDIODATA
当 SoundFormat 为10时,表示音频采AAC进行编码,此时,SoundData的定义如下:
字段 | 大小 | 含义 |
---|---|---|
AACPacketType | 1 bits | 0:AAC sequence header 1:AAC raw |
Data | 不定 | 如果AACPacketType为0,则为AudioSpecificConfig 如果AACPacketType为1,则为AAC帧数据 |
AudioSpecificConfig
字段 | 大小 | 含义 |
---|---|---|
AudioObjectType | 5 bits | 编码器类型,比如2表示AAC-LC |
SamplingFrequencyIndex | 4 bits | 采样率索引值,比如4表示44100 |
SamplingFrequencyIndex | 4 bits | 采样率索引值,比如4表示44100 |
ChannelConfiguration | 4 bits | 声道配置,比如2代表双声道,front-left, front-right |
示例:
主要用来存放音视频数据的元数据信息(MetaData)。采用AMF(Action Message Format)封装了一系列数据类型,比如字符串、数值、数组等。
字段 | 大小 | 含义 |
---|---|---|
Objects | SCRIPTDATAOBJECT[] | 任意数目的 SCRIPTDATAOBJECT |
SCRIPTDATAOBJECTEND | 3字节 | 永远是9,标识着Script Data的结束 |
字段 | 大小 | 含义 |
---|---|---|
ObjectName | SCRIPTDATASTRING | 对象的名字 |
ObjectData | SCRIPTDATAVALUE | 对象的值 |
字段 | 字段类型 | 字段含义 |
---|---|---|
Type | SCRIPTDATASTRING | 变量类型: 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 |
ECMAArrayLength | 如果Type为8(数组),则为UI32 | 数组长度 |
ScriptDataValue | If Type == 0 DOUBLE If Type == 1 UI8 If Type == 2 SCRIPTDATASTRING …(有点长,可以参考规范) | 变量的值 |
ScriptDataValueTerminator | 如果Type3,则为SCRIPTDATAOBJECTEND 如果 Type8,则为SCRIPTDATAVARIABLEEND | Object、Array的结束符 |
MetaData中包含了音视频相关的元数据,封装在Script Data Tag中,它包含了两个AMF。
第一个AMF:
第二个AMF:
字段 | 大小 | 含义 |
---|---|---|
duration | DOUBLE | 文件的时长 |
width | DOUBLE | 视频宽度(px) |
height | DOUBLE | 视频高度(px) |
videodatarate | DOUBLE | 视频比特率(kb/s) |
framerate | DOUBLE | 视频帧率(帧/s) |
videocodecid | DOUBLE | 视频编解码器ID(参考Video Tag) |
audiosamplerate | DOUBLE | 音频采样率 |
audiosamplesize | DOUBLE | 音频采样精度(参考Audio Tag) |
stereo | BOOL | 是否立体声 |
audiocodecid | DOUBLE | 音频编解码器ID(参考Audio Tag) |
filesize | DOUBLE | 文件总得大小(字节) |
struct flv_header_t
{
unsigned char FLV[3];
unsigned char version;
unsigned char audio;
unsigned char video;
unsigned int offset; // data offset
};
static inline uint32_t be_read_uint32(const uint8_t* ptr)
{
return (ptr[0]<< 24) | (ptr[1]<< 16) | (ptr[2]<< 8) | ptr[3];
}
static inline void be_write_uint32(uint8_t* ptr, uint32_t val)
{
ptr[0] = (uint8_t)((val >>24) & 0xFF);
ptr[1] = (uint8_t)((val >>16) & 0xFF);
ptr[2] = (uint8_t)((val >>8) & 0xFF);
ptr[3] = (uint8_t)(val & 0xFF);
}
int flv_header_read(struct flv_header_t* flv, const uint8_t* buf, size_t len)
{
if (len< 9 || 'F' != buf[0] || 'L' != buf[1] || 'V' != buf[2])
{
assert(0);
return -1;
}
flv->FLV[0] = buf[0];
flv->FLV[1] = buf[1];
flv->FLV[2] = buf[2];
flv->version = buf[3];
assert(0x00 == (buf[4] & 0xF8) && 0x00 == (buf[4] & 0x20));
flv->audio = (buf[4] >>2) & 0x01;
flv->video = buf[4] & 0x01;
flv->offset = be_read_uint32(buf + 5);
return FLV_HEADER_SIZE;
}
其他解析可参考ireader开源库,github: https://github.com/ireader
解析工具推荐一款解析flv格式码流的工具:FlvAnalyzer.exe,解析效果如图所示:
部分参考:
https://www.cnblogs.com/chyingp/p/flv-getting-started.html
https://blog.51cto.com/u_13861442/5169955
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
本文名称:音视频学习(十三)——flv详解-创新互联
网站网址:https://www.cdcxhl.com/article18/eoigp.html
成都网站建设公司_创新互联,为您提供商城网站、网站建设、品牌网站设计、网站改版、定制网站、App设计
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联