HTTP-FLV协议详解

目录

一、协议概述

二、数据传输过程

三、知识点汇总

四、HTTP-FLV使用场景及优缺点

五、QA

1、为什么HTTP-FLV用作拉流而不是推流?

2、发送数据的大小是如何确定的?

一、协议概述

1、写在前面:

(1)在学习HTTP-FLV之前需要对HTTP协议和FLV封装格式有所了解,可以参考如下两篇文章:

HTTP协议详解之HTTP/1.1

FLV格式详解

(2)学习HTTP-FLV的时候可以配合抓包工具wireshark或chrome抓包工具,去分析收发的消息类型及消息内容。

2、HTTP-FLV就是HTTP+FLV,将音视频数据封装成FLV格式,然后通过HTTP协议传输给客户端。

(1)HTTP是最常见的应用层协议,我们日常基本的浏览器上网就是基于HTTP协议。HTTP的详细内容可以参考作者的另一篇博文:HTTP协议详解之HTTP/1.1

(2)FLV是非常常见的音视频封装格式。FLV封装格式的详细内容可以参考作者的另一篇博文:FLV格式详解

3、HTTP-FLV流的形式至少有三种,但是播放地址的形式都是一样的,形如"http://ossrs.net:8081/live/livestream.flv"(https://github.com/ossrs/srs/wiki/v2_CN_DeliveryHttpStream#about-http-flv),本文要介绍的是FLV直播流

(1)FLV文件,渐进式HTTP流。放一个文件到nginx目录,可以访问下载在播放器播放,这是HTTP FLV文件,也就是渐进式下载流,其实是一个点播流。所谓渐进式下载,也就是用户观看时无法从未下载的地方开始看。

(2)FLV伪流。一般说的HTTP FLV,比上面的渐进式流高级一点,譬如,一个120分钟的电影,作为渐进式流播放时,用户需要从60分钟开始看,如何支持呢?因为nginx是当做文件下载的,无法直接跳转到第60分钟(nginx也不知道60分钟对应的字节偏移是多少呀)。后来有人就支持这种跳着播放,通过指定时间服务器从指定的位置开始给流,这种支持flv?start=,就是http flv的伪流,本质上还是点播流

(3)FLV直播流,是严格意义上的直播流,有RTMP的所有特征,譬如集群、低延迟、热备、GOP cache,而且有HTTP的优势,譬如302、穿墙、通用。(http优势详见“四、HTTP-FLV使用场景及优缺点->2优点”)

4、客户端如果要使用HTTP-FLV协议播放直播内容,会先发送http get请求,来请求数据。响应头中的内容是我们理解HTTP-FLV的关键:

(1)服务器的响应头中没有Content-Length因为如果有Content-Length则收到Content-Length大小的数据就会认为数据传输完就会断开连接。如果响应头中没有Content-Length这个字段,客户端就会一直接收数据,直到socket连接断开。HTTP-FLV就是利用了这个原理,响应头中没有Content-Length,客户端就会一直接收数据。

(2)HTTP-FLV协议使用分块传输的方式在服务器和客户端之间传输数据,在这种情况下,服务器的响应头将提供一个标头Transfer-Encoding:chunked,服务器端将向客户端发送一个空块,以指示响应的结束。(在实际测试中,响应头中也会出现没有Transfer-Encoding:chunked,而有Connection:close的情况,用于告诉http客户端继续接收数据,直到服务器端关闭连接。)

二、数据传输过程

1、整体流程

(1)用户直播开始推rtmp流到服务器,服务器转换成HTTP-FLV流。

(2)观众(客户端)播放,先发送http get请求到服务器(请求的uri就是HTTP-FLV的播放地址,形如"http://ossrs.net:8081/live/livestream.flv"),请求HTTP-FLV流。

(3)服务器向客户端发送http响应和发送flv格式的数据。

(4)观众(客户端)侧收到数据后会进行组包操作,组成一个个完整的flv tag,然后进行播放。

(5)断开连接,用户直播结束,服务器主动断开连接 或 观众退出直播间,客户端主动断开连接。

2、下面分别详细讨论每一阶段的过程:

(1)用户直播开始推rtmp流到服务器,服务器转换成HTTP-FLV流

在直播场景中,推流协议基本是RTMP,只有拉流协议才会用到HTTP-FLV,所以通常情况下HTTP-FLV的直播流是服务器产生的(服务器将RTMP转换成HTTP-FLV),数据传输的过程就是用户从服务器拉流的过程。

(2)观众(客户端)播放,先发送http get请求到服务器,请求HTTP-FLV流

通过wireshark抓包分析可以看出,客户端在拉流时,会首先发送http get 方法,请求数据,然后服务器就会向客户端发送flv直播流。客户端发送http请求时和服务器建立了tcp连接,服务器向客户端发送数据时也是用的同一条tcp连接;服务器向客户端发送数据的同时,客户端也在不停的发送ACK

​​

 客户端请求,请求的uri就是播放地址

(3)服务器向客户端发送http响应和发送flv格式的数据

通过wireshark抓包分析可以看出,服务器的响应和和flv数据是一起发送过来,服务器的http响应头中没有Content-Length,但是有Transfer-Encoding:chunked说明要分块传输数据,因为在直播场景中音视频数据是不间断产生的,所以服务器在发送数据时不知道数据的总大小,此时不能用Content-Length,所以要分块发送数据,直到服务器向客户端发送一个空块,以指示响应的结束,才可以断开连接

从flv数据可以看出,第一个flv包发送的是script tag,内容是metadata。无论任何时刻进入直播间,服务器都会按照flv封装格式的数据顺序发送数据,即按照flv header,previous tag size,metadata,aac/avc squence header,video/audio tag这种顺序发送数据(flv封装格式可参考:FLV格式详解_flv解析_~小生的博客-CSDN博客)。即使直播已经进行30min后进入直播间,服务器仍然会按照上述顺序给客户端发送数据(其他用户不会重新发送flv header等数据),以保证直播的任意时刻进入直播间都能观看直播。如果直接发送video/audio tag则缺少编解码信息,编解码信息存储在aac/avc squence header中,此时无法正常播放。

因为是分块传输,那每一块的大小是如何确定的?

在HTTP/1.1中,每个块的大小是可以根据具体情况来确定的,没有固定的大小限制。服务器可以根据网络状况和传输效率来决定每个块的大小。

第一个flv包,发送的是metadata

 注 从不同域名拉流时还会遇到如下情况:

http的响应中同样没有Content-Length,但是也没有chrome播放时的Transfer-Encoding:chunked,并且此时Connection是Close(当有Transfer-Encoding:chunked时Connection都是keep-alive),用于告诉http客户端继续接收数据,直到服务器端关闭连接

(4)观众(客户端)侧收到数据后会进行组包操作,组成一个个完整的flv tag,然后进行播放

由于音视频数据是分块传输到客户端的,所以一个数据包往往不是一个完整的flv tag,有可能是tag的一部分,也有可能是多个tag。当不足一个tag的时候,客户端需要进行组包,即将几个数据包中的数据组成一个完整的tag,然后再进行播放或其它操作。

因为服务发送到客户端的数据是按照flv封装格式的数据顺序发送的 (flv封装格式可参考:FLV格式详解_flv解析_~小生的博客-CSDN博客),并且flv header,previous tag size,tag header大小都是固定的,所以可以准确的偏移到tag header的起始位置,并且根据tag header中的datasize获取tag data的大小。

当获取到tag data的大小后,再根据接收到的数据长度来判断是否完整的接收了一个tag的数据,如果没有接收完数据则可以继续读取服务端发来的下一个数据包。如果接收完,则可以开始对下一个tag进行组包的操作。同时可以对组好包的tag进行播放或其它操作。

(5)断开连接,用户直播结束,服务器主动断开连接 或 观众退出直播间,客户端主动断开链接

三、知识点汇总

1、客户端如果要使用HTTP-FLV协议播放直播内容,会先发送http get请求,请求数据。响应头中没有Content-Length进而保持连接,而有Transfer-Encoding:chunked使用分块传输的方式传输数据。详见“一、协议概述->4”。

2、HTTP-FLV流的形式至少有三种,可以用来播放点播文件,也可以用来播放直播流,详见“一、协议概述->3”。

3、HTTP-FLV流的传输过程,详见“二、数据传输过程”。

四、HTTP-FLV使用场景及优缺点

1、使用场景:

(1)直播场景:HTTP-FLV可以用于实现实时的音视频直播,支持大规模用户同时观看直播内容。

(2)视频点播场景:HTTP-FLV可以用于实现在线视频点播,用户可以随时选择观看视频内容。

2、优点: (https://github.com/ossrs/srs/wiki/v2_CN_DeliveryHttpStream#about-http-flv

(1)HTTP-FLV和RTMP的延迟一样,因此可以满足延迟的要求。

(2)穿墙:很多防火墙会墙掉RTMP,但是不会墙HTTP,因此HTTP-FLV出现奇怪问题的概率很小。

(3)调度:RTMP也有个302,可惜是播放器as中支持的,HTTP-FLV流就支持302方便CDN纠正DNS的错误。在流媒体服务器需要更改流的源地址时,也可以通过重定向来通知客户端获取新的流源地址。(http 302可参考:http状态码301和302详解及区别

(4)简单:flv是最简单的流媒体封装,http是最广泛的协议,这两个到一起维护性很高,比RTMP简单多了。

3、缺点:

(1)不支持双向通信:HTTP-FLV是一种单向的传输协议,只能由服务器向客户端发送数据,无法实现双向通信。如果需要实现双向通信(如客户端向服务器发送控制指令),则需要额外的机制或协议来实现。

五、QA

1、为什么HTTP-FLV用作拉流而不是推流?

HTTP-FLV的协议功能相对简单,仅适用于特性的场景,不如RTMP具备的灵活性和全面性。 RTMP是一种专门设计用于流媒体传输的协议,它具有丰富的功能和协议支持,包括传输控制,数据封装,流量控制等。

2、发送数据的大小是如何确定的?

在HTTP/1.1中,每个块的大小是可以根据具体情况来确定的,没有固定的大小限制。服务器可以根据网络状况和传输效率来决定每个块的大小。

猜你喜欢

转载自blog.csdn.net/weixin_39399492/article/details/131540586