Nginx功能篇18—流媒体服务

概述

本章,您将学习到 Nginx 的流媒体服务。

Nginx 不仅是一个高性能的 Web 服务器,利用其他的模块,Nginx 也能作为流媒体服务器。

流媒体服务:允许用户通过网络实时传输和播放音频或视频内容,而无需等待整个文件下载完成,常用的协议包括 HLS (HTTP Live Streaming,是基于 HTTP 的流媒体协议,广泛用于移动设备和 Web 浏览器)和 RTMP (Real-Time Messaging Protocol,低延迟的流媒体协议,常用于直播场景)。

HLS 是苹果公司开发出的流媒体协议,其将视频文件分割成多个小片段(通常是 .ts 文件),并通过播放列表文件(.m3u8)来索引这些小片段。

RTMP 是由 Macromedia/Adobe 开发出的流媒体协议,这是一种基于 TCP 的协议,主要优点是稳定、兼容性强以及低延迟传输,现如今主要用在直播场景中(几乎所有主流直播平台的推流地址都以 rtmp:// 开头)。

推流与拉流

推流(Push stream):先通过显示器、摄像头、麦克风等方式采集到实时的音视频,经压缩编码后通过特定协议(RTMP、WebRTC、HLS、RTSP等)上传到媒体服务器的过程。这一过程可简述为:

  • 采集
  • 编码
  • 封装
  • 推送

拉流(Pull stream):指通过客户端从流媒体服务器上获取到音视频并进行播放的过程。这一过程可简述为:

  • 请求
  • 传输
  • 解码
  • 播放

Nginx 中的对流媒体协议的支持

在 Nginx 中要支持 HLS 和 RTMP 协议,需要使用到 nginx-rtmp-module 这个模块,这是 Github 的项目地址。

添加模块

关于 Nginx 模块的详细内容,参阅 模块的添加与使用 这篇文档。

在 Nginx 中使用动态模块的前置条件:

  • Nginx 的版本必须大于等于 1.9.11
  • nginx -V 命令的输出中 必须 包含 --with-compat 或显示支持 dynamic modules。若输出中缺少这些内容,您必须重新编译安装 Nginx,否则无法使用动态模块。
  • load_module 指令必须放在 main 上下文中且必须书写在 events 上下文的前面
  • Nginx 中动态模块对 ABI(‌Application Binary Interface‌,应用二进制接口)的要求极其严格,需要新手注意。您编译动态模块的环境必须与初始编译安装 Nginx 的环境(GCC 版本、PCRE 版本、OpenSSL 版本等)一致,否则后续容易出现 「module "xxx" is not binary compatible」 的错误
# 满足前置条件
Shell > /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.31.5
built by gcc 8.5.0 20210514 (Red Hat 8.5.0-28) (GCC)
built with OpenSSL 1.1.1k  FIPS 25 Mar 2021
TLS SNI support enabled
configure arguments: ... --with-compat

# 下载模块的归档压缩包
Shell > wget -c https://github.com/arut/nginx-rtmp-module/archive/refs/tags/v1.2.2.tar.gz

# 解压并提取
Shell > tar -xvf v1.2.2.tar.gz -C /usr/local/src/

# 编译成动态模块
Shell > cd /usr/local/src/nginx-1.31.5/
Shell > ./configure --with-compat --add-dynamic-module=/usr/local/src/nginx-rtmp-module-1.2.2 && make modules

# objs 目录下生成了 .so 文件
Shell > ls -l /usr/local/src/nginx-1.31.5/objs/ngx_rtmp_module.so
-rwxr-xr-x 1 root root 1656376 Sep 27 16:06 /usr/local/src/nginx-1.31.5/objs/ngx_rtmp_module.so

# 创建存放 .so 文件的目录
Shell > mkdir /usr/local/nginx/modules
Shell > mv /usr/local/src/nginx-1.31.5/objs/ngx_rtmp_module.so /usr/local/nginx/modules/

# 变更文件的所有者、所属组以及它们的权限
Shell > chown nginx:nginx /usr/local/nginx/modules/ngx_rtmp_module.so && chmod 755 /usr/local/nginx/modules/ngx_rtmp_module.so

使用模块

先在主配置文件 nginx.conf 中加载动态模块文件:

...
load_module modules/ngx_rtmp_module.so;

events {
    ...
}

http {
    ...
}

HLS 协议

在 /var/ 目录中新创建一个目录:

Shell > mkdir /var/stream/

# 变更所有者、所属组以及它们的权限
Shell > chown nginx:nginx /var/stream/ && chmod 755 /var/stream/

打开主配置文件 nginx.conf 文件,追加以下内容:

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

        location / {
            ...
        }
    }
}

rtmp {
    server {
        listen 1935; # RTMP 协议所使用的默认端口
        chunk_size 4096;

        application mylive {
            live on;
            hls on;
            hls_path /var/stream;
            hls_fragment 5;
            hls_playlist_length 60;
        }
    }
}

说明如下:

  • 定义一个 rtmp 上下文

  • 在 rtmp 上下文中定义一个 server 上下文

    • chunk_size 指令 - RTMP 消息分块(Chunk)的最大大小,单位为字节
  • 创建一个名为 mylive 的 RTMP 应用

  • live 指令 - 是否开启实时直播模式

  • hls 指令 - 在当前应用中是否启用 HLS 支持

  • hls_path 指令 - 指定 .ts 文件和 .m3u8 文件的存储路径

  • hls_fragment 指令 - 设置每个 .ts 文件的时长,单位为秒

  • hls_playlist_length 指令 - 设置 .m3u8 播放列表中保留的总时长,单位为秒

提示
需要注意的是,由于 HLS 协议是基于 http 协议的,因此只有上面的配置是不够的。

再在 http 上下文中新增一个 8080 端口的 server 上下文:

...
http {
    ...

    server {
        listen 80;
        ...
    }

    server {
        listen 443 ssl http2;
        ...
    }

    server {
        # 使用其他的端口号也可以
        listen 8080;
        server_name example.com live.example.com;

        location /stream {
            types {
                application/vnd.apple.mpegurl m3u8;
                video/mp2t ts;
            }

            root /var;
            add_header Cache-Control no-cache;
        }
    }
}

rtmp {
    ...
}

假设 IP 地址为 192.168.100.20,OBS 推流设置的 "流名称"(Stream Key)为 test,则拉流(拉流一般使用 VLC 播放器或 PotPlayer 播放器)地址为:

http://192.168.100.20:8080/stream/test.m3u8

重要说明如下:

  • 8080 端口对应于 server { listen 8080; ...}
  • /stream 对应于 location /stream { ... }
  • 由于 root /var; 的存在,Nginx 实际会去查找 /var/stream/test.m3u8 文件
  • hls_path 指令指定的目录路径应该与 location 上下文中的一致,即:

    • hls_path /var/stream
    • location /stream { ... root /var; } - Nginx 中的路径拼接,也就是 /var/stream

RTMP 协议

RTMP 协议只需要这部分配置即可:

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

        location / {
            ...
        }
    }
}

rtmp {
    server {
        listen 1935; # RTMP 协议所使用的默认端口
        chunk_size 4096;

        application mylive {
            live on;
            record off;
        }
    }
}
  • record 指令 - 是否开启录制功能,这里为关闭

假设 IP 地址为 192.168.100.20,则在推流端(如 OBS)的设置如下:

  • 服务器 - rtmp://192.168.100.20:1935/mylive
  • "串流密钥"(Stream Key)- test

拉流地址:

rtmp://192.168.100.20:1935/mylive/test
Avatar photo

关于 陸風睿

GNU/Linux 从业者、开源爱好者、技术钻研者,撰写文档既是兴趣也是工作内容之一。Q - "281957576";WeChat - "jiulongxiaotianci",Github - https://github.com/jimcat8
用一杯咖啡支持我们,我们的每一篇[文档]都经过实际操作和精心打磨,而不是简单地从网上复制粘贴。期间投入了大量心血,只为能够真正帮助到您。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇