Hacks on Computer Vision

基于nginx-rtmp-module的视频点播小试

2016.03.05

前几天基于nginx-rtmp-module做了个测试HTTP Live Streaming的小demo,主要是为了测试在单个m3u8文件中包含同一个视频不同码率的切片流的运行情况,简单记录一下。

多码率的m3u8简介

根据苹果官网的描述,使用多码流HLS的主要好处有下面几点:

  • 当播放其中一个码率的视频遇到404错误时,客户端可以直接跳转到其他的码率;
  • 客户端可以根据自己的网络条件选择合适码率的视频播放。

要支持多码率视频,其m3u8文件可以这么做:

#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=200000, RESOLUTION=720x480
http://ALPHA.mycompany.com/lo/prog_index.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=200000, RESOLUTION=720x480
http://BETA.mycompany.com/lo/prog_index.m3u8
 
#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=500000, RESOLUTION=1920x1080
http://ALPHA.mycompany.com/md/prog_index.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=500000, RESOLUTION=1920x1080
http://BETA.mycompany.com/md/prog_index.m3u8

其中PROGRAM-ID是对视频的标识,这里都为1表示它们是同一个视频;BANDWIDTH指的是最大每秒字节数,客户端可以根据这个参数,自由选择合适的视频播放;后面的RESOLUTION表示的视频的分辨率。每一行的m3u8文件是具体视频切片的内容。

这就相当于在一个总的m3u8中,通过这种形式包含了同一视频不同码率、不同分辨率的视频,在上面的例子中,如果ALPHA对应的机器挂掉,客户端可以切换到对应的BETA地址上;而如果客户端的网络比较好,会直接播放分辨率更高、码率更大的视频。

有关HLS的详细内容可以参考HLS的草稿和苹果官网提供的样例

基于nginx-rtmp-module的HLS服务器端搭建

nginx的商业版本有hls模块的支持,但github上有开源的rtmp模块,可以用于直播和点播,支持hls。

下载nginx-rtmp-module的代码:

git clone https://github.com/arut/nginx-rtmp-module

下载nginx源码:

wget http://nginx.org/download/nginx-1.9.12.tar.gz
tar xvf nginx-1.9.12.tar.gz && cd nginx-1.9.12

把nginx-rtmp-module模块加入到nginx中:

./configure --add-module=../nginx-rtmp-module/
make
make install

这一步要注意--add-module的路径,在configure完成后,可以看下输出信息中是否成功的添加了这个模块。

nginx默认会安装到/usr/local/nginx目录下,编辑该目录下的配置文件conf/nginx.conf,可以参考该模块的样例


#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  10;
}

rtmp {
    server {
        listen 1935;
        chunk_size 4000;

        application vod {
            play /var/flvs;
        }

        application vod2 {
            play /var/vod2;
        }

        application hls {
            live on;
            hls on;
            hls_path /var/hls;
        }
    }
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    access_log /var/log/access.log;
    error_log /var/log/error.log;

    sendfile        on;

    keepalive_timeout  65;


    server {
        listen       80;
        server_name  localhost;

        location /stat {
            rtmp_stat all;
            rtmp_stat_stylesheet stat.xsl;
        }

        location /stat.xsl {
            root /var/;
        }

        location /hls {
            types {
                application/vnd.apple.mpegurl m3u8;
                video/mp2t ts;
            }
            root /var/hls;
            add_header Cache-Control no-cache;
        }
    }
}

其中,比较重要的是

rtmp {
    server {
        listen 1935;
        chunk_size 4000;

        application vod {
            play /var/flvs;
        }

        application vod2 {
            play /var/vod2;
        }

        application hls {
            live on;
            hls on;
            hls_path /var/hls;
        }
    }
}

其中play对应的是视频文件所在的文件夹,比如下面我们测试点播(video on demand)时,就可以把视频文件放在/var/vod2文件夹下。

之后就可以启动nginx了

/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf

如果没有启动成功,会输出对应的错误信息,修改配置文件中的内容即可。

接下来就可以测试视频了,我是使用的VLC播放器,打开地址

rtmp://xxx.xxx.xxx.xxx:1935/vod2/sample.mp4

应该就可以看到视频了。

如果显示出错,可以查看下nginx的access.logerror.log里面的信息来排查。

这个模块比较好的一点是,还提供了一个简单的统计页面,访问http://xxx.xxx.xxx.xxx/stat就可以看到:

请输入图片描述

测试下视频切片m3u8格式,这次使用VLC打开地址:

http://xxx.xxx.xxx.xxx/hls/main.m3u8

VLC可以看到一段一段的视频切片,而access.log日志也会出现类似下面的信息:

xx.xxx.xx.xxx - - [03/Mar/2016:02:34:39 -0500] "GET /main.m3u8 HTTP/1.1" 206 210 "-" "VLC/2.2.1 LibVLC/2.2.1"
xx.xxx.xx.xxx - - [03/Mar/2016:02:34:39 -0500] "GET /hd/hd.m3u8 HTTP/1.1" 206 468 "-" "VLC/2.2.1 LibVLC/2.2.1"
xx.xxx.xx.xxx - - [03/Mar/2016:02:34:39 -0500] "GET /hd/hd.m3u8 HTTP/1.1" 206 468 "-" "VLC/2.2.1 LibVLC/2.2.1"
xx.xxx.xx.xxx - - [03/Mar/2016:02:34:45 -0500] "GET /hd/stream00000.ts HTTP/1.1" 206 705188 "-" "VLC/2.2.1 LibVLC/2.2.1"
xx.xxx.xx.xxx - - [03/Mar/2016:02:34:52 -0500] "GET /hd/stream00001.ts HTTP/1.1" 206 742412 "-" "VLC/2.2.1 LibVLC/2.2.1"
xx.xxx.xx.xxx - - [03/Mar/2016:02:34:57 -0500] "GET /hd/stream00002.ts HTTP/1.1" 206 599344 "-" "VLC/2.2.1 LibVLC/2.2.1"
xx.xxx.xx.xxx - - [03/Mar/2016:02:35:02 -0500] "GET /hd/stream00003.ts HTTP/1.1" 206 407020 "-" "VLC/2.2.1 LibVLC/2.2.1"
xx.xxx.xx.xxx - - [03/Mar/2016:02:35:08 -0500] "GET /hd/stream00004.ts HTTP/1.1" 206 385400 "-" "VLC/2.2.1 LibVLC/2.2.1"
xx.xxx.xx.xxx - - [03/Mar/2016:02:35:14 -0500] "GET /hd/stream00005.ts HTTP/1.1" 206 401192 "-" "VLC/2.2.1 LibVLC/2.2.1"
xx.xxx.xx.xxx - - [03/Mar/2016:02:35:20 -0500] "GET /hd/stream00006.ts HTTP/1.1" 206 429392 "-" "VLC/2.2.1 LibVLC/2.2.1"
xx.xxx.xx.xxx - - [03/Mar/2016:02:35:25 -0500] "GET /hd/stream00007.ts HTTP/1.1" 206 456652 "-" "VLC/2.2.1 LibVLC/2.2.1"
xx.xxx.xx.xxx - - [03/Mar/2016:02:37:11 -0500] "GET /hd/stream00008.ts HTTP/1.1" 206 457780 "-" "VLC/2.2.1 LibVLC/2.2.1"

可以看到其状态码都是206。

__EOF__

本文作者HackCV
版权声明本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
本文链接https://hackcv.com/posts/%E5%9F%BA%E4%BA%8Enginx-rtmp-module%E7%9A%84%E8%A7%86%E9%A2%91%E7%82%B9%E6%92%AD%E5%B0%8F%E8%AF%95/

发表评论