RTMP 流的相关配置体验

2021-08-26 1772点热度 2人点赞

心血来潮,想和朋友一起看电影,但是电影比较不符合法律法规,所以迟迟想不好在哪里看。期间折腾 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 [ 链接 ]

StarryVoid

Have a good time