[时间:2018-03] [状态:Open]

[关键词:流媒体,stream,HLS]

本文是上一篇的后续部分,链接如下:HLS协议综述

2 playlist(m3u8)介绍

HLS中的playlist是一个UTF-8编码的文本文件,其中包含了URL和描述性标签。一个常规的playlist如下所示:

#EXT-X-VERSION:3
#EXTM3U
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:1 # Old-style integer duration; avoid for newer clients.
#EXTINF:10,
http://media.example.com/segment0.ts # New-style floating-point duration; use for modern clients.
#EXTINF:10.0,
http://media.example.com/segment1.ts
#EXTINF:9.5,
http://media.example.com/segment2.ts
#EXT-X-ENDLIST

其中以'#'打头的行都是标签,HLS标准规定对于标准中未定义的标签,可以直接忽略;也就是说'#'也可以作为注释行。这里说明下上面M3U8文件的构成:

  • #EXT-X-VERSION:<n> 表示协议的版本号,而且每个M3U8中只能出现一次该标签。对于具体版本号的定义,可以参考标准的第7节。
  • #EXTM3U作为M3U文件的标识符,可以用于文件类型识别,这是必须的字段。
  • #EXT-X-TARGETDURATION:<s>表示最长分片的时长,这是必须的字段。
  • #EXT-X-MEDIA-SEQUENCE:<number>表示playlist文件中第一个分片的序列号(整数值)。如果M3U8文件中没有该字段,则playlist中第一个分片的序列号必须是0。
  • #EXTINF:<duration>,[<title>]表示下一个分片的时长。对于每个分片,必须有该字段。 对于#EXT-X-VERSION小于3的情况下,duration必须是整数;其他情况下duration可以是浮点数和整数。title是一个可选字段,仅用于增强可读性。
  • #EXT-X-ENDLIST 该字段表示分片结束,不会在playlist文件中添加新的分片。

上面介绍的是最常见的playlist,还有一种playlist,仅包含播放节目列表信息,在HLS中称为master playlist。其示例如下:

#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=1280000,AVERAGE-BANDWIDTH=1000000, RESOLUTION=720x480
http://example.com/low.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=2, BANDWIDTH=2560000,AVERAGE-BANDWIDTH=2000000, RESOLUTION=1080x720
http://example.com/mid.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=3, BANDWIDTH=7680000,AVERAGE-BANDWIDTH=6000000, RESOLUTION=1920x1080
http://example.com/high.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=4, BANDWIDTH=65000,CODECS="mp4a.40.5"
http://example.com/audio-only.m3u8

其中包含的标签说明如下:

#EXT-X-STREAM-INF:<attribute-list>用于标识一个Variant Stream,这是由一系列的Redition组成的。该标签的属性列表中包含了Variant Stream的描述信息。例如:

  • BANDWIDTH表示Variant Stream中的峰值比特率,单位bits/s。
  • AVERAGE-BANDWIDTH表示Variant Stream中的平均比特率,单位bits/s。
  • CODECS包含Variant Stream中音视频编码格式相关的信息,比如上面的"mp4a.40.5"。
  • RESOLUTION包含Variant Stream中对应视频流的分辨率。
  • FRAME-RATE表示Variant Stream中的视频帧率。

M3U8中还有一个标签需要关注下,EXT-X-PLAYLIST-TYPE。该标签只有两个值:EVENT、VOD。EVENT指的是分片工具只能在M3U8末尾添加新的分片的信息,但不能删除老的分片,通常比较适用于直播+录播的情况(既要提供给客户端点播功能,也要对实时场景进行录制,直播完成之后EVENT就自然退化为VOD)。但是对于M3U8中存在#EXT-X-ENDLIST标签时,可以忽略EXT-X-PLAYLIST-TYPE

还有一种情况,如果M3U8中不存在#EXT-X-ENDLIST以及EXT-X-PLAYLIST-TYPE标签,则服务器端可以任意更新playlist内容。

到此我们基本介绍了完了M3U8的格式。

3 服务器端和客户端的主要实现逻辑

HLS之服务器端

在第一部分介绍过,HLS的服务器端包括三个部分:转码器、分片器、分发端。对于VOD而言,这三个部分是可以独立工作的,并不需要太多的配合。但对于直播而言,三者需要密切配合,以保证直播的实时性和流畅度。典型的服务器端逻辑是这样的:

  1. 将原始音视频数据或者多媒体素材通过转码器编码复用;
  2. 将复用后的文件切片,并生成对应的M3U8(注意切片应该符合HLS规范);
  3. 为每个切片生成对应的URL,并更新M3U8文件;
  4. 直播需要实时更新Playlist对应的M3U8,点播生成完成之后服务器端不得修改Playlist

HLS之客户端

从逻辑上来讲,HLS客户端更为简单。其典型处理逻辑如下:

  1. 通过给定URI获取 Playlist。若是Master Playlist,客户端需选择一个Variant Stream来播放。
  2. 客户端检查#EXT-X-VERSION版本是否满足。
  3. 客户端应该忽略不可识别的 tags,忽略不可识别的属性键值对。
  4. 加载Media Playlist file,并选择一个segment开始播放;
  5. 播放完成一个segment之后,根据客户端当前的具体情况选择一个新的segment,并重复执行播放操作;
  6. 对于直播,需要定期刷新Media Playlist file,并选择合适的segment播放。

4 码率切换的基本逻辑

从HLS协议的定义来看,所有的码率切换策略都是有客户端定义的。服务器端仅仅提供几种可供选择的码率。所以主要的码率切换逻辑也是在客户端完成。

客户端判断是否切换的主要因素如下:

  1. 设备实际下载速度
  2. 设备运行情况(CPU、内存、以及屏幕分辨率)

比较简单的客户端会直接根据实际下载速度和Variant Stream标称的码率做比较,如果满足就上切,不满足就下切。

当然在实际切换时还需要考虑播放器的用户体验,最好做到平滑切换,用户没有直接的可见的播放卡顿。

5 常见的开源HLS框架

到目前为止,我所遇到的HLS播放框架主要有:ffmpeg中的HLS模块、AOSP中的HLS模块。当然在Mac或iOS中原生就支持HLS,不过没有源码。

6 总结

后面的文章将中主要关注ffmpeg和AOSP中的HLS相关的实现。同时会给出一个基于ffmpeg搭建的HLS直播系统(本地文件模拟的直播源)。

本文主要简单总结了HLS协议相关的基础知识,以及HLS服务器端和客户端的常规实现逻辑。仅供后续参考及查阅。

参考

  1. APPLE-HLS
  2. IETF-HTTP Live Streaming
  3. HLS 协议详解

流媒体之HLS——综述(二)的更多相关文章

  1. 流媒体之HLS——综述

    [时间:2018-01] [状态:Open] [关键词:流媒体,stream,HLS] 0 HLS背景及初衷 HLS是由苹果公司发起的流媒体网络传输协议,可参考rfc8261 HTTP Live St ...

  2. 文献综述二:UML技术在行业资源平台系统建模中的应用

    一.基本信息 标题:UML技术在行业资源平台系统建模中的应用 时间:2015 出版源:Hans汉斯 文件分类:uml技术的应用 二.研究背景 为方便行业人员高效率地搜集专业知识,实现知识的共享.采用计 ...

  3. [SRS流媒体]RTMP/HLS 直播服务器simple-rtmp-server安装

    一个采用MIT协议授权的国产的简单的RTMP/HLS 直播服务器,其核心的价值理念在于简单高效. 使用方法: tep 1: build srs tar xf simple-rtmp-server-*. ...

  4. Android流媒体开发之路二:NDK开发Android端RTMP直播推流程序

    NDK开发Android端RTMP直播推流程序 经过一番折腾,成功把RTMP直播推流代码,通过NDK交叉编译的方式,移植到了Android下,从而实现了Android端采集摄像头和麦克缝数据,然后进行 ...

  5. 文献综述二十:基于UML技术的客户关系管理系统实现

    一.基本信息 标题:基于UML技术的客户关系管理系统实现 时间:2015 出版源:电子设计工程 文件分类:uml技术的研究 二.研究背景 设计出可应用与银行和储户之间沟通的客户关系管理系统,从而实现对 ...

  6. 流媒体协议RTMP,RTSP与HLS有什么不同

    转载自:http://www.cuplayer.com/player/PlayerCode/Wowza/2015/0204/1774.html HLS (HTTP Live Streaming) Ap ...

  7. 解决用EasyDarwin开源流媒体服务器做HLS直播时Flash Player卡住的问题

    最近在开发EasyDarwin开源流媒体服务器HLS直播的时候发现一个现象:在PC上用flash player播放HLS和在ios上面播放HLS时,效果明显不同,在ios上播放非常稳定,而在flash ...

  8. srs之深入浅出看流媒体

    本文转载:https://blog.csdn.net/zjqlovell/article/details/50786040 CDN这几年爆炸式增长,带宽提速是根源,而HTTP始终还是那个屌样,因此目前 ...

  9. AOSP中的HLS协议解析

    [时间:2018-04] [状态:Open] [关键词:流媒体,stream,HLS, AOSP, 源码分析,HttpLiveSource, LiveSession,PlaylistFetcher] ...

随机推荐

  1. Shell脚本笔记(六)呈现数据

    呈现数据 一.文件描述符 Linux系统将每个对象当做文件处理,这包括输入和输出进程.Linux用文件描述符来标识每个文件对象.每个进程最多可以有9个 文件描述符,bash shell保留了前三个文件 ...

  2. 浅析webpack使用方法

    webpack是一个网页模块打包工具,可以将所有代码.图片.样式打包在一起,除此之外还有许多实用的功能.最近看了一个慕课学习了一下webpack的使用,在这里做一下总结. 本文不会涉及太多深入的知识, ...

  3. Mysql建库建用户建表等常用命令

    格式: mysql -h主机地址 -u用户名 -p用户密码 1.连接到本机上的MYSQL.首先打开DOS窗口,然后进入目录mysql\bin,再键入命令mysql -u root -p,回车后提示你输 ...

  4. 3ds max学习笔记(九)-- 实例操作(路径阵列)

    栅栏 路径阵列也叫间隔工具,将选择的物体沿指定的路径进行复制.实现物体在路径上的饿均匀分布. 选择需要分布的物体对象,在视图中绘制二维图形做为路径线条. 1.选择线条,制作路径 2.选择需要分布的物体 ...

  5. ajax-异步加载片段

    片段一般用.htm后缀 下面是ajax加载片段的demo 涉及知识点为: jquery.load(url, data, callback); 必需的 URL 参数规定您希望加载的 URL. 可选的 d ...

  6. PAT Basic 1001

    1001 害死人不偿命的(3n+1)猜想 (15 分) 卡拉兹(Callatz)猜想: 对任何一个正整数 n,如果它是偶数,那么把它砍掉一半:如果它是奇数,那么把 (3n+1) 砍掉一半.这样一直反复 ...

  7. python之继承与派生

    1 继承 继承的概念:继承是一种创建新的类的方式,在python中,新建的类可以继承自一个或者多个父类,原始类称为基类或超类,新建的类称为派生类或子类. python中类的继承分为:单继承和多继承 继 ...

  8. JS_高程5.引用类型(4)Array类型的各类方法

    一.转换方法 所有的对象都具有toLocaleString(),toString()和valueOf()方法.调用toString()方法会返回由数组中的每个值的字符串拼接而成的一个以逗号分隔的字符串 ...

  9. openstack 之~openstack各组件关系

    认识openstack 第一:openstack是什么? OpenStack是一个由NASA(美国国家航空航天局)和Rackspace合作研发并发起的,以Apache许可证授权的自由软件和开放源代码项 ...

  10. hihocoder1712 字符串排序(思维)

    https://hihocoder.com/problemset/problem/1712 感觉解法呼之欲出,却出不来.. 一个很好的思路是,根据新的顺序表,把给定的n组字符串换成旧表对应的字符,然后 ...