1.HLS官网
阅读本文前,也可以参考前面文章,手把手配置HLS流媒体服务器
如果想更全面了解HLS,参考官网地址:
https://developer.Apple.com/library/archive/documentation/NetworkingInternet/Conceptual/StreamingMediaGuide/DeployingHTTPLiveStreaming/DeployingHTTPLiveStreaming.html
HLS官网界面
2.HLS数据流程框架
这个框架图,在这篇文章里手把手配置HLS流媒体服务器,已经讲解过了,这里就不再赘述了。贴上图,温故而知新。
这里详细说说推流端、服务器端,拉流端是如何使用。基本的流程框架如下图:
推流端涉及到采集、编码、推流(FFmpeg、librtmp)等模块。推流端框架可以参考前面这篇文章流媒体之推流拉流实战之关键点优化分析(2)。
流媒体服务器一般需要做如下工作:
关于流媒体服务器搭建和基本认识,可以阅读这篇文章,流媒体服务器架构与应用分析
(1)协议转换,将rtmp协议转换为hls协议。
(2)封装格式转换,将flv的封装格式要转换为ts的封装格式。
(3)如果要将推流视频源转码(先解码再编码),如把1080P的视频转码为高清、标清等,就需要转码。注意:目前的技术还很少将标清转换为1080P,这方面技术还不成熟,而且业务需求也不是很大。
(4)存储转换文件,如将ts文件存储到web server(srs也是支持web服务器),早期srs版本是用Nginx提供ts、m3u8载。
HLS拉流端拉流播放
拉流端一般涉及到音视频解封装,解码,显示等模块。关于拉流端可以阅读这几篇文章。
理解流媒体服务器和HLS拉流播放,需要注意如下几点:
(1)m3u8、ts和拉流路数没有关系。只要有新的ts文件,xxx.m3u8文件(由很多个ts文件构成)就会更新。
(2)在直播场景,最多缓存多少秒的ts文件,过期会删除。
(3)在点播场景,不会删除ts文件,是保存为整个点播节目。
3.详解流媒体服务器(主要是直播场景)工作
流媒体服务器负责将输⼊的⾳视频媒体内容转换成为适合于内容分发组件进⾏递送的格式。对于视频直播,流媒体服务器需要做如下工作。
(1)采集和编码,编码器⾸先将摄像机实时采集的⾳视频数据压缩编码为符合特定标准的⾳视频基本流(注意:⽬前苹果的系统仅⽀持H.264视频和AAC⾳频)。
(2)TS封装,复⽤和封装成为符合MPEG-2系统层标准的传输流(TS)格式进⾏输出。
(3)流分割器(Stream Segmenter)负责将编码器输出的MPEG-2 TS流分割为⼀系列连续的、⻓度均等的⼩TS⽂件(后缀名为.ts),并依次发送⾄内容分发组件中的Web服务器进⾏存储。
(4)同时,记录分片的位置。为了跟踪播放过程中媒体⽂件的可⽤性和当前位置,流分割器还需创建⼀个含有指向这些⼩TS⽂件指针的索引⽂件(就是前面文章提到的indexfile),同样放置于Web服务器之中。这个索引⽂件可以看作是⼀个连续媒体流中的播放列表滑动窗⼝,每当流分割器⽣成⼀个新的TS⽂件时,这个索引⽂件的内容也被更新,新的⽂件URI(统⼀资源定位符)加⼊到滑动窗⼝的末尾,⽼的⽂件URI则被移去,这样索引⽂件中将始终包含最新的固定数量的x个分段(主要是在直播场景下)。流分割器还可以对其⽣成的每个⼩TS⽂件进⾏加密,并⽣成相应的密钥⽂件。“滑动窗口”如下图所示:
为什么要采用MPEG-2 TS格式对音视频封装呢?
因为它能够将⾳视频媒体流严格按时序进⾏交织复⽤,任意截取和分段后,每⼀个分段都可能不依赖于之前的分段⽽独⽴进⾏解码和播放。
TS⽂件中必须仅包含⼀个MPEG-2节⽬列表,在每个⽂件的开头应包含⼀个节⽬关联表(PAT)和⼀个节⽬映射表(PMT),包含视频的⽂件中还必须含有⾄少⼀个关键帧和其他⾜够信息(如序列头)⽤以完成解码器的初始化。
什么是xxx.m3u8文件?
索引⽂件采⽤扩展的M3U播放列表格式,后缀名为.m3u8。M3U播放列表是⼀个由若⼲⽂本⾏组成的⽂本⽂件,用于索引,其中每⼀⾏要么是⼀个URI,⼀个空⾏,或者是⼀个以注释符“#”起始的⾏。每个URI⾏指向⼀个分段的媒体⽂件,或者⼀个衍⽣的索引(播放列表)⽂件。后面的文章还会详细说明m3u8的格式。
除了以“#EXT”起始的⾏是标签⾏外,其他以“#”起始的⾏是注释,应予忽略。下⾯是⼀个简单的.m3u8索引⽂件例⼦,其所表示的媒体流由3个未加密的⻓度为10秒的TS⽂件组成。
#EXTM3U
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-TARGETDURATION:10
#EXTINF:10, 表示10s
http://media.example.com/segment1.ts
#EXTINF:10, 表示10s
http://media.example.com/segment2.ts
#EXTINF:10, 表示10s
http://media.example.com/segment3.ts
#EXT-X-ENDLIST
4.详解流媒体服务器(主要是点播场景)工作
视频点播,大部分工作类似直播,但有些部分,也有区别,如下:
(1)对 于 视 频 点 播 ( V O D ) , ⽂ 件 分 割 器 ( F i l e Segmenter)⾸先将预编码存储的媒体⽂件转码为MPEG-2 TS格式⽂件(已经封装为TS格式的⽂件则忽略这⼀步)。
(2)然后再将该TS⽂件分割成⼀系列⻓度均等的⼩TS⽂件。⽂件分割器同样也⽣成⼀个含有指向这些⼩⽂件指针的索引⽂件。
千万注意:与直播型会话不同的是,这⾥的索引⽂件是⼀个不随时间⽽更新的静态⽂件,其中包含⼀个节⽬从头到尾所有分段⽂件的URI列表(也就是分片并不会过期),并以#EXT-X-ENDLIST标签结尾。
在直播中,可以将一个直播事件转换为点播(VOD)节目源,供以后点播。这时就可以不删除已过期的分段媒体文件,同时在索引⽂件中也不删除这些⽂件所对应的URI索引项,在直播结束的时候将#EXT-X-ENDLIST标签添加⾄索引⽂件的末尾。
5.内容分发
怎样把切片ts文件分发出去呢?
内容分发系统⽤于通过HTTP协议将分割后的⼩媒体⽂件及其索引⽂件递送⾄客户端播放器,它既可以是⼀个普通的Web服务器,也可以是⼀个Web缓存系统。⼏乎不需要对Web服务器做任何特殊的配置和增加其他定制的模块。推荐的配置仅限于对.m3u8⽂件和.ts⽂件的MIME类型关联,如表所示。
HTTP Live Streaming中建议的MIME类型
xxx.m3u8和xxx.ts文件的MIME类型如下表所示:
由于索引⽂件需要频繁更新和下载,因此在Web cache的配置中有必要对.m3u8⽂件的TTL(time-to-live)值进⾏微调,以保证客户端每次请求该⽂件时都能够下载到它的最新版本。
6.拉流播放端
当播放器去拉取流媒体服务器的分片ts文件,详细步骤如下:
(1)拉流端通过访问Web⽹⻚中的URL链接来获取和下载⼀个流媒体会话的索引⽂件。这个索引⽂件进⼀步指定了服务器上当前可⽤的TS格式媒体⽂件、解密密钥和其他替换流的位置。
(2)拉流端依次下载索引⽂件中列出的每⼀个可⽤媒体⽂件。当这些媒体⽂件缓冲够⼀定数量后,客户端将它们按顺序重新拼装成⼀个连贯的TS流,然后发送⾄播放器进⾏解码和呈现。
(3)如果是加密媒体文件,需要根据索引⽂件的指引来获取解密密钥,提供⽤户认证接⼝(服务端提供),并按需进⾏解密。如果是视频点播,则步骤(2)是反复进行,直到拉流端碰到索引⽂件中的#EXT-X-ENDLIST标签。
(4)如果是视频直播,索引⽂件中不存在#EXT-X-ENDLIST标签,拉流端将周期性地向Web服务器重新请求获取该索引⽂件的更新版本,然后在这个更新版的索引⽂件中查找新的媒体⽂件和解密密钥,并将它们的URI添加⾄下载队列的末尾。
注意:HTTP Live Streaming并不是⼀个真正实时的流媒体系统,这是因为对应于媒体分段的⼤⼩和持续时间有⼀定潜在的时间延迟。在拉流端,至少在⼀个分段媒体⽂件被完全下载之后才能够开始播放,即先下载,后才能播放,延时必定大。在实际项目设计中,通常要求下载完成两个分段媒体⽂件(这也会增加延迟)之后才开始播放以保证不同分段⾳视频之间的⽆缝连接。
在拉流端开始下载之前,必须等待服务器端的编码器和流分割器⾄少⽣成⼀个TS⽂件,这也会带来潜在的时延。
在推荐配置下,HTTP Live Streaming系统的典型时延约在30s左右(这是一个参考值,不适合延时大的场景)。
7.⽹络⾃适应的流间切换和故障保护
前面文章提到过,在基于HTTP Live Streaming的流媒体系统中,服务器可以为同⼀节⽬源准备多份以不同码率和质量编码的替换流,并为每个替换流都⽣成⼀个衍⽣的索引⽂件。在主索引⽂件中通过包含⼀系列指向其他衍⽣索引⽂件的URI指针来找到相应的替换流,如下图所示。
在移动互联⽹环境下,由于⽹络覆盖⾯的不同和信号强弱的变化,移动终端可能随时在不同的⽆线接⼊⽹络(例如3G,EDGE,GPRS和WiFi等)之间进⾏切换。此时客户端软件可根据⽹络和带宽的变化情况随时切换到不同衍⽣索引⽂件所指向的替换流进⾏下载,从⽽⾃适应地为⽤户提供相应⽹络条件下接近最优的⾳视频QoS体验。上述替换流和衍⽣索引⽂件机制除了可以⽤于基于带宽波动的动态流间切换外,还可以⽤于服务器的故障保护。
服务器故障保护
(1)⾸先在⼀台服务器上按照正常流程⽣成⼀个媒体流或者多个替换流,以及对应的索引⽂件,
(2)然后再在另⼀台服务器上⽣成⼀套并⾏的备份媒体流和索引⽂件。
(3)将指向备份流的索引加⼊到主索引⽂件之中,使得其中针对每个带宽值都对应有⼀个主媒体流和⼀个备份媒体流。
如,假定主服务器和备份服务器分别为ALPHA和BETA,则主索引⽂件中的内容可能如下所示:
#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=200000
http://ALPHA.example.com/lo/prog_index.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=200000
http://BETA.example.com/lo/prog_index.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=500000
http://ALPHA.example.com/md/prog_index.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=500000
http://BETA.example.com/md/prog_index.m3u8
在上述例⼦中,当客户端连接主服务器ALPHA失败时,它将试图连接备份服务器BETA,从中获取最⾼带宽值替换流所对应的衍⽣索引⽂件,并进⼀步根据该索引⽂件下载相应的替换媒体流⽂件。
相对于常⻅的流媒体直播协议,例如RTMP协议、RTSP协议、MMS协议等,HLS直播协议最⼤的不同在于,直播客户端获取到的,并不是⼀个完整的数据流。HLS协议在服务器端将直播数据流存储为连续的、很短时⻓的媒体⽂件(MPEG-TS格式),而拉流端则不断的下载并播放这些⼩⽂件,因为服务器端总是会将最新的直播数据⽣成新的⼩⽂件,这样拉流端只要不停的按顺序播放从服务器获取到的⽂件,就实现了直播。由此可⻅,基本上可以认为,HLS是以点播的技术⽅式来实现直播。
由于数据通过HTTP协议传输,所以完全不⽤考虑防⽕墙或者代理的问题,⽽且分段⽂件的时⻓很短,客户端可以很快的选择和切换码率,以适应不同带宽条件下的播放。
优点:HLS能够快速切换不同码率,适应不同带宽。
缺点:它的延迟⼀般总是会远远⾼于普通的流媒体直播协议。
8.研究关键技术点
还有以下关键技术点,有待研究,在这里先提出来,在后面的文章会继续写。
(1)采集视频源和⾳频源的数据。
(2)对原始数据进⾏H264编码和AAC编码。
(3)视频和⾳频数据封装为MPEG-TS包。
(4)HLS分段⽣成策略及m3u8索引⽂件。
(5)HTTP传输协议。
9.测试说明
经过测试,不同播放器拉取同一份xxx.m3u8文件,延时差别很大,说明播放器策略不一样。延时差别如下图:
FFplay拉流的延时是最大。为什么会这样呢?
对于FFplay,拉取到m3u8文件,从第一个ts文件开始去播放。而对于srs播放器,不是从第一个ts文件播放,一般是播最后2个ts文件,所以这样会更快。知道其中的原因,以后设计播放器,就便于去优化。
本篇文章就分析到这里,欢迎大家关注欢迎关注,点赞,转发,收藏,分享,评论区讨论。
后面关于项目知识,后期会更新。欢迎关注微信公众号"记录世界 from antonio"。