ffmpeg+nginx+nginx-rtmp-module 搭建 rtmp hls http 流媒体服务器成功经验分享

Nginx本身是一个非常出色的HTTP服务器,FFMPEG是非常好的音视频解决方案.这两个东西通过一个nginx的模块nginx-rtmp-module,组合在一起即可以搭建一个功能相对比较完善的流媒体服务器。这个流媒体服务器可以支持RTMP和HLS(Live Http Stream)

nginx配合ffmpeg做流媒体服务器的原理是: nginx通过rtmp模块提供rtmp服务, ffmpeg推送一个rtmp流到nginx, 然后客户端通过访问nginx来收看实时视频流. HLS也是差不多的原理,只是最终客户端是通过HTTP协议来访问的,但是ffmpeg推送流仍然是rtmp的。如图所示:

1.安装编译环境和依赖项

yum -y install gcc glibc glibc-devel make nasm pkgconfig lib-devel openssl-devel expat-devel gettext-devel libtool mhash.x86_64 perl-Digest-SHA1.x86_64 gcc-c++
yum -y install git pcre pcre-devel zlib zlib-devel

2.下载nginx和nginx-rtmp-module

wget http://nginx.org/download/nginx-1.10.0.tar.gz
tar zxvf nginx-1.10.0.tar.gz
git clone git://github.com/arut/nginx-rtmp-module.git

3.编译nginx

cd nginx-1.10.0
./configure --prefix=/usr/local/nginx --add-module=../nginx-rtmp-module --with-http_stub_status_module
make
make install

4.配置nginx并启动服务

vi /usr/local/nginx/conf/nginx.conf
增加一下内容:
    rtmp {  
        server {  
            listen 1935;  
      
            application myapp {  
                live on;  
            }  
            application hls {  
                live on;  
                hls on;  
                hls_path /tmp/hls;  
            }  
        }  
    }  

然后,针对hls,还需要在http里面增加一个location配置
    location /hls {  
                types {  
                    application/vnd.apple.mpegurl m3u8;  
                    video/mp2t ts;  
                }  
                root /tmp;  
                add_header Cache-Control no-cache;  
    }
/usr/local/nginx/sbin/nginx

5.安装ffmpeg和相应的解码库

yum -y install yasm
#如果yum源里面没有yasm,就用下面的方式安装,注意要去掉前面的注释符号#
#++++++++Yasm+++++++++++
#wget http://www.tortall.net/projects/yasm/releases/yasm-1.2.0.tar.gz
#tar xzvf yasm-1.2.0.tar.gz
#cd yasm-1.2.0
#./configure
#make
#make install
#cd ..
#++++++++x264+++++++++++
git clone git://git.videolan.org/x264
cd x264
./configure --enable-shared 
make
make install
cd ..
#++++++++LAME+++++++++++
wget http://downloads.sourceforge.net/project/lame/lame/3.99/lame-3.99.5.tar.gz
tar xzvf lame-3.99.5.tar.gz
cd lame-3.99.5
./configure --enable-nasm
make
make install
cd ..
#++++++++libogg+++++++++++
wget http://downloads.xiph.org/releases/ogg/libogg-1.3.0.tar.gz
tar xzvf libogg-1.3.0.tar.gz
cd libogg-1.3.0
./configure
make
make install
cd ..
#++++++++libvorbis+++++++++++
wget http://downloads.xiph.org/releases/vorbis/libvorbis-1.3.3.tar.gz
tar xzvf libvorbis-1.3.3.tar.gz
cd libvorbis-1.3.3
./configure
make
make install
cd ..
#++++++++libvpx+++++++++++
wget http://down1.chinaunix.net/distfiles/libvpx-v1.1.0.tar.bz2
tar jxvf libvpx-v1.1.0.tar.bz2
cd libvpx-v1.1.0
./configure --enable-shared --enable-vp8
make
make install
cd ..
#++++++++FAAD2+++++++++++
wget http://downloads.sourceforge.net/project/faac/faad2-src/faad2-2.7/faad2-2.7.tar.gz
tar zxvf faad2-2.7.tar.gz
cd faad2-2.7
./configure
make
make install
cd ..
#++++++++FAAC+++++++++++
wget http://downloads.sourceforge.net/project/faac/faac-src/faac-1.28/faac-1.28.tar.gz
tar zxvf faac-1.28.tar.gz
cd faac-1.28
vi common/mp4v2/mpeg4ip.h
#修改以下内容
从123行开始修改此文件mpeg4ip.h,到129行结束。
    修改前:
    #ifdef __cplusplus
    extern "C" {
    #endif
    char *strcasestr(const char *haystack, const char *needle);
    #ifdef __cplusplus
    }
    #endif

    修改后:
    #ifdef __cplusplus
    extern "C++" {
    #endif
    const char *strcasestr(const char *haystack, const char *needle);
    #ifdef __cplusplus
    }
    #endif
#修改完后保存退出
./configure
make
make install
cd ..
#++++++++Xvid+++++++++++
wget http://downloads.xvid.org/downloads/xvidcore-1.3.2.tar.gz
tar zxvf xvidcore-1.3.2.tar.gz
cd xvidcore/build/generic
./configure
make
make install
cd ../../../
#++++++++ffmpeg+++++++++++
git clone git://source.ffmpeg.org/ffmpeg
cd ffmpeg
./configure  --prefix=/opt/ffmpeg/ --enable-version3  --enable-libvpx --enable-libfaac --enable-libmp3lame  --enable-libvorbis --enable-libx264 --enable-libxvid --enable-shared --enable-gpl --enable-postproc --enable-nonfree  --enable-avfilter --enable-pthreads
make && make install
cd ..
vi /etc/ld.so.conf
#增加以下内容
include ld.so.conf.d/*.conf
/lib
/lib64
/usr/lib
/usr/lib64
/usr/local/lib
/usr/local/lib64
/opt/ffmpeg/lib
#保存退出
ldconfig

6.用ffmpeg推流到nginx

#RTMP方式
/opt/ffmpeg/bin/ffmpeg -re -i "/home/1.mp4" -vcodec libx264 -vprofile baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -s 1280x720 -q 10 rtmp://0.0.0.0:1935/
myapp/test1
#HTTP方式
/opt/ffmpeg/bin/ffmpeg -re -i "/home/2.mp4" -vcodec libx264 -vprofile baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -s 1280x720 -q 10 rtmp://0.0.0.0:1935/hls/test2

7.验证服务是否搭建成功
上面这两个流的地址分别是:
第一个就是推送的地址: rtmp://0.0.0.0:1935/myapp/test1
第二个是HTTP地址: http://0.0.0.0:80/hls/test2.m3u8

其中0.0.0.0换成你服务器的ip地址。
现在我们的流媒体服务器有两个实时流了,一个是rtmp的,另一个是hls的,用流媒体播放器播放一下,实际测试vlc无法播放,mpc-hc、potplayer可以播放,还有一个测试swf地址也可以播放:http://www.cutv.com/demo/live_test.swf,其它播放器没有测试,rtmp方式成功,http方式没有成功。
8.后续
ffmpeg功能强大,还可以做在线转码、切片等功能,暂时没有测试。有兴趣的同学可以自行实验。

最后贴上一段对于HLS这个比较特殊的流媒体协议的解释:
(这段解释来自: http://www.cnblogs.com/haibindev/archive/2013/01/30/2880764.html)
HTTP Live Streaming(HLS)是苹果公司(Apple Inc.)实现的基于HTTP的流媒体传输协议,可实现流媒体的直播和点播,相对于常见的流媒体直播协议,例如RTMP协议、RTSP协议、MMS协议等,HLS直播最大的不同在于,直播客户端获取到的,并不是一个完整的数据流。HLS协议在服务器端将直播数据流存储为连续的、很短时长的媒体文件(MPEG-TS格式),而客户端则不断的下载并播放这些小文件,因为服务器端总是会将最新的直播数据生成新的小文件,这样客户端只要不停的按顺序播放从服务器获取到的文件,就实现了直播。由此可见,基本上可以认为,HLS是以点播的技术方式来实现直播。由于数据通过HTTP协议传输,所以完全不用考虑防火墙或者代理的问题,而且分段文件的时长很短,客户端可以很快的选择和切换码率,以适应不同带宽条件下的播放。不过HLS的这种技术特点,决定了它的延迟一般总是会高于普通的流媒体直播协议。

参考链接:
http://cache.baiducontent.com/c?m=9f65cb4a8c8507ed4fece7631046893b4c4380146d96864968d4e414c42246040020bee7723517708d98293c5db21a1cacab672c601e76e0dd9bd3149ca694282f8327317a1992044f934fa09a1179877dd14de9de45b2e1ac7884afa2c4df2244cb23453cdfb29c5b7003ca19e71541bcfbcf0f4b08&p=977bdf0c86cc42af5b81c7710f41cc&newp=89759a46d6c018fc57efdb371c418e231610db2151d2d34c&user=baidu&fm=sc&query=centos+nginx-rtmp-module&qid=8ca1d4d200012b2b&p1=7
http://download.chinaunix.net/download.php?id=40081&ResourceID=13024
http://redstarofsleep.iteye.com/blog/2123752