如何在Ubuntu 22.04上使用Nginx-RTMP建立视频流服务器。
引言
流媒体视频有许多应用场景。像Twitch这样的服务提供商在处理网络发现和社区管理方面非常受欢迎,而像OBS Studio这样的免费软件则广泛用于实时合并多个不同流媒体源的视频覆盖层。虽然这些平台非常强大,但在某些情况下,您可能希望能够托管不依赖其他服务提供商的流媒体。
在本教程中,您将学习如何配置Nginx Web服务器来托管独立的RTMP视频流,该流可以在不同的应用程序中链接和观看。RTMP(实时消息传输协议)定义了大多数互联网视频流的基础知识。您还将学习如何使用相同的技术托管支持更现代平台的HLS和DASH流。
先决条件
完成本指南,您需要以下:
- An Ubuntu 22.04 server and a non-root user with sudo privileges. You can learn more about how to set up a user with these privileges in our Initial Server Setup with Ubuntu 22.04 guide.
- Nginx installed, following How To Install Nginx on Ubuntu 22.04.
本教程将使用占位符域名your_domain作为URL和主机名。在教程中进行操作时,请用您自己的域名或IP地址替换它。
第一步 – 安装和配置Nginx-RTMP
大多数现代流媒体工具都支持RTMP协议,该协议定义了互联网视频流的基本参数。Nginx网络服务器包含一个模块,允许您通过专用URL提供最小配置的RTMP流,类似于默认提供HTTP访问网页的方式。Nginx RTMP模块不会自动包含在Nginx中,但在Ubuntu 22.04和大多数其他Linux发行版上,您可以将其作为额外的软件包安装。
开始以非root用户身份运行以下命令来更新软件包列表并安装Nginx模块:
- sudo apt update
- sudo apt install libnginx-mod-rtmp
安装该模块并不会自动开始提供流。您需要在Nginx配置文件中添加一个配置块,定义流的位置和方式。
使用nano或者你喜欢的文本编辑器,打开Nginx的主配置文件/etc/nginx/nginx.conf,并在文件末尾添加以下配置块。
- sudo nano /etc/nginx/nginx.conf
. . .
rtmp {
server {
listen 1935;
chunk_size 4096;
allow publish 127.0.0.1;
deny publish all;
application live {
live on;
record off;
}
}
}
- listen 1935 means that RTMP will be listening for connections on port 1935, which is standard.
- chunk_size 4096 means that RTMP will be sending data in 4KB blocks, which is also standard.
- allow publish 127.0.0.1 and deny publish all mean that the server will only allow video to be published from the same server, to avoid any other users pushing their own streams.
- application live defines an application block that will be available at the /live URL path.
- live on enables live mode so that multiple users can connect to your stream concurrently, a baseline assumption of video streaming.
- record off disables Nginx-RTMP’s recording functionality, so that all streams are not separately saved to disk by default.
保存并关闭文件。如果你正在使用nano,按下CTRL+X,然后在提示时按Y和ENTER。
这是你的RTMP配置的开头。默认情况下,它监听在1935端口上,这意味着你需要在防火墙中打开该端口。如果你在初始服务器设置时配置了ufw,请运行以下命令。
- sudo ufw allow 1935/tcp
现在你可以使用你的更改重新加载Nginx。
- sudo systemctl reload nginx.service
你现在有一个正在工作的RTMP服务器。在下一部分中,我们将介绍如何从本地和远程源流式传输视频至你的RTMP服务器。
第二步 – 将视频发送到你的RTMP服务器。
有多种方法可以向RTMP服务器发送视频。其中一种选择是使用ffmpeg,这是一种常用的命令行音视频工具,可以直接在服务器上播放视频文件。如果服务器上没有视频文件,您可以使用youtube-dl这个命令行工具从像YouTube这样的流媒体平台下载视频。如果要使用youtube-dl,您还需要在服务器上安装最新版本的Python。
首先,安装Python及其软件包管理器pip。
- sudo apt install python3-pip
接下来,使用pip来安装youtube-dl。
- sudo pip install youtube-dl
现在你可以使用youtube-dl从YouTube下载视频。如果你还没想好视频,可以试试这个视频,介绍DigitalOcean的App平台。
- youtube-dl https://www.youtube.com/watch?v=iom_nhYQIYk -f mp4
Note
你的输出将会作为youtube-dl返回,它会将下载的视频和音频流合并为一个文件,这是正常的。
[youtube] iom_nhYQIYk: Downloading webpage [download] Destination: Introducing App Platform by DigitalOcean-iom_nhYQIYk.mp4 [download] 100% of 7.90MiB in 01:39
现在,在您的当前目录下有一个视频文件,标题类似于Introducing App Platform by DigitalOcean-iom_nhYQIYk.mp4。要进行流媒体播放,请安装ffmpeg。
- sudo apt install ffmpeg
并使用FFmpeg将其发送到您的RTMP服务器。
- ffmpeg -re -i “Introducing App Platform by DigitalOcean-iom_nhYQIYk.mp4” -c:v copy -c:a aac -ar 44100 -ac 1 -f flv rtmp://localhost/live/stream
这个ffmpeg命令正在对视频进行一些操作,以便将其准备为适合流媒体的格式。这并不是一个ffmpeg教程,所以你不需要过分关注它,但你可以将各种选项理解如下:
- -re specifies that input will be read at its native frame rate.
- -i “Introducing App Platform by DigitalOcean-iom_nhYQIYk.mp4” specifies the path to our input file.
- -c:v is set to copy, meaning that you’re copying over the video format you got from YouTube natively.
- -c:a has other parameters, namely aac -ar 44100 -ac 1, because you need to resample the audio to an RTMP-friendly format. aac is a widely supported audio codec, 44100 hz is a common frequency, and -ac 1 specifies the first version of the AAC spec for compatibility purposes.
- -f flv wraps the video in an flv format container for maximum compatibility with RTMP.
视频被发送到 rtmp://localhost/live/stream,这是因为您在第一步中定义了直播配置块,并且stream是此视频的随意选择的URL。
Note
当FFmpeg正在流式传输视频时,它会打印时间码。
frame= 127 fps= 25 q=-1.0 size= 405kB time=00:00:05.00 bitrate= 662.2kbits/s speed=frame= 140 fps= 25 q=-1.0 size= 628kB time=00:00:05.52 bitrate= 931.0kbits/s speed=frame= 153 fps= 25 q=-1.0 size= 866kB time=00:00:06.04 bitrate=1173.1kbits/s speed=
这是标准的ffmpeg输出。如果您正在将视频转换为不同的格式,这些信息可能有助于了解视频重采样的效率如何,但在这种情况下,您只想看到视频是否以一致的方式播放。使用这个示例视频,您应该得到确切的fps=25增量。
当FFmpeg正在运行时,您可以从视频播放器连接到您的RTMP流。如果您在本地安装了VLC、mpv或其他媒体播放器,您应该能够通过在媒体播放器中打开URL rtmp://your_domain/live/stream来查看您的流。在FFmpeg播放完视频后,您的流将终止。如果您希望它无限循环播放,您可以在FFmpeg命令的开始处添加-stream_loop -1。
Note
现在你已经学会了如何从命令行流式传输静态视频源,接下来你将学习如何使用台式电脑上的OBS从动态源流式传输视频。
第三步 – 通过OBS将视频流式传输到您的服务器(可选)
当你有一个准备好的视频想要播放回放时,通过ffmpeg进行流式传输非常方便,但是直播可以更加动态。直播流行的软件是OBS(Open Broadcaster Software)——它是免费、开源且非常强大的工具。
OBS 是一种桌面应用程序,它将从您的本地计算机连接到服务器。
安装OBS后,配置它意味着自定义你希望添加到直播中的桌面窗口和音频源,然后添加流媒体服务的凭据。本教程不涵盖你的流媒体配置,因为这是个人偏好问题,而默认情况下,你可以通过仅直播整个桌面来获得一个可用的演示。要设置流媒体服务的凭据,请打开OBS的设置菜单,转到流媒体选项,并输入以下选项:
Streaming Service: Custom
Server: rtmp://your_domain/live
Play Path/Stream Key: obs_stream
obs_stream 是一个随机选择的路径,在这种情况下,你的视频将可通过 rtmp://your_domain/live/obs_stream 进行访问。你不需要启用身份验证,但需要在第一步中配置的IP白名单中添加一个额外的条目。
回到服务器上,打开Nginx的主配置文件/etc/nginx/nginx.conf,并为您的本地IP地址添加一个额外的允许发布条目。如果您不知道您的本地IP地址,最好去类似于“What’s my IP”的网站,这样可以告诉您您的访问位置。
- sudo nano /etc/nginx/nginx.conf
. . .
allow publish 127.0.0.1;
allow publish your_local_ip_address;
deny publish all;
. . .
保存并关闭文件,然后重新加载Nginx。
- sudo systemctl reload nginx.service
你现在应该能够关闭OBS的设置菜单,并从主界面点击开始流式传输!尝试在媒体播放器中使用以前的方式查看你的流式传输:rtmp://your_domain/live/obs_stream。现在你已经了解了视频流式传输的基本原理,可以为你的服务器添加一些其他功能,使其更适用于生产环境。
第四步-将监控添加到您的配置中(可选)
现在你已经配置了Nginx来使用Nginx-RTMP模块进行视频流传输,一个常见的下一步是启用RTMP统计页面。与将更多配置细节添加到主要的nginx.conf文件中不同,Nginx允许你在一个名为sites-available/的子目录中的个别文件中添加每个站点的配置。在这种情况下,你将创建一个名为rtmp的配置文件。
- sudo nano /etc/nginx/sites-available/rtmp
加入以下内容:
server {
listen 8080;
server_name localhost;
# rtmp stat
location /stat {
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl {
root /var/www/html/rtmp;
}
# rtmp control
location /control {
rtmp_control all;
}
}
保存并关闭文件。此配置块中的stat.xsl文件用于在浏览器中样式化和显示RTMP统计页面。它是由之前安装的libnginx-mod-rtmp库提供的,但默认情况下是压缩的,所以您需要解压缩并将其放在/var/www/html/rtmp目录中以匹配示例配置。请注意,您可以在Nginx-RTMP文档中找到有关任何这些选项的其他信息。
创建 /var/www/html/rtmp 目录,然后使用以下命令解压 stat.xsl.gz 文件。
- sudo mkdir /var/www/html/rtmp
- sudo cp /usr/share/doc/libnginx-mod-rtmp/examples/stat.xsl /var/www/html/rtmp/stat.xsl
最后,要访问您添加的统计页面,您需要在防火墙中打开另一个端口。具体来说,监听指令已配置为端口8080,因此您需要添加一个规则以访问该端口上的Nginx。然而,您可能不希望他人能够访问您的统计页面,所以最好只允许您自己的IP地址进行访问。运行以下命令:
- sudo ufw allow from your_ip_address to any port http-alt
接下来,您需要激活这个新配置。Nginx的惯例是从sites-available/文件夹中创建符号链接(类似于快捷方式),指向另一个名为sites-enabled/的文件夹,以确定是否启用或禁用它们。为了清晰起见,请使用完整路径创建这个链接。
- sudo ln -s /etc/nginx/sites-available/rtmp /etc/nginx/sites-enabled/rtmp
现在你可以重新加载Nginx来处理你的更改:
- sudo systemctl reload nginx.service
你现在应该可以在浏览器中输入http://你的域名:8080/stat 来查看RTMP统计页面。当你正在观看流媒体视频时,访问并刷新该页面,观察流媒体统计数据如何变化。
现在你已经学会了如何监控你的视频流并将其推送给第三方提供商。在最后一部分,你将学习如何直接在浏览器中提供它,而不需要使用第三方流媒体平台或独立的媒体播放器应用程序。
第五步 – 为浏览器创建现代流(可选)
作为最后一步,您可能希望为较新的流媒体协议添加支持,使用户可以直接通过Web浏览器从您的服务器流式传输视频。有两种协议可用于创建基于HTTP的视频流:苹果的HLS和MPEG DASH。它们都有优点和缺点,所以您可能希望同时支持两种协议。
Nginx-RTMP 模块同时支持这两个标准。要在您的服务器上添加 HLS 和 DASH 支持,您需要修改 nginx.conf 文件中的 rtmp 块。使用 nano 或您喜欢的编辑器打开 /etc/nginx/nginx.conf,然后添加下面突出显示的指令。
- sudo nano /etc/nginx/nginx.conf
/etc/nginx/nginx.conf 可以翻译成:
– Nginx配置文件路径:/etc/nginx/nginx.conf
. . .
rtmp {
server {
. . .
application live {
live on;
record off;
hls on;
hls_path /var/www/html/stream/hls;
hls_fragment 3;
hls_playlist_length 60;
dash on;
dash_path /var/www/html/stream/dash;
}
}
}
. . .
保存并关闭文件。接下来,将此内容添加到您的sites-available/rtmp文件的底部。
- sudo nano /etc/nginx/sites-available/rtmp
. . .
server {
listen 8088;
location / {
add_header Access-Control-Allow-Origin *;
root /var/www/html/stream;
}
}
types {
application/dash+xml mpd;
}
Note
保存并关闭文件。请注意,这里使用的是8088端口,这是为了避免与您可能在端口80或443上运行的任何服务冲突,而在本教程中做出的另一个任意选择。目前您需要在防火墙中打开该端口。
- sudo ufw allow 8088/tcp
最后,在您的网站根目录中创建一个流目录,以与配置块相匹配,这样Nginx就能够生成HLS和DASH所需的文件。
- sudo mkdir /var/www/html/stream
请再次重启Nginx。
- sudo systemctl reload nginx
现在您应该可以在http://your_domain:8088/hls/stream.m3u8获得一个HLS流,并在http://your_domain:8088/dash/stream.mpd获得一个DASH流。这些端点会在您的RTMP视频源之上生成任何必要的元数据,以支持现代API。
结论
在此教程中使用的配置选项都在Nginx RTMP Wiki页面有所记载。通常,Nginx模块共享常见语法,并提供一套非常庞大的配置选项,您可以查看它们的文档以从这里更改任何设置。
几乎所有的互联网视频流媒体都是基于RTMP、HLS和DASH实现的,通过本教程中所探索的方法,您可以通过其他广播服务提供您的流媒体,或以您选择的任何其他方式公开它。接下来,您可以阅读如何将Nginx配置为反向代理,以便将这些不同的视频终端作为子域名提供给用户。