使用 NGINX 搭建 RTMP 流媒体服务器实现直播功能

使用 NGINX 搭建 RTMP 流媒体服务器实现直播功能

本文介绍了如何使用 Nginx 搭建 RTMP 流媒体服务器,并提供配置文件和前端示例,实现直播功能。

环境

操作系统: Ubuntu 18.04 LTS (bionic), WSL
Nginx 版本: nginx/1.14.0
推流工具: OBS Studio 24.0.3 (64bit, Windows)
拉流工具: VLC Portable
HTML 播放器: Video.js 7.8.4

注意

本文所有内容不提供任何担保
知识共享许可协议
本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。

1. 安装或重新安装 NGINX

1.1 如果需要,则卸载 NGINX

如果您之前使用了 apt 安装了 nginx,请运行以下命令来卸载这个版本。如果您同时运行这个版本的 nginx 和稍后编译安装的 nginx,将会发生冲突。

sudo apt-get remove nginx nginx-core nginx-extras nginx-full nginx-light
1.2 如果需要,则下载 NGINX

如果您从未下载过 nginx,请 cd 到一个用于保存下载的目录,并下载 nginx。使用如下命令下载 nginx-1.14.0.tar.gz。您可以访问 https://nginx.org/download/ 找到其他版本。

wget https://nginx.org/download/nginx-1.14.0.tar.gz
1.3 克隆 nginx-rtmp-module

将 nginx-rtmp-module 的源代码克隆到本地。

git clone https://github.com/arut/nginx-rtmp-module.git
1.4 安装 NGINX 依赖

有关 nginx 依赖安装的详细问题,请参考 nginx documentation 官方文档或查询有关帮助。

sudo apt-get install gcc g++ gdb zlib openssl libssl-dev libpcre3 libpcre3-dev zlib1g-dev
1.5 编译 NGINX

请先通过以下命令解压 nginx-x.xx.x.tar.gz。如果不是,请将 nginx-1.14.0.tar.gz 改为您的文件名,下同。

tar -zxvf nginx-1.14.0.tar.gz

然后,请进入该目录。

cd nginx-1.14.0

接下来,请执行 configure,并附加以下条件。

sudo ./configure --prefix=/usr/local/nginx --add-module=../nginx-rtmp-module

其中,--prefix=/usr/local/nginx 可选,意为将 nginx 的目录前缀改为 /usr/local/nginx;--add-module=../nginx-rtmp-module 必须,意为 添加 nginx-rtmp-module 模块,其中 ../nginx-rtmp-module 是您在 1.2 中的克隆目录。有关 configure 的详细信息,您可以访问 nginx 的官方文档

接着,请使用如下命令编译和安装 nginx。

make # 编译

sudo make install # 安装
# 请注意! 如果您之前安装过 nginx, 执行 make install 命令将可能覆盖旧版。此时,请复制当前目录下 objs/ 的文件到指定的文件夹。

如果需要,您可以将 nginx 加入环境变量以方便使用。

1.6 检查安装

到 /usr/local/nginx/sbin 或您刚设置的 prefix 目录下的 sbin,执行如下命令查看 nginx 版本。

nginx -V

# 您应看到类似于如下的内容
nginx version: nginx/1.14.0
built by gcc 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)
built with OpenSSL 1.1.1  11 Sep 2018
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --add-module=../nginx-rtmp-module
1.7 启动 NGINX
sudo ./nginx

如果 nginx 正确启动,您可访问 localhost 看到 Welcome to nginx! 页面。

2. 更改配置文件

sudo vi /usr/local/nginx/conf/nginx.conf # 在编辑前,建议您备份

http { ... } 添加如下内容

rtmp {
   server {
        listen 1935; # 监听 1935 端口
        chunk_size 4000; # 分块传输
        application streaming { # 请将 streaming 改为推流请求路径,例如可以改成 hls 等
                live on; # 开启实时
                hls on; # 开启 hls
                hls_path /usr/local/nginx/html/streaming; # rtmp推流请求和保存文件的路径,和上文 application 后的路径相同
                hls_fragment 5s; # 规定每个 TS 文件包含 5s 的视频内容
                wait_key on; # 对视频切片进行保护,防止马赛克
                hls_cleanup on; # 清理多余切片
                hls_playlist_length 60s; # 可回放 60s 视频长度
                hls_continuous on; # 连续模式
                hls_nested on; # 嵌套模式
           }
       }
}

将下列内容加入到 http { server { ... } } 之中

# http {
#    ...
#    server {
#       ...

        # 以下内容可选,用于查看直播统计信息
        location /stat { 
            rtmp_stat all;
            rtmp_stat_stylesheet stat.xsl;
        }

        location /stat.xsl { 
                root /usr/local/nginx/nginx-rtmp-module/; # 请将这个路径改为您在步骤 1.3 中克隆的路径,并确保 stat.xsl 在这个文件夹下
        }
        # 这部分内容结束
        # -----------------
        # 以下内容必须
        location /streaming {  # 请确保这个路径和上文在 http {...} 前的 application 字段中的两个推流请求路径相同
                types {
                        application/vnd.apple.mpegurl m3u8;
                        video/mp2t ts;
                        text/html;
                }
                default_type text/html;
                alias /usr/local/nginx/html/streaming; # 亦需和上述推流请求路径相同
                expires -1;
                add_header Cache-Control no-cache;
                index index.html;
        }
        # 这部分必须内容结束

#   ...
#   }
# }

之后,重启 nginx 以刷新配置。

sudo ./nginx -s reload 

3. 编写前端代码

m3u8 格式通常可以在手机和 Safari 浏览器打开,而无法在其他浏览器打开,因此需要 Video.js 解码。

首先,需要下载 Video.js 用于实现在电脑上解码 m3u8,请到 Releases - videojs/video.js - GitHub 下载。

3.1 目录结构
├── live # 直播的前端部分
│   ├── index.html # 用于跳转桌面版或手机版
│   ├── desktop # 桌面版
│   │   └── index.html
│   └── m # 手机版
│       └── index.html
├── streaming # 推流请求目录
│   │── xxx.ts
│   └── index.m3u8
└── video-js-7.8.4

live 文件夹用于存放 HTML 等,其中 live/index.html 用于跳转到桌面还是手机网页。

3.2 live/index.html
<!DOCTYPE html>
<head>
        <meta charset="UTF-8">
        <title>Redirecting...</title>
        <style>
                body {
                        width: 45em;
                        margin: 0 auto;
                        font-family: Tahoma, Verdana, Arial, sans-serif;
                }
        </style>
</head>
<body>
        <h1>If this page is not responding, please confirm your browser is accepting Javascript.</h1>
        <hr>
        <p>If you are using a desktop computer, please click <a href="../live/desktop/">here</a> to redirect.</p>
        <p>If you are using a mobile device, please click <a href="../live/m/">here</a> to redirect.</p>
        <p>A mobile device is supposed to accept m3u8 format.</p>
        <br>
        <br>
        <h1>如果看到此页,请确认浏览器允许运行Javascript。</h1>
        <hr>
        <p>如果您在使用桌面计算机,请点击<a href="../live/desktop/">此处</a>以重定向。</p>
        <p>如果你在使用移动设备,请点击<a href="../live/m/">此处</a>以重定向。</p>
        <p>移动设备应该支持m3u8格式。</p>
<script type="text/javascript">
        var system ={};
        var p = navigator.platform;
        system.win = p.indexOf("Win") == 0;
        system.mac = p.indexOf("Mac") == 0;
        system.x11 = (p == "X11") || (p.indexOf("Linux") == 0);
        if(system.win||system.mac||system.xll){ //Desktop
                window.location.href="../live/desktop/"
        }else{ //Mobile
                window.location.href="../live/m/";
        }
</script>
</body>
3.3 live/desktop/index.html
<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <title>直播</title>
    <link href="https://vjs.zencdn.net/7.4.1/video-js.css" rel="stylesheet" />
  </head>

  <body>
	  <h1>直播</h1>
	  <br>
	  <p>如果您在使用支持m3u8的设备,请尝试<a href="../m">移动版</a>直播。</p>
	  <hr>
	  <br>
    <video id="myVideo" class="video-js vjs-default-skin vjs-big-play-centered" controls autoplay preload="auto" width="1920" height="1080" data-setup="{}">
      <source id="source" src="http://localhost/streaming/index.m3u8" type="application/x-mpegURL"/>
    </video>
  </body>
  <script src="https://vjs.zencdn.net/7.4.1/video.js"></script>
</html>
3.4 live/m/index.html
<!DOCTYPE html>
<head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
        <title>直播 - 移动版</title>
        <style>
                body {
                        width: 20em;
                        margin: 0 auto;
                        font-family: Tahoma, Verdana, Arial, sans-serif;
                }
        </style>
</head>
<body>
        <h1>直播</h1>
        <hr>
        <p>欢迎访问手机版直播!</p>
        <video src="/streaming/index.m3u8" controls="controls" width="320" height="240">
                您的浏览器不支持 video 标签,或者您的设备无法解码 m3u8 格式。请访问 <a href="../desktop/">桌面版网页</a> 尝试使用 Javascript 解码。
        </video>
        <br>
        <br>
        <br>
        <hr>
        <p>如果无法观看,请访问 <a href="../desktop/">桌面版网页</a> 尝试使用 Javascript 解码。</p>
</body>

4. 推流和拉流

4.1 推流

如果您需要 OBS Studio 的详细安装步骤,请参阅我的这篇博客:使用OBS配置虚拟摄像头

使用 OBS Studio 推流,设置如图。

OBS Settings
然后开始推流,即可看到服务器已经产生 TS 片段,继而产生 index.m3u8。访问 http://localhost/live/ ,即可看到直播画面。

4.2 拉流

如果您使用能播放网络流媒体的播放器拉流,请注意将网络 URL 地址写为推流请求地址 (例如 rtmp://localhost/streaming),而非上文的 http://localhost/live/。

VLC

此处使用的图片是视频【2018洛天依庆生会】一花依世界(bilibili音乐出品/国风电子)  (BV1Vs411H7JH)   出品:bilibili音乐@哔哩哔哩音乐姬
华夏风韵,洛水天依

5. Just a moment …

至此,已完成使用 nginx 搭建 RTMP 流媒体服务器,实现了直播的功能。

接下来,您应该考虑以下问题

  • 使访问 /stat 需要授权

    首先,安装 htpasswd

    sudo apt-get install apache2-utils
    

    然后,修改上文 location /stat

     location /stat {
                auth_basic "User Authentication";
                auth_basic_user_file /usr/local/nginx/htpasswd;
                rtmp_stat all;
                rtmp_stat_stylesheet stat.xsl;
            }
    

    最后,重启 nginx

    sudo ./nginx -s reload
    
  • 推流时索要 Stream Key 和授权

    注意: 以下方法尚未验证可行性,请查阅其他资料。

    rtmp {
       server {
            listen 1935; # 监听 1935 端口
            chunk_size 4000; # 分块传输
            application streaming { # 请将 streaming 改为推流请求路径,例如可以改成 hls 等
                    live on; # 开启实时
                    
                    # 添加授权开始
                    on_publish xxx; # 当推流将要开始时请求xxx,来实现授权
                    # 添加授权结束
                    
                    hls on; # 开启 hls
                    hls_path /usr/local/nginx/html/streaming; # rtmp推流请求和保存文件的路径,和上文 application 后的路径相同
                    hls_fragment 5s; # 规定每个 TS 文件包含 5s 的视频内容
                    wait_key on; # 对视频切片进行保护,防止马赛克
                    hls_cleanup on; # 清理多余切片
                    hls_playlist_length 60s; # 可回放 60s 视频长度
                    hls_continuous on; # 连续模式
                    hls_nested on; # 嵌套模式
               }
           }
    }
    
  • 优化 UI / UX

  • 其他……

6. Enjoy it, if you are all set.

如果一切就绪,则流媒体服务器搭建完毕!

本文不提供任何担保。


知识共享许可协议
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议进行许可。
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值