背景:前一段时间帮助一个朋友研究了下流媒体播放方面的知识,感觉挺好玩的。现在把浅薄的尝试和总结分享给大家。
一.HLS流媒体点播系统概述
HTTP Live Streaming最初是苹果公司针对其iPhone、iPod、iTouch和iPad等移动设备而开发的流媒体协议,后来在桌面QuickTime播放器中也得到了应用。HTTP Live Streaming允许内容提供者通过普通Web服务器向上述客户端提供接近实时的音视频流媒体服务,包括直播和点播。HTTP Live Streaming支持将同一节目编码为不同码率的多个替换流,客户端软件可以根据网络带宽的变化在这些不同码率的替换流之间进行智能切换。此外,HTTP Live Streaming还支持通过媒体加密和用户认证等方式来达到媒体版权保护。目前HTTP Live Streaming已被提交成为IETF的Internet-Draft。
一个典型的HTTP Live Streaming流媒体系统由内容准备(流媒体服务)、内容分发(分发服务器)和客户端软件三部分组成,如图所示
1.1 内容准备服务
内容准备服务(流媒体服务器)负责将输入的音视频媒体内容转换成为适合于内容分发服务进行传输的格式。对于视频源获取的或者上传的视利用视频编码器转化为MPEG-2系统层标准的传输流(TS)格式进行输出。流分割器负责将编码器输出的MPEG-2 TS流分割为一系列连续的、长度均等的小TS文件(后缀名为.ts),并依次发送至内容分发组件中的Web服务器进行存储。与此同时,流分割器还需创建一个含有指向这些小TS文件指针的索引文件(后缀为m3u8),同样放置于Web服务器之中进行存储。流分割器还可以对其生成的每个小TS文件进行加密,并生成相应的密钥文件。
之所以采用MPEG-2 TS格式来对编码后的媒体流进行统一封装,是因为它能够将音视频媒体流严格按时序进行交织复用,任意截取和分段后,每一个分段都可能不依赖于之前的分段而独立进行解码和播放
1.2内容分发服务
内容分发服务(分发服务器)用于通过HTTP协议将分割后的小媒体文件及其索引文件递送至客户端播放器,可以采用一个普通的Web服务器(nginx,Apache)来实现。
1.3 客户端
通常情况下,客户端软件通过访问Web网页中的URL链接来获取和下载一个流媒体会话的索引文件。这个索引文件进一步指定了服务器上当前可用的TS格式媒体文件、解密密钥和其他替换流的位置。对于选定的媒体流,客户端依次下载索引文件中列出的每一个可用媒体文件。当这些媒体文件缓冲够一定数量后,客户端将它们按顺序重新拼装成一个连贯的TS流,然后发送至播放器进行解码和呈现。对于加密的媒体文件,客户端还负责根据索引文件的指引来获取解密密钥,提供用户认证接口,并按需进行解密。
1.4 HTTP Live Streaming协议介绍
索引文件采用扩展的M3U播放列表格式,后缀名为.m3u8。M3U播放列表是一个由若干文本行组成的文本文件,其中每一行要么是一个URI,一个空行,或者是一个以注释符“#”起始的行。每个URI行指向一个分段的媒体文件,或者一个衍生的索引(播放列表)文件。除了以“#EXT”起始的行是标签行外,其他以“#”起始的行是注释,应予忽略。下面是一个简单的.m3u8索引文件例子,其所表示的媒体流由3个未加密的长度为10秒的TS文件组成
1
2
3
4
5
6
7
8
9
|
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-TARGETDURATION:10
#EXTINF:10,
http://media.example.com/segment1.ts
#EXTINF:10,
http://media.example.com/segment2.ts
#EXTINF:10,
http://media.example.com/segment3.ts
#EXT-X-ENDLIST
|
对于视频点播,直到客户端碰到索引文件中的#EXT-X-ENDLIST标签便会停止播放。
二.HLS流媒体系统的优势
部署方便,便于分发:一旦切分完成,之后的分发过程完全不需要额外使用任何专门软件,普通的网络服务器即可,大大降低了 CDN 边缘服务器的配置要求,可以使用任何现成的 CDN。分发使用的协议是最常见 HTTP,代理服务器对这个协议的缓存优化相当成熟。
时移特性好:如果你要在一段长达一小时的视频中跳转,如果使用单个 MP4 格式的视频文件,并且也是用 HTTP 协议,那么需要代理服务器支持 HTTP range request 以获取大文件中的一部分。不是所有的代理服务器都对此有良好的支持。而 HTTP Live Streaming 则只需要根据列表文件中的时间轴找出对应的 TS 片段下载即可,不需要 range request,对代理服务器的要求小很多。所有代理服务器都支持小文件的高效缓存。
自适应码率流播:效果就是客户端会根据网络状况自动选择不同码率的视频流,条件允许的情况下使用高码率,网络繁忙的时候使用低码率,并且自动在二者间随意切换。这对移动设备网络状况不稳定的情况下保障流畅播放非常有帮助。实现方法是服务器端提供多码率视频流,并且在列表文件中注明,播放器根据播放进度和下载速度自动调整。
对网络环境支持好:HLS可以穿过任何允许HTTP数据通过的防火墙或者代理服务器。
二.HLS流媒体系统的缺点
具有时延性:HTTP Live Streaming并不是一个真正实时的流媒体系统,这是因为对应于媒体分段的大小和持续时间有一定潜在的时间延迟。在客户端中,至少在一个分段媒体文件被完全下载之后才能够开始播放,而通常要求下载完成两个分段媒体文件之后才开始播放以保证不同分段音视频之间的无缝连接。
媒体数据码率相对较大:MPEG-TS流有比通常文件更多的头信息,会导致文件整体码率明显上升。
三.技术选型
内容准备服务中的编码器采用ffmpeg,流切片采用Segmenter,web服务器采用Nginx,客户端:对flash支持客户端的选用StrobeMedia Playback,ios利用Safari浏览即可,Android正在研究中,对于支持html5的浏览器可采用html5技术进行播放。
四.流媒体服务器的安装配置
系统环境:
发行版本:CentOS release 6.3
内核版本:2.6.32-279.el6.x86_64
4.1 ffmpeg的安装
4.1.1安装Yasm
Yasm是一个完全重写的NASM汇编。目前,它支持x86和AMD64指令集,接受NASM和气体汇编语法,产出二进制, ELF32 , ELF64 ,COFF , Mach - O的( 32和64 ) , RDOFF2 ,的Win32和Win64对象的格式,并生成STABS 调试信息的来源,DWARF 2 ,CodeView 8格式。
1
2
3
4
5
6
7
|
wget http://www.tortall.net/projects/yasm/releases/yasm-1.2.0.tar.gz
tar zxvf yasm-1.2.0.tar.gz
cd yasm-1.2.0
./configure –prefix=/usr/local
Make
make install
查看yasm是否可以执行,不能执行就将/usr/local/bin加入可执行路径
|
4.1.2 安装ffmpeg
FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。它包括了目前领先的音/视频编码库libavcodec。可以轻易地实现多种视频格式之间的相互转换,例如在本例中可以把MP4,MOV等文件转成我们用来切片的MPEG-TS文件。
1
2
3
4
5
6
|
wget http://ffmpeg.org/releases/ffmpeg-2.2.tar.gz
tar zxvf ffmpeg-2.2.tar.gz
cd ffmpeg-2.2
./configure –prefix=/usr/local
Make
make install
|
4.2 切片工具segmenter的安装
我们使用segmenter工具获得m3u8的索引文件以及视频流切片文件。
从http://httpsegmenter.googlecode.com/svn/ 找到segmenter.c文件,采用如下编译方式
1
|
gcc -Wall-g segmenter.c -o segmenter -lavformat -lavcodec -lavutil -lm -lz-lpthread -std=c99
|
建议之后把生成的二进制segmenter拷贝入/usr/local/bin方便使用。
警告:针对网络上很多https://github.com/johnf/m3u8-segmenter这个解决方案,在我和王海涛的测试中发现切片不准确的情况,需要注意。
4.3 web服务器nginx的安装
4.3.1 可以直接安装官网提供的较新的稳定版本即可,也可以安装github上的加入nginx-rtmp-module模块的版本,https://github.com/arut/nginx-rtmp-module。
4.3.2由于我们需要播放m3u8,ts类型的文件,所以要在nginx的conf/mime.types文件中加入
1
2
|
application/x-mpegURL m3u8;
video/MP2T ts;
|
4.3.3另外对于nginx的http配置块中server配置块进行下简要说明
1
2
3
4
5
6
7
8
9
10
|
http {
server {
listen 80;
server_name localhost;
location / {
root /usr/local/html;
index index.html index.htm;
}
}
}
|
listen 表示nginx的监听端口,建议配置为80,因为“允许HTTP数据通过的防火墙或者代理服务器”这个缘故。
对Location进行讲解主要是为了指出今后我们的视频存储URL对应在web
1
2
3
4
5
6
7
8
9
|
以root方式设置资源路径
语法:rootpath;
默认:roothtml;
配置块:http、server、location、if
例如,定义资源文件相对于HTTP请求的根目录。
location /download/ {
. root /opt/web/html/;
}
在上面的配置中,如果有一个请求的URI是/download/index/test.html,那么Web服务器将会返回服务器上/opt/web/html/download/index/test.html文件的内容。
|
以root方式设置资源路径
语法:rootpath;
默认:roothtml;
配置块:http、server、location、if
例如,定义资源文件相对于HTTP请求的根目录。
location /download/ {
. root /opt/web/html/;
}
在上面的配置中,如果有一个请求的URI是/download/index/test.html,那么Web服务器将会返回服务器上/opt/web/html/download/index/test.html文件的内容。
五.如何采用HLS协议播放视频
5.1 利用ffmpeg对视频文件进行转码 **文件 -- >ts文件。
1
2
3
4
5
6
7
8
|
ffmpeg -y -i <infile> -vcodec copy -acodec copy -vbsf h264_mp4toannexb <output file>
-y 覆盖输出文件,即如果nba.xxx文件已经存在的话,直接覆盖
-i “filename” 指定需要转换的文件
-vcodec的意思是指定一个视频编码器,copy的意思就是不编码,直接复制到新文件。
-acodec的意思是指定一个音频编码器,copy的意思就是不编码,直接复制到新文件。
vbsf为过滤方法,即将mp4规定的H264组织方式转换回H264协议书规定的字节流格式。
h264_mp4toannexb 过滤器,很多解码器只支持annexb这种模式,因此需要将mp4做转换
其中in file为待转换的视频文件,比如input.mov,outputfile为转换后的文件,要命名为output.ts
|
5.2 利用segmenter将转换好的ts文件切割成多个ts片,并生成.m3u8的索引文件。
5.3 分完片后就会生成视频的m3u8索引文件和视频分片文件,将这些文件拷贝至相应的web目录即可。
六.测试及结论
6.1 播放模式
对于苹果的设备可直接使用safari播放m3u8文件。
对于支持flash的设备我们采用StrobeMediaPlayback实现播放音视频文件。
对于支持hls的平台,在对html5支持的浏览器下,可直接使用浏览器进行视频播放。
6.2 演示资源
略
6.3 测试结果
对于苹果设备均支持m3u8文件的播放(iphone,ipad, mac os)。
对于支持flash的设备均支持StrobeMediaPlayback播放(pc)。
对于浏览器支持html5的浏览器均支持html5方式的播放(苹果设备,pc, android)。
附录:
1. 关于StrobeMediaPlayback的配置方式:
说明:StrobeMediaPlayback自身不支持hls视频的播放,但是利用第三方插件可以完成对hls视频播放的支持。
配置方式:
第三方插件地址https://github.com/denivip/osmf-hls-plugin,我们进行配置只需要将
StrobeMediaPlayback文件夹下的文件拷贝至nginx的web目录下,然后对StrobeMediaPlayback/ StrobeMediaPlayback.html文件内容进行更改
将src改为hls索引文件的url,接着通过访问url就可以完成对hls视频的播放。