HLS协议详解

目录

一、协议概述

二、数据传输过程

三、知识点汇总

四、HLS优缺点及使用场景

五、QA

一、协议概述

1、写在前面:学习的时候一定要对照官方文档及背景知识(ts、m3u8、http)、结合分析工具,才能深入理解

(1)HLS官方文档:RFC 8216 - HTTP Live Streaming

(2)背景知识补充文档:TS格式详解M3U8格式详解HTTP协议详解之HTTP/1.1

(3)其它参考资料:HTTP Live Streaming (HLS) - Apple Developer

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

2、HLS(HTTP Live Streaming)是苹果公司基于HTTP提出来的一种自适应码率的流媒体传输协议。尤其是在移动端,由于ios/h5不支持flash,使得HLS成了移动端实时音视频流传输的首选。HLS经常应用在直播领域,一些国内的直播云通常使用HLS拉流。但是HLS延迟严重,通常延迟都在10-30s之间。

3、HLS主要内容由HTTP + M3U8 + TS这三个部分共同组成

(1)HTTP是最常见的应用层协议,我们日常基本的浏览器上网就是基于HTTP协议。在HLS中,客户端通过HTTP请求获取m3u8内容。HTTP的详细内容可以参考作者的另一篇博文:HTTP协议详解之HTTP/1.1

(2)M3U8是一个UTF-8文本文件,不包含音视频数据,其内容是一个播放列表,告诉播放器如何播放一个个ts文件,相当于一个索引文件。M3U8的详细内容可以参考作者的另一篇博文:M3U8格式详解

(3)TS文件是一个媒体段,包含一部分音视频数据,一个完整的视频会包含很多个ts文件,直播场景下会不断的产生新的ts文件,播放HLS时实际上播放的就是ts。TS封装格式的详细内容可以参考作者的另一篇博文:TS格式详解

4、HLS(HTTP Live Streaming)允许播放器根据当前网络条件自适应媒体的比特率,以保持最佳质量的无间断播放。它支持插入式内容边界,可以在媒体流中插入广告、节目信息等内容。它提供了灵活的媒体加密框架,可以保护媒体内容的安全性。它可以高效地提供多个版本的同一内容,例如音频翻译。上述内容均可以通过m3u8的标签来提供信息,告知播放器何时插入广告,用哪种方式进行加密等。

5、相对于常见的流媒体直播协议,例如RTMP、RTSP、HTTP-FLV,HLS最大的不同在于,直播客户端获取到的并不是一个完整的数据流。HLS协议在服务器将直播数据流存储为连续的、很短时常的媒体文件(MPEG-TS格式),而客户端则不断的下载并播放这些小文件,因为服务器端总是会将最新的直播数据生成新的小文件,这样客户端只要不停的按顺序播放从服务器获取到的媒体文件,这就实现了直播。基本上可以认为,HLS是以点播的技术方式来实现直播。

6、直播和点播的场景均可以使用HLS,直播场景下实时更新m3u8、ts,点播场景下m3u8、ts都不会更新。两种场景下客户端请求m3u8的逻辑略有不同,“二、HLS数据传输过程”有详细描述。

二、HLS数据传输过程

2.1 直播场景

1、整体流程

(1)用户直播开始推rtmp流到服务器,服务器转换成m3u8文件和ts文件。

(2)观众(客户端)获取音视频数据,先发送http get请求到服务器获取m3u8内容,获取ts的地址,然后再发送http get请求请求ts,收到ts包之后再开始播放。请求m3u8、ts是一个循环的过程,因为m3u8时不断更新的。(请求的URI就是HLS的播放地址,形如"http://ossrs.net:8081/live/livestream.m3u8")

(3)服务器向客户端发送http响应和发送m3u8或ts数据。

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

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

2、推流端、服务器、播放端的交互流程如下图所示

3、详细流程介绍

(1)用户直播开始推rtmp流到服务器,服务器转换成m3u8文件和ts文件。

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

        直播场景中,ts文件是不断产生的,为了能够播放直播过程中最新产生的ts文件, ​​m3u8的内容也是会不断被更新的。每当有新的ts文件生成时,m3u8文件的内容也会被更新(m3u8文件的名字不会变),新的文件URI加入到m3u8文件末尾,老的URI则会被移除,这样m3u8文件中将始终包含最新的固定数量的n个ts分片,n的值可以设置。m3u8也可以理解为一个滑动窗口,如下图所示:

         每一个ts分片都不会依赖于之前的分片而独立进行解码和播放。为此,每一个ts文件的开都应该包含一个节目关联表(PAT)和一个节目映射表(PMT),ts文件的第一帧应该是I帧和其它足够信息(如pes头)用以完成解码器的初始化。正在写入的ts文件会有”tmp”后缀,写完的文件就没有“tmp”后缀

        需要注意的是,m3u8文件和ts文件的数量和拉流路数没有关系,服务器端m3u8文件只有一个,每个ts文件也只有一个。

        分片是一个循环的过程,每一个分片的时长基本固定:每一个分片都是从I帧开始,由于GOP的原因,分片时长没有办法特别精确(比如设置每一个分片都是5s,则每一个分片的时长都是5s左右,没有办法特别精确):GOP可能超过ts分片的时长,比如ts设置成1s,GOP是2s,则ts实际时长就是2s。

(2)观众(客户端)获取音视频数据,先发送http get请求到服务器获取m3u8内容,获取ts的地址,然后再发送http get请求请求ts,收到ts包之后再开始播放。请求m3u8、ts是一个循环的过程,因为m3u8时不断更新的。(请求的URI就是HLS的播放地址,形如"http://ossrs.net:8081/live/livestream.m3u8")

        通过wireshark抓包分析可以进一步看出,客户端在拉流时,会循环发送http get请求,来获取m3u8的内容,当m3u8中包含的ts快播完之后客户端再次发送http get请求,获取新的m3u8内容,然后继续获取新的ts文件。

        两次请求m3u8的时间间隔和ts的时长有关系。

(3)服务器向客户端发送http响应和发送m3u8内容或ts数据。

  m3u8内容:

ts数据:

携带PAT的ts packet

携带PMT的ts packet

携带音视频数据的ts packet

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

       播放过程:客户端一次下载m3u8文件中列出了每一个可用媒体文件,当这些媒体文件缓冲够一定数量后,客户端将它们按照顺序重新拼装成一个连贯的ts刘,然后发送至播放器进行解码和呈现

        组包过程:一般视频一帧被打包成一个pes packet,一个pes packet的长度一般都大于ts packet的188字节,所以还是要进行切分,一个pes packet会被拆分成几部分,由多个ts packet携带。此时,只有携带第一个pes packet分组的ts packet才会有pes header,后面的ts packet只有es数据和填充字节,即不是每一个携带音视频数据的ts packet都有pes的打包数据(pes header)。ts header中的有效载荷单元起始符(payload_unit_start_indicator)为1时,就知道这是下一帧的开始了,将前面的所有ES数据组合成一帧数据。开始下一轮组帧。

        组帧完成后开始播放,直播场景中,由于m3u8中没有"EXT-X-ENDLIST"标签,所以播放的时候是没有进度条的。    

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

2.2 点播场景

1、整体流程

(1)观众(客户端)播放,先发送http get请求到服务器获取m3u8内容,获取ts的地址,然后再发送http get请求请求ts,收到ts包之后再开始播放。只请求一次m3u8因为点播场景下m3u8包含全量的ts文件,内容不会有变化,所以只请求一次即可。(请求的URI就是HLS的播放地址,形如"http://ossrs.net:8081/live/livestream.m3u8")

(2)服务器向客户端发送http响应和发送m3u8或ts数据。

        详细过程同“2.1直播场景->3、详细流程介绍->(3)服务器向客户端发送http响应和发送m3u8内容或ts数据。”

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

        播放和组包的详细过程同“2.1直播场景->3、详细流程介绍->(4)观众(客户端)侧收到数据后会进行组包操作,组成一个个完整的帧,然后进行播放。”

        组帧完成后开始播放,点播场景中,m3u8中有"EXT-X-ENDLIST"标签,所以播放的时候有进度条。
(4)断开连接,用户直播结束,服务器主动断开连接 或 观众退出直播间,客户端主动断开连接。

三、知识点汇总

1、直播、点播场景下的不同点

(1)拉流的过程:直播场景中,客户端是循环请求m3u8的,因为m3u8的内容是不断更新的;点播场景中,客户端只请求一次m3u8,m3u8的内容不变,只请求一次获取m3u8的全量内容即可。

(2)m3u8的区别:

直播:只包含最近几个ts文件,没有“EXT-X-ENDLIST”标签。

点播:有全量的ts文件,有“EXT-X-ENDLIST”标签。

(3)m3u8、ts文件的生成:直播场景中,m3u8实时更新,也不断有新的ts生成。点播场景下m3u8不会实时更新,也不会有新的ts生成。因为直播场景中不断有新数据生成,点播场景下不会有新数据生成。

2、直播、点播场景下的同点

(1)客户端请求m3u8、ts文件都是http get请求。

四、HLS使用场景及优缺点

1、使用场景

(1)直播、点播场景均可以使用HLS,尤其是在移动端,由于ios/h5不支持flash,使得HLS成了移动端音视频流传输的首选。

2、优点

(1)自适应码率:HLS可以根据网络带宽和设备性能等因素,自动调整视频的码率和分辨率,以保证最佳的观看体验。

(2)安全性高:HLS协议支持加密传输,可以保证视频内容的安全性。

(3)它支持插入式内容边界:可以不改变原始流的方式媒体流中插入广告、节目信息等内容,需要在m3u8中加入"EXT-X-DISCONTINUITY"标签和插入流的URI即可。如果是flv、mp4格式的文件,需要把插入的广告融合进原始流,需要做一些视频拼接的工作。

(4)适合录像:录像之后产生的ts文件可以直接上传到云端,然后删除本地文件,不占用本地磁盘空间,这是录制flv、mp4无法相比的。

(5)支持实时回放:HLS支持实时回放,也就是直播还没结束的时候可以回看直播过的内容。

3、缺点

(1)延时大:由于HLS是基于分段传输的,因此无法实现实时性较高的直播,不适合对实时性要求较高的场景,通常延迟都在10-30s之间。

五、QA

1、HLS延时这么大,如果直接从最后一个ts文件播放会有什么问题?

可能会产生卡顿,可以多缓存一些数据,如果播完最后一个ts,还没有新的ts产生则可以用缓存数据,来减少卡顿。只是能减少卡顿,不能完全消除卡顿;可以在起播的时候多缓存一些数据。

2、直播场景和点播场景下HLS有什么区别?

详见“三、知识点汇总->1、直播、点播场景下的不同点”

猜你喜欢

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