nginx-rtmp流媒体服务器
简介
Nginx是http和反向代理服务器,同时支持邮件协议(IMAP/POP3/SMTP),由俄罗斯程序设计师Igor Sysoev所开发,其代码遵循BSD许可证开源。由于其轻量,占用系统资源少,并发量强的特点,而拥有不少的用户。
Nginx-rtmp-module是nginx的一个模块,开源。使用这个模块开源在nginx的基础上快速搭建起一个流媒体服务器。配合ffmpeg开源项目开源实现许多点播和直播的基本功能。
功能特点
Nginx-rtmp架构的流媒体服务器具有以下一些功能特点:(翻译自官网)
- 支持RTMP / HLS / MPEG-DASH协议的视频直播。测试推流可以实现rtmp 和http flv 的推流,hls和dash并没有测试推流;拉流可以实现rtmp 和hls,没有测试http flv 和dash。
2.支持flv/mp4格式的视频点播,支持以文件或者http的方式的输入。
3.支持两种流的分发模式 push and pull
4.可以将多直播流分别录制成flv文件
5.支持H264/AAC编码
6.支持在线转码 Onlinetranscoding with FFmpeg 转码实现也是exec ffmpeg的,理论上支持一切ffmpeg支持的库。
7.支持HLS (HTTP Live Streaming)需要 libavformat (>= 8. 53.31.100) from ffmpeg (ffmpeg.org)
8.支持http回调 HTTPcallbacks (publish/play/record/update etc)
9.支持特定情况下调用外部程序(exec) ffmpeg转码即采用这种方式
10.使用HTTPcontrol模块来 recording audio/video and dropping clients
11.先进内存控制技术,可以在使用少量内存的情况下完成流畅的直播功能。
12.可以和以下外部程序协同工作:Wirecast, FMS, Wowza, JWPlayer, FlowPlayer, StrobeMediaPlayback, ffmpeg, avconv, rtmpdump, flvstreamer等。
13.统计数据展示在XML / XSL文件中,友好的可读形式。
14.支持跨平台 Linux/FreeBSD/MacOS。
安装及配置
以下针对nginx-rtmp服务器的安装以及一些配置项做一下简单介绍。
安装部署
nginx-rtmp-module:
wget -O nginx-rtmp-module.zip https://github.com/arut/nginx-rtmp-module/archive/master.zip
unzip nginx-rtmp-module.zip
nginx:
wget http://nginx.org/download/nginx-1.11.6.tar.gz
tar –x zxvf nginx-1.11.6.tar.gz
编译安装:
部署nginx-rtmp服务器除了需要nginx本身的一些支撑包和库之外,在configure的时候需要添加nginx-rtmp-module
选项。
./configure --prefix=/usr/local/nginx --with-http_ssl_module --add-module=/root/nginx-rtmp-module
make && make install
配置
原生的nginx-rtmp的所有功能均在nginx的配置文件/usr/local/nginx/conf/nginx.conf
中实现。
nginx.conf
的整体架构:
#rtmp配置
rtmp {
server {
listen 1935;
chunk_size 4000
application app_name {
………… #配置项
}
application app_name2 {
………… #配置项
}
application vod {
play /var/flvs; #video on demand
}
}
}
#nginx配置
http {
server {
location /hls {
# Serve HLS fragments
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /tmp;
add_header Cache-Control no-cache;
}
}
}
需要在rtmp{ }
中配置各种流媒体相关的配置,在http{ }
中配置各种http相关的配置。各个application
独立配置,支持正则匹配。
以下介绍一些重要的配置项:
直播基本配置:
rtmp推拉流
在rtmp{ server{ * } }
中配置以下内容
application mytv {
live on;
}
如此即配置了发布点为mytv
的直播频道,可以实现rtmp推流和拉流。推拉流地址:
rtmp://ip:1935/mytv/stream
hls
在application mytv { * }
中配置以下内容
application mytv {
………… #省略其他配置
hls on;
hls_path /tmp/hls;
hls_fragment 15s;
}
在http { server{ location /hls { } } }
中配置以下内容
http {
...
server {
...
location /hls {
types {
application/vnd.apple.mpegurl m3u8;
}
root /tmp;
add_header Cache-Control no-cache;
add_header Access-Control-Allow-Origin *;
}
}
}
如此配置之后,这个即可进行hls拉流.
详细的关于hls的其他配置。如切片时间命名设置、是否加密hls等配置可以参考:
hls配置文档
MPEG-DASH
在application
配置段中配置:
dash on;
dash_path /tmp/dash;
dash_fragment 15s;
在http
配置段中配置:
http {
...
server {
...
location /dash {
root /tmp;
add_header Cache-Control no-cache;
# To avoid issues with cross-domain HTTP requests (e.g. during development)
add_header Access-Control-Allow-Origin *;
}
}
}
MPEG-DASH 实现方式与HLS类似,具体可以查看:
mpeg-dash配置文档
自动转推
当多台nginx-rtmp 服务器运行时,可以配置把流自动推到其他机器上。
rtmp_auto_push on;
rtmp_auto_push_reconnect 1s;
rtmp_socket_dir /var/sock;
rtmp {
server {
listen 1935;
application myapp {
live on;
}
}
}
此功能没有测试过,未知其具体转推是如何实现的。
录制
在application mytv { * }
中配置以下内容
application mytv {
………… #省略其他配置
# record first 1K of stream
record all;
record_path /tmp/av;
record_max_size 1K;
# append current timestamp to each flv
record_unique on; #开启后每个录制文件根据时间命名
}
其他录制选项可参考:
record配置文档
转码
nginx-rtmp 采用调用外部程序ffmpeg 进行转码。需要在application mytv { * }
中配置以下内容
rtmp {
server {
listen 1935;
application src {
live on;
exec ffmpeg -i rtmp://localhost/src/$name
-c:a libfdk_aac -b:a 32k -c:v libx264 -b:v 128K -f flv rtmp://localhost/hls/$name_low
-c:a libfdk_aac -b:a 64k -c:v libx264 -b:v 256k -f flv rtmp://localhost/hls/$name_mid
-c:a libfdk_aac -b:a 128k -c:v libx264 -b:v 512K -f flv rtmp://localhost/hls/$name_hi;
}
application hls {
live on;
……
}
}
}
exec ffmpeg 这样的配置是会在拉流请求转码流的时候触发ffmpeg 拉流转码,在多台机器做流媒体的时候,可以通过exec_pul 和exec_push 来配置在拉流时触发转码或者在推流时触发转码。
exec
关于调用外部程序,nginx-rtmp 支持多个配置项,参考:
exec配置文档
统计信息
在http{ server{ } }
中配置可以启用统计信息。
http {
server {
location /stat {
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl {
root /path/to/stat/xsl/file;
}
}
}
访问http://192.168.1.1:8765/stat
可以看到当前时间内的各个application 的概况。
也可以下载http://192.168.1.1:8765/stat.xsl
进行统计。
端口号根据nginx配置而定。
日志
除了原生nginx 自带的error.log 和access.log 两个日志外,nginx-rtmp-module 模块还有一个rtmp-aceesss.log 日志。默认都是在nginx 的安装目录的 /logs
目录中。
查阅资料后发现,nginx 应该是可以自定日志的格式的。在配置文件中也可以定义错误日志的级别,有
debug | info | notice | warn | error | crit 几个级别,大概排查问题都利用debug 级别的错误日志。
控制模块
nginx-rtmp 服务器支持以http的形式从外部对rtmp 进行控制。需要配置以下项。
http {
……
server {
listen 8080;
server_name localhost;
....
location /control {
rtmp_control all;
}
}
}
再在需要控制的application
中预设好各种参数之后,便可以采用类似接口的形式对某些流进行录制,禁播,重定向之类的操作了。以下展示开始和停止录制的url。
curl "http://localhost:8080/control/record/start?app=myapp&name=mystream&rec=rec1"
curl "http://localhost:8080/control/record/stop?app=myapp&name=mystream&rec=rec1"
具体的控制说明可以查看:
control配置文档
总结
Nginx-rtmp 架构的流媒体服务器实际测试基本功能都有,性能也不错。在配置较差的VPS 上搭建也可以流畅运行,并不占用太多的资源。但是其只能实现简单的功能,实际对于业务以及运营需要改进的地方还有很多。
实测nginx-rtmp 服务器在hls 时,播放有时会有卡顿,原因未知;同码率推到其他流媒体服务器,hls 拉流没有卡顿,可能跟推流也有关系。
Q&As
Q: mpeg dash?
A: 类似于apple家的HLS,MPEG-DASH 是基于HTTP的自适应串流方案中的唯一国际标准。也是有小切片和索引文件组成,SC计划在明年支持此协议。
Q: http callback?
A: 在nginx-rtmp 的官方wiki 中描述的http callback 大概意思为客户端发送连接请求时,会发送一个异步http 请求,会使处理暂停,直到返回状态码之后再根据状态码继续连接请求。具体可以查看:
**https://github.com/arut/nginx-rtmp-module/wiki/Directives#notify **
Q: 多域名配置?
A: 网上资料说nginx 本身是可以改写url 的,有可以配置多个域名;nginx-rtmp 服务器没有说明可以支持多域名的配置,目测在做一些修改之后是可以做到支持多域名的。
Q: 延迟?
A: nginx-rtmp 的拉流和推流,延迟在1s左右。在播放器缓冲设置在0时所测。