HTTP-FLV协议

1、简介

       FLV (Flash Video) 是 Adobe 公司推出的另一种视频格式,是一种在网络上传输的流媒体数据存储容器格式。其格式相对简单轻量,不需要很大的媒体头部信息。整个FLV由 The FLV Header, The FLV Body 以及其它 Tag 组成。因此加载速度极快。采用 FLV 格式封装的文件后缀为 .flv。而HTTP-FLV 即将流媒体数据封装成 FLV 格式,然后通过 HTTP 协议传输给客户端。

       HTTP协议中有个约定:content-length字段,http的body部分的长度服务器回复http请求的时候如果有这个字段,客户端就接收这个长度的数据然后就认为数据传输完成了,如果服务器回复http请求中没有这个字段,客户端就一直接收数据,直到服务器跟客户端的socket连接断开。

       http-flv直播就是利用第二个原理,服务器回复客户端请求的时候不加content-length字段,在回复了http内容之后,紧接着发送flv数据,客户端就一直接收数据了。

 

2、优缺点

(1)优点

       HTTP-FLV 依靠 MIME 的特性,根据协议中的 Content-Type 来选择相应的程序去处理相应的内容,使得流媒体可以通过 HTTP 传输。相较于 RTMP 协议,HTTP-FLV 能够较好的穿透防火墙,它是基于 HTTP/80 传输,有效避免被防火墙拦截。除此之外,它可以通过 HTTP 302 跳转灵活调度/负载均衡,支持使用 HTTPS 加密传输,也能够兼容支持 Android,iOS 的移动端。

(2)缺点

       由于HTTP-FLV的传输特性,会让流媒体资源缓存在本地客户端,在保密性

TYPE[1byte] + body size[3byte] + timestamp [4byte] +streamID [3byte] +[body data]+[previousTagSize 4byte]

方面不够好。因为网络流量较大,它也不适合做拉流协议。

 

3、FLV格式

       首先我们都知道在媒体格式里,几乎都以h264视频编码。如今httpflv直播的flv数据也都是h264&aac为主的。flv封装单元是以tag来表示的,一个tag可以是音频tag或者视频tag,或者脚本tag及其其他类型。值得注意的是flv里面字节序是网络字节序,

flv的格式:

flvheader+[脚本tag(metadata)]+[第一个视频tag(h264_spspps)]+[第一个音频tag(aac_header)]+[第二个视频tag(h264第一个关键帧)]+ 后面就是音频和视频tag交互存在

tag的格式:

TYPE[1byte] + body size[3byte] + timestamp [4byte] +streamID [3byte] +[body data]+[previousTagSize 4byte]

这里的timestamp是这样存在的[ time tamp 3b,time tamp ex 1b]
h264
视频tagbody:
这里存储的h264是没有nal分割符的,在tbody里面是这样存储的,

[isKeyFrame(1byte)]+0x01+[compositionTime 3byte]+[h264 size 4byte]

compositionTimeh264编码结果dtspts之间的偏移。
aac视频tagbody

0xaf+0x01+aac raw

(1)单位说明

(2)FLV 文件头和文件体 (E.2, E.3)

从整个文件上看,FLV = FLV File Header + FLV File Body。

    通常,FLV 的前 13 个字节(flv header + PreviousTagSize0)完全相同,所以,程序中会单独定义一个常量来指定。

(3)FLV Tag (E.4)

       Timestamp 和 TimestampExtended 组成了这个 TAG 包数据的 PTS 信息,PTS = Timestamp | TimestampExtended << 24。

(4)AudioTag (E.4.2)

由于 AAC 编码的特殊性,这里着重说明了 AAC 编码的 Tag 格式。

       AudioTagHeader 的第一个字节,也就是接跟着 StreamID 的 1 个字节包含了音频类型,采样率等的基本信息。

       AudioTagHeader 之后跟着的就是 AUDIODATA 部分了。但是,这里有个特例,如果音频格式(SoundFormat)是 AAC,AudioTagHeader 中会多出 1 个字节的数据 AACPacketType,这个字段来表示 AACAUDIODATA 的类型:0 = AAC sequence header,1 = AAC raw。

       AudioSpecificConfig 结构描述非常复杂,在标准文档中是用伪代码描述的,这里先假定要编码的音频格式,做一下简化。

       音频编码为:AAC-LC,音频采样率为 44100。

       在 FLV 的文件中,一般情况下 AAC sequence header 这种包只出现1次,而且是第一个 audio tag,为什么需要这种 tag,因为在做 FLV demux 的时候,如果是 AAC 的音频,需要在每帧 AAC ES 流前边添加 7 个字节 ADST 头,ADST 是解码器通用的格式,也就是说 AAC 的纯 ES 流要打包成 ADST 格式的 AAC 文件,解码器才能正常播放。就是在打包 ADST 的时候,需要 samplingFrequencyIndex 这个信息,samplingFrequencyIndex 最准确的信息是在 AudioSpecificConfig 中,这样,你就完全可以把 FLV 文件中的音频信息及数据提取出来,送给音频解码器正常播放了。

(5)VideoTag (E.4.3)

由于 AVC(H.264) 编码的特殊性,这里着重说明了 AVC(H.264) 编码的 Tag 格式。

       VideoTagHeader 的第一个字节,也就是接跟着 StreamID 的 1 个字节包含着视频帧类型及视频 CodecID 等最基本信息。

       VideoTagHeader 之后跟着的就是 VIDEODATA 部分了。但是,这里有个特例,如果视频格式(CodecID)是 AVC,VideoTagHeader 会多出 4 个字节的信息。

       AVCDecoderConfigurationRecord 包含着是 H.264 解码相关比较重要的 SPS 和 PPS 信息,在给 AVC 解码器送数据流之前一定要把 SPS 和 PPS 信息送出,否则的话,解码器不能正常解码。而且在解码器 stop 之后再次 start 之前,如 seek,快进快退状态切换等,都需要重新送一遍 SPS 和 PPS 的信息。AVCDecoderConfigurationRecord 在 FLV 文件中一般情况也只出现 1 次,也就是第一个 video tag。

       AVCDecoderConfigurationRecord 长度为 sizeof(UI8) * (11 + sps_size + pps_size)。

(6)SCRIPTDATA (E.4.4)

ScriptTagBody 内容用 AMF 编码

       一个 SCRIPTDATAVALUE 记录包含一个有类型的 ActionScript 值。

(7)onMetadata (E.5)

FLV metadata object 保存在 SCRIPTDATA 中, 叫 onMetaData。不同的软件生成的 FLV 的 properties 不同。

(8)keyframes 索引信息

       官方的文档中并没有对 keyframes index 做描述,但是,flv 的这种结构每个 tag 又不像 TS 有同步头,如果没有 keyframes index 的话,需要按顺序读取每一个tag, seek 及快进快退的效果会非常差。后来在做 flv 文件合成的时候,发现网上有的 flv 文件将 keyframes 信息隐藏在 Script Tag 中。

       keyframes 几乎是一个非官方的标准, 也就是民间标准。两个常用的操作 metadata 的工具是 flvtool2 和 FLVMDI,都是把 keyframes 作为一个默认的元信息项目。在 FLVMDI 的主页上有描述:

keyframes: (Object) This object is added only if you specify the /k switch. 'keyframes' is known to FLVMDI and if /k switch is not specified, 'keyframes' object will be deleted. 'keyframes' object has 2 arrays: 'filepositions' and 'times'. Both arrays have the same number of elements, which is equal to the number of key frames in the FLV. Values in times array are in 'seconds'. Each correspond to the timestamp of the n'th key frame. Values in filepositions array are in 'bytes'. Each correspond to the fileposition of the nth key frame video tag (which starts with byte tag type 9).

       也就是说 keyframes 中包含着 2 个内容 “filepositions” 和 “times”分别指的是关键帧的文件位置和关键帧的 PTS。通过 keyframes 可以建立起自己的 Index,然后在 seek 和快进快退的操作中,快速有效地跳转到你想要找的关键帧位置进行处理。

(9)FLV 分析工具

 

参考:

(1)官方文档:Adobe Flash Video File Format Specification Version 10.1:

http://download.macromedia.com/f4v/video_file_format_spec_v10_1.pdf

(2)https://segmentfault.com/a/1190000010791731?utm_medium=hao.caibaojian.com&utm_source=hao.caibaojian.com&share_user=1030000000178452

猜你喜欢

转载自blog.csdn.net/King_weng/article/details/106080645