心血来潮,想和朋友一起看电影,但是电影比较不符合法律法规,所以迟迟想不好在哪里看。期间折腾 RTMP 流,有所记录。
1 、 Nginx 的 RTMP 体验
Nginx 的 RTMP 组件默认是 nginx-rtmp-module [ 链接 ]
这款组件是大多数发行版都有现成的包,一般来说不需要编译
apt-get install libnginx-mod-rtmp
安装好后,即可在 nginx.conf 中增加 rtmp{}
相关字段
1.1 、创建基本的 rtmp 流分发的配置
通常 Nginx 的站点配置都是 include 进主配置文件中,所以 rtmp 也一样可以如此操作
在 nginx.conf 配置文件中,与 http{} 同级的地方之前插入 rtmp 配置
rtmp{ include /etc/nginx/rtmp.d/*.conf; }
然后我们用此配置路径,创建 /etc/nginx/rtmp.d/ 文件夹,并在其中添加相关服务配置 default.conf
server { listen 1935; # chunk_size 4096; # RTMP 块大小 # max_streams 128; # 最大并行 RTMP 流 数量 # drop_idle_publisher 10s; #推流者停止推流后断开链接时间 application live { live on; # allow publish all; # allow play all; } }
此时,我们就可以重新加载 nginx 配置
nginx -s reload
然后,使用相关推流软件,为服务器推送 rtmp 流。
但是在推送之前,我们不要忘记打开防火墙
firewall-cmd --add-port=1935/tcp
推送 rtmp 流的路径是根据 application 后面的 应用名 ( live ) 决定的,同时受限于 allow publish / deny publish 参数
rtmp://server.address:1935/live
而查看 rtmp 流的路径和推送的路径一致,但受限于 allow play / deny play 参数。
rtmp 流默认不在本地保存,所以收到的流的配置完全取决于推送方的推流配置
1.2 、 RTMP 模块的 HLS 配置
现代的服务器当然支持多终端了,而不同系统的终端千奇百怪,其中适配最好的还是 HLS
当然 HLS 的缺点也很明显,延迟高(5-20s)且服务器需要有缓存文件。
HLS 使用 m3u8 + ts 文件的方式调度,m3u8 里是一个指针指向了对应的 ts 视频片段
而 HLS 配置的方式也很简单,只需要在原有的 RTMP 基础上增加少许配置即可同时使用。
相关参数配置可以参考 [ 链接 ]
application hls_live { live on; # interleave on; # 音视频流使用相同 RTMP 块传输 # wait_key on; # 在播放时使视频流从 关键帧 开始播放 hls on; hls_path /tmp/hls; hls_fragment 1300ms; hls_max_fragment 1800ms; hls_playlist_length 3900ms; hls_fragment_slicing aligned; # pull rtmp:// #从远程服务器拉取流并显示 # push rtmp:// #从本地服务器推送流至目标 }
但与 RTMP 不同,我们还需要额外增加一个 http 站点以供 HLS/HTTP 方式访问
这里创建的是 http://localhost/ 这个虚拟站点,站点的根路径为 Nginx 自带的示例页面
站点的 live 路径指向了 rtmp 的 hls 缓存路径,并配置了允许跨域调用
server { listen 80; listen [::]:80; server_name localhost; access_log /var/log/nginx/lives.log; error_log /var/log/nginx/lives-error.log; location / { root html; index index.html; } location /lives { alias /tmp/hls; expires -1; add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Cache-Control' 'no-cache'; } }
配置好后,依然重启 Nginx,重启后可以使用 HLS/HTTP 的方式访问。
推流的终端的目标推送地址没有变化。
rtmp://server.address:1935/live
HLS/HTTP 查看流的地址是一个文件,如果直接用浏览器打开会进行下载
http://localhost:80/lives/livestream.m3u8
注意这里有三个名词参数,live 对应 rtmp 的配置,lives 对应 http 的配置,而 livestream 对应 推流者的 串流密钥
(如为空则会出现 /tmp/hls/.m3u8 的文件)
1.3 、 RTMP 模块的 多终端流分发 配置
如果有多个终端同时从服务器取流,而服务器上传上来的流只有一份,这时会出现冲突。
对于专门的流服务器,他们会复制多份流并传输。在 Nginx 中有同样的配置方式
编辑 nginx.conf ,在 rtmp {}
同级的位置上添加全局参数
rtmp_auto_push on;
rtmp_auto_push_reconnect 1s;
rtmp_socket_dir /tmp/rtmp/;
添加好后,同样的重新加载 Nginx 配置
nginx -s reload
这里会自动创建 /tmp/rtmp/ 文件夹,并且里面会生成 等同 worker_processes 数量的 socket 文件。
此时再访问 rtmp,会发现多终端不会因为互相抢占而卡顿了。
1.4 、类似的同款 RTMP 组件
Nginx 还有另一款 RTMP 组件,额外还支持了 FLV,名字是 nginx-http-flv-module [ 链接 ]
相比 rtmp-module ,flv-module 额外增加了许多命令参数用于优化性能
但是由于 flv-module 并不能直接合并到 apt-get 安装的 nginx 里面,需要编译
而编译使用官方的 Nginx -V
参数,会出现 __DATA_TIME__
错误,所以最终没有采用
2 、 SRS 的 RTMP 体验
SRS 是一款优秀的 流分发 整体解决方案,所以当我们想了解更多时,可以体验一下 SRS 的解决方案 [ 链接 ]
在 Ubuntu 20 中,直接下载并编译 SRS 4 是一切正常的,而 SRS 3 会出现一些问题(有些组件被彻底替换了)
(吐槽:SRS 为了搞中文圈子,把 Github 上的 WIKI 弄得稀烂,还不更新)
(吐槽 2:SRS 整个包搞得一团麻,全是快捷方式根本摘不清,编译完居然还得留着不能删了)
首先按照 Wiki 留下的仅剩的几句话,编译安装(遇到任何问题,只能一律谷歌去补所需要的包)
cd /opt/ git clone -b 4.0release https://gitee.com/ossrs/srs.git cd /opt/srs/trunk ./configure make
编译完成后,我们重点关注几个文件
/opt/srs/trunk/etc/init.d/srs # 主启动文件 (重要) /opt/srs/trunk/usr/lib/systemd/system/srs.service # Systemd 服务文件,对应上方主启动文件使用 /opt/srs/trunk/objs/srs # 程序文件 /opt/srs/trunk/conf/srs.conf # 配置文件 /opt/srs/trunk/objs/srs.log # 日志文件 /opt/srs/trunk/objs/srs.pid # 进程 ID 文件
这几个文件之中,互相指向,所以当我们要改动相关路径时,务必同步配置文件的信息。
然后我们可以运行服务器了,手动启动的命令如下
/opt/srs/trunk/objs/srs -c /opt/srs/trunk/conf/srs.conf
但是实际上我们完全可以通过 主启动文件 进行管理。复制一个主启动文件,并修改五个选项配置
ROOT="/opt/srs/trunk/" APP="/opt/srs/trunk/objs/srs" CONFIG="/opt/srs/trunk/conf/srs.conf" DEFAULT_PID_FILE='/opt/srs/trunk/objs/srs.pid' DEFAULT_LOG_FILE='/opt/srs/trunk/objs/srs.log'
修改完毕后,直接运行即可(systemd 服务文件也可以直接拷贝过去并修改指向即可)
bash srs start
此时你就可以直接通过访问 http://localhost:8080/ 进行管理操作了。
然后分享时的链接如下,直接打开就能看。
http://localhost/players/srs_player.html?autostart=true&app=live&stream=livestream.flv&server=localhost&port=80&vhost=localhost&schema=http
如果涉及 SRS 配置文件,在测试过程中我生成了一份使用的配置文件,记录在此(改动多处文件位置)
listen 1935; max_connections 1000; srs_log_tank file; srs_log_file /opt/srs/log/srs.log; pid /opt/srs/run/srs.pid; daemon on; http_api { enabled off; listen 1985; raw_api { enabled off; allow_reload on; allow_query on; allow_update on; } } http_server { enabled on; listen 8080; dir /opt/srs/objs/nginx/html; } vhost localhost { tcp_nodelay on; min_latency on; play { gop_cache off; queue_length 10; mw_latency 100; } publish { mr off; } hls { enabled on; } http_remux { enabled on; mount [vhost]/[app]/[stream].flv; } enabled on; } vhost __defaultVhost__ { hls { enabled on; } http_remux { enabled on; mount [vhost]/[app]/[stream].flv; } } ff_log_dir /dev/null;
如果你需要从你原本的 Nginx 中代理 8080 端口,则需要在 原本的 Nginx 增加下面的代理站点配置。请注意安全性问题
server { listen 80; listen [::]:80; server_name localhost; access_log /var/log/nginx/lives.log; error_log /var/log/nginx/lives-error.log; location / { proxy_pass http://localhost:8080/; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; } }
3 、体验感想
RTMP 吃带宽,服务器带宽不够根本跑不快
HLS 高延迟,但多平台兼容性好
HLV 低延迟,但多平台兼容性差
WebAPI 更低延迟,但需要限定公网 IP 。
玩玩就好,真正想一起看电影,还得走视频会议。
如果 SRS 的 WebAPI 要是支持 Turn 服务器 就好了。
4 、参考链接
Enabling Video Streaming for Remote Learning with NGINX and NGINX Plus [ 链接 ]
How to setup Nginx+RTMP live stream server [ 链接 ]