先贴出一系列参考网站 :
概念解释 :
***HLS是一套解决方案, 包含三个部分 : ***
苹果官方文档的配图Server :
服务器组件负责获取的媒体输入流 , 然后Media编码后 MPEG-4(H.264 video 和 AAC audio)格式然后用硬件打包到 MPEG-2 (MPEG-2 transport stream)的传输流中。图中显示,传输流会经过stream segmenter, 这里的工作是MPEG-2传输流会被分散为小片段然后保存为一个或多个系列的 .ts 格式的媒体文件。这个过程需要借助编码工具来完成,比如 Apple stream segmenter。
(视频类是.ts文件,纯音频会被编码为一些音频小片段,通常为 ADTS头的AAC、MP3、或者 AC-3格式。)
服务端可以采用硬件编码和软件编码两种形式,其功能都是按照上文描述的规则对现有的媒体文件进行切片并使用索引文件进行管理。而软件切片通常会使用 Apple 公司提供的工具或者第三方的集成工具。
Distribution :
同时上面提到的那个切片器(segmenter)也会创建一个索引文件,通常会包含这些媒体文件的一个列表,也能包含元数据。他一般都是一个.M38U 个hi的列表。列表元素会关联一个 URL 用于客户端访问。然后按序去请求这些 URL。
client :
分配组件由标准的网络服务器。他们负责接受Client客户端请求并提供相关联的资源给客户端。
接下来将上面的图的每一块解释一下
Media encoder (媒体编码) :
媒体编码器获取到音视频设备的实时信号,将其编码后压缩用于传输。而编码格式必须配置为客户端所支持的格式,比如 H.264 视频和HE-AAC 音频。当前,支持 用于视频的 MPEG-2 传输流和 纯音频 MPEG 基本流。编码器通过本地网络将 MPEG-2 传输流分发出去,送到流切片器(Stream segmenter)那里。标准传输流和压缩传输流无法混合使用。传输流(这个流是指, 图中MPEG-2 transport stream流)可以被打包成很多种不同的压缩格式,这里有两个表详细列举了支持的压缩格式类型。 * 音频框架技术: Audio Technologies *
视频框架 : Vedio Technologies
在编码中涂,不要修改视频编码器的设置,比如视频大小或者编码解码器类型。如果避免不了,那修改动作必须发生在一个片段边界。并且需要早之后相连的片段上用 EXT-X-DISCONTINUITY进行标记。
Stream segmenter (流切片器)
流切片器(通常是一个软件,一个SDK)会通过本地网络从上面的媒体编码器中读取数据,然后将着这些数据一组相等时间间隔的小媒体文件。虽然每一个片段都是一个单独的文件,但是他们的来源是一个连续的流,切完照样可以无缝重构回去。
切片器在切片同时会创建一个索引文件(Index file),索引文件会包含这些切片文件的引用。每当一个切片文件生成后,索引文件都会进行更新。索引用于追踪切片文件的有效性和定位切片文件的位置。切片器同时也可以对你的媒体片段进行加密并且创建一个密钥文件作为整个过程的一部分。
文件切片器(相对于上面的流切片器, 就是切文件的)
如果已经有编码后的文件(而不是编码流),你可以使用文件切片器,通过它对编码后的媒体文件进行 MPEG-2 流的封装并且将它们分割为等长度的小片段。切片器允许你使用已经存在的音视频库用于 HLS 服务。它和流切片器的功能相似,但是处理的源从流替换流为了文件。
媒体片段文件,(上面切除来的小片段)
媒体片段是由切片器生成的,基于编码后的媒体源,并且是由一系列的 .ts(如果是纯音频则不是.ts格式)格式的文件组成,其中包含了你想通过 MPEG-2 传送流携带的 H.264 视频 和 AAC /MP3/AC-3 音频。对于纯音频的广播,切片器可以生产 MPEG 基础音频流,其中包含了 ADTS头的AAC、MP3、或者AC3等音频。
索引文件(PlayLists)
通常由切片器附带生成,保存为 .m3u8格式,.m3u一般用于 MP3 音频的索引文件。 Note如果你的扩展名是.m3u,并且系统支持.mp3文件,那客户的软件可能要与典型的 MP3 playList 保持一致来完成 流网络音频的播放。
.m3u8 PlayLists文件为了更精确,你可以在 version 3 或者之后的协议版本中使用 float 数来标记媒体片段的时长,并且要明确写明版本号,如果没有版本号,则必须与 version 1 协议保持一致。你可以使用官方提供的切片器去生产各种各样的 playlist 索引文件,详见 媒体文件切片器
Distribution分布式部分
分布式系统是一个网络服务或者一个网络缓存系统,用于通过 HTTP 向客户端发送媒体文件和索引文件。不用自定义模块发送内容。通常仅仅需要很简单的网络配置即可使用。而且这种配置一般就是限制指定 .M38U 文件和 .ts 文件的 MIME 类型。详见 部署 HTTP Live Streaming
Client客户端部分
客户端开始时回去抓取 索引文件(.m3u8/.m3u),其中用URL来标记不同的流。索引文件可以指定可用媒体文件的位置,解密的密钥,以及任何可以切换的流。对于选中的流,客户端会有序的下载每一个可获得的文件。每一个文件都包含流中的连环碎片。一旦下载到足够量的数据,客户端会开始向用户展示重新装配好的媒体资源。
客户端负责抓取任何解密密钥,认证或者展示一个用于认证的界面,之后再解密需要的文件。
这个过程会一直持续知道出现 结束标记 #EXT-X-ENDLIST
。如果结束标记不出现,该索引就是用于持续广播的。客户端会定期的加载一些新的索引文件。客户端会从新更新的索引文件中去查找加密密钥并且将关联的URL加入到请求队列中去。
会话模式##
通常包含 Live 和 VOD (点播)两种
点播VOD的特点就是可以获取到一个静态的索引文件,其中那个包含一套完整的资源文件地址。这种模式允许客户端访问全部节目。VOD点播拥有先进的下载技术,包括加密认证技术和动态切换文件传输速率的功能(通常用于不同分辨率视频之间的切换)。
Live 会话就是实时事件的录制展示。它的索引文件一直处于动态变化的,你需要不断的更新索引文件 playlist 然后移除旧的索引文件。这种类型通过向索引文件添加媒体地址可以很容易的转化为VOD类型。在转化时不要移除原来旧的源,而是通过添加一个 #ET-X-ENDLIST
标记来终止实时事件。转化时如果你的索引文件中包含 EXT-X-PLAYLIST-TYPE
标签,你需要将值从 EVENT
改为 VOD。
抓取分析##
主索引 :
直播源 : http://dlhls.cdn.zhanqi.tv/zqlive/30647_JIjP2.m3u8
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-STREAM-INF:PROGRAM-ID=1,PUBLISHEDTIME=1462118775,CURRENTTIME=1462155858,BANDWIDTH=400000,RESOLUTION=854x480
30647_JIjP2_400/index.m3u8?Dnion_vsnae=30647_JIjP2
#EXT-X-STREAM-INF:PROGRAM-ID=1,PUBLISHEDTIME=1462118776,CURRENTTIME=1462155858,BANDWIDTH=700000,RESOLUTION=1280x720
30647_JIjP2_700/index.m3u8?Dnion_vsnae=30647_JIjP2
#EXT-X-STREAM-INF:PROGRAM-ID=1,PUBLISHEDTIME=1462118775,CURRENTTIME=1462155858,BANDWIDTH=1024000,RESOLUTION=1280x720
30647_JIjP2_1024/index.m3u8?Dnion_vsnae=30647_JIjP2
每一个标签的格式, 属性, 作用,请参考这里
#EXTM3U
每个M3U文件第一行必须是这个tag,请标示作用
#EXT-X-VERSION
用以标示协议版本。(到我写这篇文章为止,HLS协议已经经历了19个版本了,既然这里是3, 那么这里用的就是HLS协议第三个版本)此标签只能有0或1个,不写代表使用版本1。
#EXT-X-STREAM-INF
#EXT-X-STREAM-INF的格式 :
#EXT-X-STREAM-INF : [attribute=value][,attribute=value]* <URI>
标签的属性列表中直接指明当前流是VIDEO还是AUDIO
属性 :
- BANDWIDTH 指定码率
- PROGRAM-ID 唯一ID (这个属性在后面的协议版本废除了)
- CODECS 指定流的编码类型
**#EXT-X-MEDIA-SEQUENCE:1462118775 **每一个media URI 在 PlayList中只有唯一的序号,相邻之间序号+1, 一个media URI并不是必须要包含的,如果没有,默认为0
如果你的视频具备流切换功能,处于不同的带宽、不同的网速播放不同清晰度的视频流,这样只能的流切换可以保证用户感觉到非常流畅的观影体验,同时不同的设备也可以作为选择的条件,比如视网膜屏可以再网速良好的情况下播放清晰度更高的视频流。
这种功能的实现在于,索引文件的特殊结构
图片来源于苹果官网- 主索引文件和子索引文件都是.M3U8的playlist
- 主索引文件只需下载一次,但对于直播节目子索引文件定期重新加载。
- 客户端可能会在任何时候改变到备用流,所有的切换都应该使用相同的音频文件
- 这一套不同速率的视频都是有工具生成的
使用variantplaylistcreator工具并且为 mediafilesegmenter
或者 mediastreamsegmenter
指定 -generate-variant-playlist 选项,详情参考 下载工具
子索引 :
根据上面的主索引文件,这里我选择了,1024, 码率为1024000的数据源, 将URL拼接一下, 得到下面的URL
http://dlhls.cdn.zhanqi.tv/zqlive/30647_JIjP2_1024/index.m3u8?Dnion_vsnae=30647_JIjP2
结果 :
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:5647
#EXT-X-TARGETDURATION:10
#EXTINF:9.560,
1462167932532_1462167932532.ts?Dnion_vsnae=30647_JIjP2
#EXTINF:6.520,
1462167942133_1462167942133.ts?Dnion_vsnae=30647_JIjP2
#EXTINF:9.960,
1462167948685_1462167948685.ts?Dnion_vsnae=30647_JIjP2
传说已久的.ts文件已经看到, 这些就是视频数据源文件,解释一下标签的作用
#EXT-X-MEDIA-SEQUENCE
每一个media URI 在 PlayList中只有唯一的序号,相邻之间序号+1
(上面那个URL, 不断请求的过程中能不断获取子索引, 每一次获取下来的都能发现EXT-X-MEDIA-SEQUENCE会不断增大)
#EXT-X-TARGETDURATION:10
每一份媒体文件的时间, 以秒为单位, 这里是10秒一份
**#EXTINF **
格式 #EXTINF <duration>,<title>
每一份媒体文件的详细信息, duration : 媒体持续时间, 应该四舍五入为整数,上面的例子,9.560就是这一份媒体文件的持续时间
title : 1462167932532_1462167932532.ts?Dnion_vsnae=30647_JIjP2这个是这一份媒体文件的URL地址,
加密##
加密部分以后再补充.
网友评论