【流媒体|从入门到出家】:流媒体协议—FLV


         第一篇章  流媒体原理


1.1    流媒体概念

1.2    流式传输特点

1.3    流媒体系统构成

1.4    流媒体涉及技术

1.5    流媒体应用

1.6    国内外大型流媒体系统

1.7    总结

流媒体相关术语


第二篇章  流媒体系统

2.1    编码工具

2.2    流媒体服务器

2.3    CDN分发网络

2.4    网络协议

2.5    播放器

总结:从一个直播APP看流媒体系统的应用  


第三篇章  流媒体协议

3.1    HTTP

3.2    RTMP

3.3   FLV

3.4    HLS

3.5    Websocket

3.5    URL






(by 又拍云@刘博 观止云PM羌人彧)


认识FLV


上一篇讲了HTTP在流媒体中的应用,接下来我们先把基于HTTP的HTTP-FLV和HLS两种直播中应用非常广泛的协议提一下。

先看看HTTP-FLV长成什么样子:http://ip:port/live/livestream.flv,协议头是http,另外”.flv”这个尾巴是它最明显的特征。

在流媒体尤其是直播应用中,为什么我们要如此重视HTTP-FLV呢,因为他的使用非常广泛,可以这么说,当下的直播平台中大部分的主线路使用的都是HTTP-FLV协议,备线路多为RTMP。小编随便在Safari中打开几个直播平台房间,一抓包就不难发现使用HTTP-FLV协议的身影:熊猫、斗鱼、虎牙、B站。



FLV格式


在说HTTP-FLV之前,我们有必要对FLV adobe 官方标准有个认识,因为HTTP-FLV协议中封装格式使用的是FLV。

FLV文件格式标准是写F4V/FLV fileformat spec v10.1的附录E里面的FLVFile Format。

▣  单位说明


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

从整个文件上看,FLV = FLV FileHeader + FLV File Body。通常,FLV的前13个字节(flv header + PreviousTagSize0)完全相同,所以, 程序中会单独定义一个常量来指定。



▣  FLV Tag (E.4)


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


▣  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文件中的音频信息及数据提取出来,送给音频解码器正常播放了。


▣  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)



▣  SCRIPTDATA (E.4.4)

ScriptTagBody内容用AMF编码。


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


▣  onMetadata (E.5)

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



▣  keyframes索引信息

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

两个常用的操作metadata的工具是flvtool2和FLVMDI,都是把keyframes作为一个默认的元信息项目。在FLVMDI的主页上有描述:


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


▣  FLV分析工具

▲  http://www.flvmeta.com/

▲  yamdi:将flv转成带索引的flv,yamdi -i i.flv -o o.flv

▲  flvlib:pip install flvlib,查看索引信息:debug-flv--metadata file.flv

▲  flvchek:http://www.adobe.com/products/adobe-media-server-family/tool-downloads.html



HTTP-FLV

我们这里说的HTTP-FLV,主要是说的是HTTP-FLV流,而不是基于HTTP的FLV视频文件点播,也不是能够随意SEEK的HTTP FLV伪流。

FLV渐进式下载:通过HTTP协议将FLV下载到播放器中播放,无法直接拉到中间去播放。

HTTP FLV伪流:支持SEEK,可从未下载的部分开始播放。

HTTP-FLV流:拥有和流式协议RTMP一样的特征,长连接,流式数据。


▣  HTTP-FLV技术实现

HTTP协议中有个content-length字段的约定,即http的body部分的长度。服务器回复http请求时如果有这个字段,客户端就接收这个长度的数据然后认为数据传输完成了,开始播放。

如果服务器回复http请求中没有这个字段,客户端就一直保持长连接接收数据,直到服务器跟客户端的socket断开。

HTTP-FLV流就利用了上述的第二个原理,服务器回复客户端请求的时候不加content-length字段,在回复了http内容之后,进行持续的数据发送,客户端就一直接收数据,以此实现了HTTP-FLV流直播。

数据传输依然是之前讲过的内容,每一个音视频数据都被封装成包含时间戳信息头的数据包,封装格式采用FLV,传输协议采用http。


▣  HTTP-FLV抓包分析

打开熊猫TV的一条直播流:

http://175.25.168.16/pl3.live.panda.tv/live_panda/d4e0a83a7e0b0c6e4c5d03774169fa3e.flv?wshc_tag=0&wsts_tag=57e233b1&wsid_tag=6a27c14e&wsiphost=ipdbm

返回信息如下:


我们发现响应头中出现Connection:close的字段,表示网宿采用的是短连接方式,直接通过服务器关闭连接来确定消息的传输长度。

还有一种实现方式,如果HTTP Header中有Content-Length,那么这个Content-Length既表示实体长度,又表示传输长度。而HTTP-FLV这种流,服务器是不可能预先知道内容大小的,这时就可以使用Transfer-Encoding:chunked模式来传输数据了。如下的响应就是采用的Chunked的方式进行的传输的响应头:



▣  HTTP-FLV延迟分析

通过http-flv的实现中不难发现,HTTP-FLV的延迟方面和RTMP能够保持一致。


▣  HTTP-FLV与其他流媒体协议的比较

当前,RTMP、HLS、HTTP-FLV是直播应用的三种主协议,说他主流,主要是因为国内所有的CDN都支持对它们的分发。这里需要注意的是,有些厂商如网宿所指的HDL,国外所称的HFL,本质上都是我们今天所讲的HTTP-FLV协议。

观止云的BMS是在国内最早支持HTTP-FLV的流媒体服务器,且相对于其他方案,观止云BMS集群内部全走RTMP,只是在边缘实时转为HTTP-FLV。如此一来系统架构更简单,稳定,且一路RTMP回源节省了不少回源流量。

❶  延迟比较

HTTP-FLV:低延迟,内容延迟可以低于3秒

RTMP:低延迟,内容延迟可以低于3秒

HLS::延迟较高,一般在10秒左右

❷  易用性比较

RTMP和HTTP-FLV:二者一样,服务端需要专门的流媒体服务器,播放端需要专门的FlashPlayer。但目前浏览器支持Flash较好,所以PC上的播放问题不大,移动端需要专门的SDK解码。

HLS:更为易用,服务端就是WEB服务器外加切片工具。播放端只要是苹果设备、HTML5平台的浏览器均可直接播放。也就是说,移动端不论是IOS还是Android,微信,朋友圈等都可以直播播放HLS直播流。

❸  RTMP和HTTP-FLV的比较:

RTMP和HTTP-FLV延迟上保持一致,在这二者的区别如下:

▲  穿墙:很多防火墙会墙掉RTMP,但是不会墙HTTP,因此HTTPFLV更不容易出问题。

▲  调度:虽然RTMP也能支持302,单实现起来较麻烦。HTTP FLV本身就支持302,更方便CDN进行重定向以便更精准的调度。

▲  容错: HTTP-FLV回源时也可以回多个源,能做到和RTMP一样,支持多级热备。

▲  简单:FLV是最简单的流媒体封装,HTTP是最广泛的协议,这两个组合在一起维护性更高,比RTMP简单。

▲  友好:HTTP-FLV代码量更小,集成SDK也更轻便。使用起来也更简单。

综上,HTTP-FLV协议具有RTMP的延迟优势,又继承了HTTP所有优势,是流媒体直播首选的分发协议。

另外,HTTP-FLV也能在推流端实现,用HTTP进行数据推流。就同样能在推流端实现上述一切优势了,只是目前国内还没有厂商实现。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值