NGINX-RTMP 直播服务部署
基于NGINX的媒体流服务器: nginx 和 nginx-rtmp-module
功能:
- RTMP、HLS、MPEG-DASH 直播
- RTMP视频点播FLV/MP4,本地文件或HTTP播放
- 支持分布式串流:推流拉流 (可多推多拉)
- 支持H264/AAC
- 支持FFmpeg在线转码
- 在某些事件上运行外部程序(exec),主要用来使用FFmpeg转码推流到其他平台,可推多平台
- HTTP控制模块,用于录制音频/视频和投放客户端
- HTTP回调(发布/播放/记录/更新等)
- 将统计数据存储在方便机器和人类可读的XML/XSL中
- 先进的缓冲技术,将内存分配保持在最低水平,以实现更快的流媒体和低内存占用
- 支持 Linux/FreeBSD/MacOS/Windows 系统
编译安装指南
注意:Ubuntu 18.04 及以后版本无需从源码编译,可以使用以下命令安装nginx和nginx-module-rtmp, 安装完成后直接配置即可
$ sudo apt update
$ sudo apt install nginx-full
$ sudo apt install libnginx-mod-rtmp
下文为从源码编译安装,过程中遇到报错请参考文末的问题合集
1. 安装构建工具
编译 nginx 需要先安装一些基础构建工具:autoconf,gcc,git,和make.运行以下命令进行安装(仅提供在Linux系统安装指南)
- Debian 和 Ubuntu:
$ sudo apt update
$ sudo apt install build-essential git
- CentOS:
$ sudo yum update
$ sudo yum groupinstall "Development Tools"
$ sudo yum install git
2. 安装依赖
编译 nginx 还需要安装一些三方依赖:Perl Compatible Regular Expressions (PCRE),OpenSSL, 和 zlib.
- Debian 和 Ubuntu:
$ sudo apt install libpcre3 libpcre3-dev libssl-dev zlib1g-dev
- CentOS:
$ sudo yum groupinstall pcre-devel zlib-devel openssl-devel
3. 编译 NGINX 和 RTMP 模块
这里将github仓库地址替换为gitee官方镜像加速下载
# 这里将编译源码放在 /usr/local/ 目录,可自定义指定路径
$ cd /usr/local/
$ sudo git clone https://gitee.com/mirrors/nginxsource.git nginx
$ sudo git clone https://gitee.com/mirrors/nginx-rtmp-module.git
$ cd nginx
$ sudo ./auto/configure --add-module=../nginx-rtmp-module --with-cc-opt="-Wimplicit-fallthrough=0" --prefix=/usr/local/nginx --conf-path=/etc/nginx/nginx.conf --sbin-path=/usr/local/sbin/nginx
$ sudo make
$ sudo make install
4. 启动 nginx 服务
运行 sudo nginx
启动nginx
运行 sudo nginx -t
检查配置代码语法是否正确
运行 sudo nginx -s reload
重载nginx配置
如果通过 apt install 安装的 nginx 可使用以下命令:
# 启动nginx
$ sudo systemctl start nginx
# 停止nginx
$ sudo systemctl stop nginx
# 重启nginx
$ sudo systemctl restart nginx
# 重载nginx
$ sudo systemctl reload nginx
网页访问 http://your_server_ip
出现欢迎页即成功启动nginx
配置 NGINX RTMP 服务
RTMP 链接地址格式
rtmp://rtmp.example.com/app[/name]
app - 应该与配置中的application {}块的名称相匹配。
name - 由每个应用程序解释,流的名称,一般省略为空。
nginx 配置文件路径: “/etc/nginx/nginx.conf”
# RTMP配置,注意: rtmp{} 与 http{} 同级
rtmp {
server {
listen 1935; #监听RTMP协议默认端口
hunk_size 4000;
# RTMP 直播流配置
application live {
live on; # 启动 rtmp 直播
record off; # 关闭录制
}
}
}
在这个配置中,服务器会监听1935端口(RTMP默认端口)的所有请求,指定 “live” 应用程序接收数据流.
当你推流拉流时,目标地址为 rtmp://server_address/application
, 其中 server_address 是服务器 IP 或 域名地址, application 就是在nginx配置文件中的设置的(比如上面示例中的 “live”).
示例的推流拉流地址为:rtmp://127.0.0.1/live
推多路配置(多个应用程序或监听不同的端口)
- server{ } 块内配置多个 application 可以实现,由于都是监听一个端口,同一时间内只有一路有画面
rtmp {
server {
listen 1935;
chunk_size 4000;
application live {
live on;
}
application live2 {
live on;
}
}
}
- 配置多个server,监听不同端口,每个server内配置一个application
rtmp {
server {
listen 1935; # 监听1935端口
chunk_size 4000;
application live {
live on;
}
}
server {
listen 1936; # 监听1936端口
chunk_size 4000;
application live2 {
live on;
}
}
示例的推拉流地址为:
rtmp://your_server_ip/live
rtmp://your_server_ip:1936/live2
权限安全
你可以在 server { } 或 application { } 配置块中添加推拉流权限规则,允许或拒绝某些IP在服务器上推流拉流.
将权限规则放在 server { } 块内,则块内的所有 application 都受影响。
将权限规则放在一个 application { } 块内,只影响这一个 application .
示例:
- 允许 127.0.0.1 推流至服务器,但拒绝其他任何来源
allow publish 127.0.0.1;
deny publish all;
- 允许其他所有任何来源拉流播放但除了 127.0.0.1
allow play all;
deny play 127.0.0.1;
重新编码(转码)
可以在 application{ } 块内运行 exec
命令(注意不支持windows系统),可以将接收到的 RTMP 流传给视频处理器进行编码转码,如 ffmpeg.
例如:将接收到的数据流编码为mp4格式并保存为文件
exec ffmpeg -i rtmp://localhost/$app/$name -c copy -f mp4 /path/to/file/$name.mp4;
转推到其他平台
1. 可以使用 push
语句将 application 接收的流推送到其他流接收平台.
例如,你可以在 application{ } 块中,将接收到的流推送到 rtmp://rs.live.net/app ,如果有串流秘钥{stream_key},只需将秘钥添加到推流地址后面即可.
push rtmp://rs.live.net/app/{stream_key};
可以对任何提供推流地址的平台做同样的操作,甚至可以使用多条 push 语句,同时向多个平台推流.
2. 当然也可以使用 exec
运行 ffmpeg
将接收到的流推送至其他平台.
在一个 application
中支持运行多个 exec
语句,使用 ffmpeg 可以对流进行处理后再推至其他平台,如给视频流加水印、转码、调整大小及改变编解码参数等, 请参考 Nginx 直播服务部署(直播 + 分流 + 画面水印)
HLS 配置
HLS 是一种相当流行的格式,能够通过HTTP和HTTPS协议来传输视频,使得将视频流嵌入到网页中变得非常容易.
1. 要启用HLS,需要在你的 application{ } 块中添加以下语句
hls on;
hls_path /tmp/hls/$app;
hls_fragment 2s;
hls_playlist_length 4s;
可以运行以下命令确保 hls_path 目录存在
mkdir -p /tmp/hls/live
你可以改变 /tmp/hls/live
为任何其他目录. $app 最好与你的 application 名相同(在示例中为 “live”), HLS.m3u8 文件将存储在这个目录中.
你也可以根据你的需求更改 hls_fragment 和 hls_playlist_length的值,2秒和4秒是我们发现在使用2秒关键帧间隔的流媒体时效果最好的值.
2. 接下来还要在nginx配置中增加一个 http{ } 块,注意需与 rtmp{ } 块同级.如下:
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
# 设置超时限制
keepalive_timeout 65;
server {
listen 80; # HTTP IPv4
listen [::]:80; # HTTP IPv6
# 域名 (建议使用 可选)
# server_name example.com www.example.com;
location /live {
# 允许跨域 使用IP访问请忽略
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length';
# 允许跨域预检请求
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
# 指定提供的文件类型 (.m3u8)
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t;
}
# 文件存储位置
# 设置与 rtmp application 中指定的 hls_path 相同
root /tmp/hls;
# 禁用缓存
add_header Cache-Control no-cache;
}
}
}
HLS 播放
启用HLS后,重启/重载 nginx, 就可以使用任何支持HLS播放的视频播放器将流媒体嵌入到你的网页中
支持HLS播放的视频播放器
向视频播放器提供以下格式的源地址
http://{server_address}/{app_name}/{secret_key}.m3u8
{server_address}是你服务器的IP或域名,{app_name}是 application{ }块的名称,{secret_key} 是你设置的串流秘钥可不设置
例如:
http://example.com/live/secret_key.m3u8
无{secret_key}则为:http://example.com/live/.m3u8
DASH 配置 (和hls类似)
rtmp {
server {
listen 1935;
application live {
live on;
dash on;
dash_path /tmp/dash/live;
dash_fragment 15s;
}
}
}
http {
server {
listen 80;
location /dash {
root /tmp/dash;
}
}
types {
text/html html;
application/dash+xml mpd;
}
}
SSL 配置
- 你也可以通过 HTTPS 提供HLS服务, 只需要在 server { } 块中使用以下语句提供SSL证书和私钥:
ssl_certificate /path/to/certificate.pem;
ssl_certificate_key /path/to/privkey.pem;
证书绑定的域名必须是你在server_name语句中指定的域名
- 还需要监听 443 端口才可以使用 https
listen 80; # HTTP IPv4
listen [::]:80; # HTTP IPv6
listen 443; # HTTPS IPv4
listen [::]:443; # HTTPS IPv6
如没有域名SSL证书,可以 获取免费 Let’s Encrypt 证书
更多的配置
源码编译安装报错合集
cp: ‘conf/koi-win’ and ‘/usr/local/nginx/conf/koi-win’ are the same file
$ sudo ./auto/configure --add-module=../nginx-rtmp-module --prefix=/usr/local/nginx --conf-path=/etc/nginx/nginx.conf
[objs/src/core/ngx_murmurhash.o] Error 1
$ sudo ./auto/configure --add-module=../nginx-rtmp-module --with-cc-opt="-Wimplicit-fallthrough=0"
sudo nginx 报 sudo: nginx: command not found
问题:
使用 sudo /usr/local/nginx/sbin/nginx
启动nginx,确定了nginx的安装路径
在 ~/.bashrc 和 /etc/profile 中添加 PATH , 执行source刷新,依然无效
export PATH=$PATH:/usr/local/nginx/sbin
解决:
在编译nginx的时候指定 sbin-path 即可
$ sudo ./auto/configure --add-module=../nginx-rtmp-module --sbin-path=/usr/local/sbin/nginx
$ sudo ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/nginx
PS. 编译的时候可以指定更多配置
--prefix=/usr/local/nginx --sbin-path=/usr/local/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/run/nginx.pid --lock-path=/run/lock/subsys/nginx --user=nginx --group=nginx
参考
RTMP Installation Instructions
Enabling Video Streaming for Remote Learning with NGINX and NGINX Plus