跳到主要内容

FLV

FLV(Flash Video) 是Adobe公司设计开发的一种流行的流媒体格式,由于其视频文件体积轻巧、封装简单等特点,使其很适合在互联网上进行应用。FLV封装格式的文件后缀通常为.flv。

FLV格式协议

FLV包括文件头和文件体两部分,其中文件体由一系列的Tag组成。如下图所示

FLV文件的详细结构。如下图所示

HTTP-FLV

HTTP-FLV将流媒体数据封装成FLV格式,然后通过HTTP协议传输给客户端。

HTTP协议中有个约定content-length字段,HTTP的body部分的长度。请求响应存在这个字段,客户端接收这个长度的数据后就认为数据传输完成了,如果不存在这个字段,客户端就一直接收数据,知道服务器跟客户端的连接断开。

HTTP-FLV利用了HTTP的分块传输,发送FLV数据,服务器无法知道流长度,所以不会填写content-length

来自虎牙直播流响应头
access-control-allow-origin: *
Access-Control-Expose-Headers: alt-svc,cdncip,cdnsip
cdncip: 2409:8a00:dda:9e80:84c5:dfc3:95d7:243e
cdnsip: 2409:8c20:1834:50d:503::3f8
Connection: close
Content-Type: video/x-flv
Date: Sun, 18 Sep 2022 00:32:33 GMT
Server: Tengine
Via: cache10.cn4333[,0]
X-Tengine-Type: live

Connection: close字段,表示采用的短连接,则直接可以通过服务器关闭连接来确定消息的传输长度。

优势:

  • HTTP-FLV依靠MIME的特性,根据协议中的content-type来选择相应的程序去处理响应的内容,使得流媒体可以通过HTTP传输。
  • 相较于RTMP协议,HTTP-FLV能够较好的穿透防火墙,他是基于HTTP/80传输,有效避免被防火墙拦截。
  • 可以通过HTTP302跳转灵活调度/负载均衡,支持使用HTTPS加密传输

不足:

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

flv.js

flv.js可以解析FLV文件,从中取出音视频数据并转成BMFF片段(mp4格式),然后交给HTML5的<video>标签进行播放。通过这种方式,使得浏览器在不借助Flash的情况下也可以播放FLV文件。

flv.js的工作原理非常简单,它首先将FLV文件转成ISO BMFF(mp4)片段,然后通过浏览器的Media Source Extensions 将MP4片段播放出来。具体的处理过程如下图所示

从上图我们可以看出,flv.js播放器首先通过Fetch Stream Loader模块从云端获取FLV数据;之后由IO Controller模块控制数据的加载;数据加载好后,调用FLV Demux将文件进行解封装,得到音视频数据;最后,将音视频数据交由MP4 Remux模块,重新对音视频数据封装成MP4格式。

将封装好的MP4片段交由浏览器的Media Source Extensions处理后,最终我们就可以看到视频并听到声音了。所以总体来说,flv.js最主要的工作是做了媒体媒体格式的转封装工作,具体的播放工作则是由浏览器来完成的。

flv.js的四个部分:

  • Fetch Stream Loader 通过url获取http-flv媒体流。其主要工作就是通过HTTP协议下载媒体数据,然后将下载后的数据交给IO Controller
  • IO Controller 控制模块,负责数据的加载、管理等工作。它会将接收到的数据传给FLV Demux
  • FLV Demux 负责去掉FLV文件头、TAG头等,拿到H264/AAC的裸流。
  • MP4 Remux 将H264/AAC裸流加上MP4头,采用多媒体格式协议是BMFF。将封装好的传给浏览器Date Source对象

参考资料

HLS:实现一对多直播系统的必备协议
FLV封装格式分析器
HTTP-FLV协议
HTTP-FLV协议
HTTP-FLV直播初探