使用Nginx-rtmp-module搭建hls直播
kevin.Zhu 发布于:2013-3-26 16:07 分类:HLS 有 30 人浏览,获得评论 0 条
HTTP Live Streaming(缩写是 HLS)是一个由苹果公司提出的基于HTTP的流媒体网络传输协议。是苹果公司QuickTime X和iPhone软件系统的一部分。它的工作原理是把整个流分成一个个小的基于HTTP的文件来下载,每次只下载一些。当媒体流正在播放时,客户端可以选择从许多不同的备用源中以不同的速率下载同样的资源,允许流媒体会话适应不同的数据速率。在开始一个流媒体会话时,客户端会下载一个包含元数据的extended M3U (m3u8) playlist文件,用于寻找可用的媒体流。
HLS只请求基本的HTTP报文,与实时传输协议(RTP)不同,HLS可以穿过任何允许HTTP数据通过的防火墙或者代理服务器。它也很容易使用内容分发网络来传输媒体流。
此协议详细内容请参考apple官方网站:https://developer.apple.com/resources/http-streaming/
hls的技术细节就不说了,这里搭建hls直播的目的就是想研究下Nginx-rtmp-module针对rtmp直播流实时转换为hls直播流的基本细节。
经过测试,我发现,rtmp直播流会被动态切分为ts片段和一个不断刷新的u3m8文件,我正需要关注这一点,必要时可能对相关代码进行调试。这里按顺序分几个部分讲述我的搭建步骤:软件编译,nginx配置,rtmp源的提供,html代码修改,客户端播放
1.软件编译
从下面的网址分别下载nginx和nginx-rtmp-module:
http://nginx.org/en/download.html
https://github.com/arut/nginx-rtmp-module
我目前的现状是已经安装好了nginx-1.4.4,需要在它的基础上安装这个模块,可以使用下面的方法增加后续的第三方模块。
进入nginx的源码目录下面
./configure --add-module=/path/to/nginx-rtmp-module --with-http_ssl_module --with-debug
来增加这个模块,然后
make
make install
注意新生成的配置文件不会覆盖原来的配置文件。参见下面的截图
可见,在config时已经看到了这个新加入的模块,下面的截图说明,现在Nginx只针对新添加的模块进行编译
由上图可见,在make install时,对原来已经存在的nginx.conf,只会进行原封不动的复制。这一点比较人性化,特别是在线上运维上,这样我们可以任意增加后续模块,然后基于前一次的nginx.conf进行修改就可以了,超赞。
如果是全新安装,就更简单了,这里略去安装步骤。
下面是我的实战记录(注意我原来使用了google perftools模块,所以以后添加的所有模块需要都加上这个编译)
cd /usr/local/src
git clone https://github.com/arut/nginx-rtmp-module.git
cd ../nginx-1.4.4
./configure --prefix=/usr/local/nginx --with-google_perftools_module --add-module=/usr/local/src/nginx-rtmp-module --with-http_ssl_module --with-debug
make
make install
2.nginx配置
Nginx可以支持多虚机配置,如果是一个ip或域名多虚机的情况,就是要不同的虚机对应不同的端口服务,而如果是多ip或域名一个虚机的情况,则又不一样。这里的实际情况就是,80和8080分别对应一个http协议的虚机,1935对应一个rtmp协议的虚机。关于hls具体配置项的解释参见
https://github.com/arut/nginx-rtmp-module/wiki/Directives
在原有的nginx.conf中加入如下配置
- rtmp {
- server {
- listen 1935;
- chunk_size 4000;
- #HLS
- # For HLS to work please create a directory in tmpfs (/tmp/app here)
- # for the fragments. The directory contents is served via HTTP (see
- # http{} section in config)
- #
- # Incoming stream must be in H264/AAC. For iPhones use baseline H264
- # profile (see ffmpeg example).
- # This example creates RTMP stream from movie ready for HLS:
- #
- # ffmpeg -loglevel verbose -re -i movie.avi -vcodec libx264
- # -vprofile baseline -acodec libmp3lame -ar 44100 -ac 1
- # -f flv rtmp://localhost:1935/hls/movie
- #
- # If you need to transcode live stream use 'exec' feature.
- #
- application hls {
- live on;
- hls on;
- hls_path /usr/local/nginx/html/hls;
- hls_fragment 5s;
- }
- }
- }
- http {
- server {
- listen 8080;
- location /hls {
- # Serve HLS fragments
- types {
- application/vnd.apple.mpegurl m3u8;
- video/mp2t ts;
- }
- root html;
- expires -1;
- }
- }
- }
然后运行如下命令检查nginx.conf是否有语法错误
service nginx configtest
重新加载配置文件
service nginx reload
运行下面的命令查看nginx状态
service nginx status
然后查看端口
netstat -nlp
注意,这里reload并不能开启这几个服务,需要使用
service nginx restart
来将rtmp服务和hls服务的端口1935和8080都打开,参看下面的截图
3.rtmp源提供
我目前采用ffmpeg来将本地文件处理来模拟产生一个rtmp直播流,现在使用下面的命令来产生一个rtmp直播流
ffmpeg -re -i sample.flv -vcodec copy -acodec copy -f flv rtmp://192.168.90.26/hls/mystream
注意,这里提供rtmp源的机器不一定和nginx在同一台物理主机上,可以是网络上的另一台机器,但是要保证它能与nginx所在的主机建立tcp链接,
也就是nginx主机需要开启rtmp服务的监听端口,这里是1935,当然你也可以修改为其他的端口。
根据nginx.conf中的hls_path配置,这个命令会向192.168.90.26主机的/usr/local/nginx/html/hls下面写入ts片段和m3u8文件,参见下面的截图:
4.修改html代码,保存为playhls.html, 这是一个HTML5+HLS视频的例子
- <!DOCTYPE html>
- <html>
- <head>
- <meta http-equiv="content-type" content="text/html; charset=utf-8">
- <title>HLS Player</title>
- </head>
- <body>
- <video poster="poster.png" height="720" width="1280" controls>
- <source src="http://192.168.90.26:8080/hls/mystream.m3u8" type="application/vnd.apple.mpegurl" />
- <p class="warning">Your browser does not support HTML5 video.</p>
- </video>
- </body>
- </html>
5.客户端播放
在支持html5的浏览器中,输入如下网址
http://192.168.90.26:8080/hls/playhls.html
但是测试支持html5的浏览器比较糟糕,没有一个可以正常播放的,在android手机上测试百度浏览器,画面出来了,但是播放时出了问题,崩掉了。我使用ipad 4,打开Safari浏览器,
就可以正常播放这个直播的视频了。参见下面的截图。
在vlc中加入如下地址也可以播放
http://192.168.90.26:8080/hls/mystream.m3u8
参见下面的截图,注意直播不能拖动!
6,状态查看
要查看到状态信息,需要在nginx.conf中加入stat模块的相关配置信息,也就是加入下面的几行信息,注意root的值是nginx-rtmp-module所在的目录
location /stat {
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl {
root /usr/local/src/nginx-rtmp-module/;
}
注意为了得到统计信息,还需要开启下面的控制模块
location /control {
rtmp_control all;
}
将它们添加到8080那台http虚机上的配置如下:
- rtmp {
- server {
- listen 1935;
- chunk_size 4000;
- #HLS
- # For HLS to work please create a directory in tmpfs (/tmp/app here)
- # for the fragments. The directory contents is served via HTTP (see
- # http{} section in config)
- #
- # Incoming stream must be in H264/AAC. For iPhones use baseline H264
- # profile (see ffmpeg example).
- # This example creates RTMP stream from movie ready for HLS:
- #
- # ffmpeg -loglevel verbose -re -i movie.avi -vcodec libx264
- # -vprofile baseline -acodec libmp3lame -ar 44100 -ac 1
- # -f flv rtmp://localhost:1935/hls/movie
- #
- # If you need to transcode live stream use 'exec' feature.
- #
- application hls {
- live on;
- hls on;
- hls_path /usr/local/nginx/html/hls;
- hls_fragment 5s;
- }
- }
- }
- http {
- server {
- listen 8080;
- location /stat {
- rtmp_stat all;
- rtmp_stat_stylesheet stat.xsl;
- }
- location /stat.xsl {
- root /usr/local/src/nginx-rtmp-module/;
- }
- location /control {
- rtmp_control all;
- }
- location /hls {
- # Serve HLS fragments
- types {
- application/vnd.apple.mpegurl m3u8;
- video/mp2t ts;
- }
- root html;
- expires -1;
- }
- }
- }
http://192.168.90.26:8080/stat
如果一切正常应该能看到相关的统计信息了,参见下面的截图
如果不添加控制模块的配置,就不能看到统计数据了,参见截图
参考文献
[1].http://blog.csdn.net/kl222/article/details/12968815
[2].http://blog.csdn.net/cjsafty/article/details/9108587
[3].http://blog.csdn.net/cccallen/article/details/8440191
[4].http://www.rosoo.net/a/201111/15273.html
[5].http://blog.raphaelzhang.com/2013/04/video-streaming-and-ffmpeg-transcoding/