关键词: NGINX配置 · RTMP推流 · HLS切片 · 多平台分发 · 音视频开发

前言:我为什么写这篇博客

作为一名音视频开发者,我经常需要搭建一个轻量级的直播服务器来做测试。尝试过几款流媒体服务器后,发现最顺手、最不容易出错的还是NGINX + RTMP模块 这套组合拳。

但说实话,我第一次接触NGINX配置文件时也是一脸懵。http块、rtmp块、location……这些都是什么?为什么一个Web服务器还能处理视频流?

如果你也有这些困惑,这篇博客就是为你准备的。我会从使用的角度出发,手把手教你配置一个能用的流媒体服务器,并提供完整的配置代码和逐行解释


一、NGINX是什么?它和音视频有什么关系?

1.1 传统认知 vs 音视频场景

大多数人对NGINX的印象是:一个高性能的Web服务器,用来做负载均衡、反向代理、托管静态网站。

但在音视频开发领域,NGINX配合nginx-rtmp-module模块后,可以秒变流媒体服务器。简单来说,它的作用就像是一个“视频中转站”:

text

主播/OBS/FFmpeg → 推流 → NGINX服务器 → 分发 → 观众(手机/电脑/浏览器)

1.2 NGINX流媒体的核心优势

特性 说明
轻量高效 事件驱动架构,单机可支撑数千并发
配置简单 一个nginx.conf搞定全部功能
多协议分发 RTMP拉流、HLS切片、HTTP-FLV统统支持
资源占用低 实测1核1G服务器轻松跑几十路流

1.3 工作原理解析

flowchart LR
    A[推流端<br>OBS/FFmpeg] -->|RTMP推流| B[NGINX + RTMP模块<br>端口:1935]
    B -->|直接分发| C[RTMP播放器<br>VLC/FFplay]
    B -->|切片成.m3u8+.ts| D[HLS分发<br>端口:8080]
    D --> E[Web浏览器<br>Video.js/H5]

一句话总结: 推流端把视频推到NGINX,NGINX负责存储、转发、切片,观众根据自己的设备选择合适的协议拉流观看。


二、搭建实战:从零开始配置

2.1 环境准备

  • 操作系统: Ubuntu 20.04 / CentOS 7+(本文以Ubuntu为例)

  • 服务器配置: 最低1核1G(个人测试完全够用)

  • 开放端口: 1935(RTMP)、8080(HTTP/HLS)

2.2 方式一:源码编译安装(推荐,最灵活)

这是最推荐的方式,可以自由定制NGINX版本和模块。

Step 1:安装编译依赖


sudo apt update
sudo apt install -y build-essential libpcre3 libpcre3-dev \
                    libssl-dev zlib1g-dev git wget

Step 2:下载源码

bash

# 下载NGINX稳定版(当前最新1.26.0)
wget https://nginx.org/download/nginx-1.26.0.tar.gz
tar -zxvf nginx-1.26.0.tar.gz

# 下载RTMP模块
git clone https://github.com/arut/nginx-rtmp-module.git

Step 3:编译安装

bash

cd nginx-1.26.0

./configure --prefix=/usr/local/nginx \
            --with-http_ssl_module \
            --add-module=../nginx-rtmp-module

make -j4           # 4核并行编译
sudo make install  # 安装到/usr/local/nginx

2.3 方式二:快速安装(适合体验)

Ubuntu/Debian可以用apt直接安装(优点是快,缺点是版本可能不是最新):

bash

sudo apt install nginx libnginx-mod-rtmp
# 配置文件位于 /etc/nginx/nginx.conf

三、核心配置:手把手写nginx.conf

3.1 配置文件结构概览

一个标准的NGINX+RTMP配置包含两大部分:

nginx

# 第一部分:RTMP流媒体配置(和http平级)
rtmp {
    server {
        # RTMP推拉流配置...
    }
}

# 第二部分:HTTP Web服务配置
http {
    server {
        # HLS切片访问、统计页面等...
    }
}

3.2 完整的生产级配置(可直接复制)

创建或编辑 /usr/local/nginx/conf/nginx.conf,写入以下内容:

nginx

# ============================================
# 用户和进程配置
# ============================================
user  nobody;
worker_processes  auto;   # 自动匹配CPU核心数
error_log  logs/error.log  info;
pid        logs/nginx.pid;

events {
    worker_connections  1024;  # 每个worker最大连接数
}

# ============================================
# RTMP流媒体核心配置
# ============================================
rtmp {
    server {
        listen 1935;           # RTMP默认端口
        chunk_size 4096;       # 数据块大小
        
        # ---------- 应用1:主推流域名 ----------
        application live {
            live on;           # 开启直播模式
            record off;        # 不录制到磁盘
            
            # 允许推流(默认允许所有,生产环境建议加鉴权)
            # allow publish 127.0.0.1;
            # deny publish all;
            
            # 开启HLS切片(可选,也可以单独开一个application)
            hls on;
            hls_path /tmp/hls;
            hls_fragment 2s;   # 每个切片2秒
            hls_playlist_length 6s;
            hls_cleanup on;    # 自动清理旧切片
        }
        
        # ---------- 应用2:纯HLS切片应用(更清晰的分工) ----------
        application hls {
            live on;
            hls on;
            hls_path /tmp/hls;
            hls_fragment 2s;
            hls_playlist_length 10s;
            hls_cleanup on;
            hls_continuous on;      # 切片连续模式
            hls_nested on;          # 按流名创建子目录
        }
        
        # ---------- 应用3:录制应用(回放场景) ----------
        application record {
            live on;
            record all;              # 录制所有推流
            record_path /tmp/recordings;
            record_unique on;        # 文件名自动加时间戳
            record_suffix -%Y%m%d_%H%M%S.flv;
        }
    }
}

# ============================================
# HTTP服务配置(提供HLS访问 + 统计页面)
# ============================================
http {
    include       mime.types;
    default_type  application/octet-stream;
    
    # 日志格式
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    
    access_log  logs/access.log  main;
    sendfile        on;
    keepalive_timeout  65;
    
    # 启用Gzip压缩
    gzip  on;
    gzip_types text/plain text/css application/json application/javascript;
    
    # ---------- 主虚拟主机 ----------
    server {
        listen 8080;
        server_name localhost;
        
        # 提供HLS切片文件访问
        location /hls {
            alias /tmp/hls;
            
            # 跨域支持(Web播放必须)
            add_header Access-Control-Allow-Origin *;
            add_header Access-Control-Allow-Methods 'GET, OPTIONS';
            add_header Access-Control-Allow-Headers 'Range';
            
            # 缓存控制
            expires -1;
            add_header Cache-Control no-cache;
            
            # .m3u8文件的MIME类型
            types {
                application/vnd.apple.mpegurl m3u8;
                video/mp2t ts;
            }
        }
        
        # RTMP服务器统计页面(强烈推荐!)
        location /stat {
            rtmp_stat all;
            rtmp_stat_stylesheet stat.xsl;
        }
        
        # 统计页面的样式(需要复制stat.xsl文件)
        location /stat.xsl {
            root /path/to/nginx-rtmp-module/;  # 改成你的模块路径
        }
        
        # 健康检查接口
        location /health {
            return 200 "OK\n";
            add_header Content-Type text/plain;
        }
        
        # 默认首页
        location / {
            root html;
            index index.html index.htm;
        }
    }
}

3.3 关键配置项逐行解释

配置项 作用 常见取值
listen 1935 RTMP服务监听端口 1935(标准),可改为其他
chunk_size RTMP数据块大小 4096~8192
live on 开启直播模式 on/off
record off 关闭录制(节省磁盘) all/off/audio/video/keyframes
hls on 开启HLS切片 on/off
hls_path HLS切片存放目录 需要确保nginx用户有写权限
hls_fragment 每个ts切片时长 2s~10s,越短延迟越低
add_header Access-Control-Allow-Origin * 解决跨域问题 开发环境用*,生产环境指定域名

四、启动测试与常用命令

4.1 启动NGINX

bash

# 创建HLS切片目录
mkdir -p /tmp/hls
chmod 777 /tmp/hls   # 确保nginx进程有写权限

# 启动服务器
/usr/local/nginx/sbin/nginx

# 如果是apt安装的
sudo systemctl start nginx

4.2 常用管理命令

bash

# 重新加载配置文件(不停服)
/usr/local/nginx/sbin/nginx -s reload

# 停止服务
/usr/local/nginx/sbin/nginx -s stop

# 优雅停止(处理完当前请求再停)
/usr/local/nginx/sbin/nginx -s quit

# 检查配置文件语法是否正确
/usr/local/nginx/sbin/nginx -t

# 查看nginx进程
ps aux | grep nginx

4.3 防火墙配置(重要!)

bash

# Ubuntu UFW
sudo ufw allow 1935/tcp
sudo ufw allow 8080/tcp

# CentOS firewalld
sudo firewall-cmd --permanent --add-port=1935/tcp
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --reload

# 云服务器还需要在安全组规则中开放这两个端口

五、推流与拉流实战

5.1 使用FFmpeg推流(本地文件循环推)

bash

# 推送本地视频文件到服务器(循环播放)
ffmpeg -re -i test.mp4 -c copy -f flv rtmp://你的服务器IP:1935/live/test

# 参数解释:
# -re    按真实帧率读取(模拟直播)
# -i     输入文件
# -c copy 不重新编码,直接复制(速度快)
# -f flv RTMP协议要求封装成FLV格式

5.2 使用OBS推流(图形化工具)

  1. 打开OBS → 设置 → 推流

  2. 服务器: rtmp://你的服务器IP:1935/live

  3. 推流码: test(可自定义)

  4. 开始推流

5.3 使用手机摄像头推流

推荐使用 Larix Broadcaster(iOS/Android都支持):

  • 服务器地址:rtmp://你的服务器IP:1935/live

  • 流名称:mobile

5.4 拉流播放(三种方式)

播放方式 地址 延迟 适用场景
VLC媒体播放器 rtmp://IP:1935/live/test 2-3秒 PC端、低延迟监控
浏览器(H5) http://IP:8080/hls/test.m3u8 5-10秒 网页通用播放
FFplay命令行 ffplay rtmp://IP:1935/live/test 2-3秒 快速调试

5.5 网页播放代码示例(HLS)

创建一个简单的HTML文件,用Video.js播放HLS流:

html

<!DOCTYPE html>
<html>
<head>
    <link href="https://vjs.zencdn.net/8.6.1/video-js.css" rel="stylesheet">
    <script src="https://vjs.zencdn.net/8.6.1/video.min.js"></script>
</head>
<body>
    <video id="my-video" class="video-js" controls preload="auto" width="800" height="450">
        <source src="http://你的服务器IP:8080/hls/test.m3u8" type="application/x-mpegURL">
        <p class="vjs-no-js">请启用JavaScript</p>
    </video>
    <script>
        var player = videojs('my-video');
    </script>
</body>
</html>

六、进阶技巧:多平台分发与RTSP转RTMP

6.1 一次推流,多平台分发(Push Relay)

这是最实用的功能之一。配置push指令后,推一路流到服务器,服务器自动帮你转发到B站、斗鱼、YouTube等多个平台:

nginx

rtmp {
    server {
        listen 1935;
        application live {
            live on;
            
            # 转发到B站直播(替换成你的地址和密钥)
            push rtmp://pili-live-rtmp.bilibili.com/live-bili/你的密钥;
            
            # 转发到斗鱼
            push rtmp://send3.douyu.com/live/你的房间号?token=你的密钥;
            
            # 转发到YouTube
            push rtmp://a.rtmp.youtube.com/live2/你的流密钥;
            
            # 备份到本地另一个应用
            push rtmp://127.0.0.1/live/backup;
        }
    }
}

6.2 RTSP摄像头 → RTMP推流

很多监控摄像头输出RTSP流,浏览器无法直接播放。用FFmpeg做中转:

bash

# 将RTSP流转换为RTMP推送到NGINX
ffmpeg -i rtsp://admin:password@192.168.1.100:554/stream1 \
       -c copy \
       -f flv \
       rtmp://localhost:1935/hls/camera

然后再访问 http://你的IP:8080/hls/camera.m3u8 就能在网页上看到监控画面了。

6.3 设置推流鉴权(防止被恶意推流)

nginx

application live {
    live on;
    
    # 只允许特定推流码
    on_publish http://localhost:8080/auth;
    
    # 或者用静态密钥
    # 推流地址:rtmp://ip/live?key=123456
    if ($arg_key != "123456") {
        return 403;
    }
}

配合一个简单的鉴权接口(Python Flask示例):

python

@app.route('/auth')
def auth():
    name = request.args.get('name')
    key = request.args.get('key')
    if key == 'your_secret_key':
        return 'OK'
    return 'Unauthorized', 403

七、常见问题排查(FAQ)

Q1:推流失败,提示“Connection refused”

原因: 端口未开放或NGINX未启动
解决:

bash

# 检查端口监听
netstat -tulnp | grep 1935

# 检查防火墙
sudo ufw status

# 查看nginx错误日志
tail -f /usr/local/nginx/logs/error.log

Q2:网页播放HLS提示“404 Not Found”

原因: HLS切片文件未生成或目录权限问题
解决:

bash

# 检查切片目录是否存在且可写
ls -la /tmp/hls/

# 赋予写权限
chmod 777 /tmp/hls

# 确认是否有推流正在运行
curl http://localhost:8080/stat

Q3:延迟太高(10秒以上)

  • HLS协议本身有5-10秒延迟,这是正常的

  • 降低hls_fragment到1-2秒可以稍微降低延迟

  • 如果追求低延迟(2-3秒),让客户端直接拉rtmp://

Q4:编译时报错“PCRE library not found”

bash

# Ubuntu/Debian
sudo apt install libpcre3-dev

# CentOS/RHEL
sudo yum install pcre-devel

Q5:服务器重启后HLS切片丢失

  • 这是正常的,HLS切片是临时文件

  • 如果需要持久化,配置record all录制到磁盘


八、性能调优建议

8.1 系统层面

bash

# 提高文件描述符限制
ulimit -n 65535

# 修改内核参数 /etc/sysctl.conf
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728

8.2 NGINX配置优化

nginx

# 增加worker进程和连接数
worker_processes auto;
worker_rlimit_nofile 65535;

events {
    worker_connections 4096;
    use epoll;
}

rtmp {
    server {
        # 增加缓冲区
        buflen 5s;
        # 增加超时时间
        timeout 30s;
        ping 30s;
        ping_timeout 10s;
    }
}

九、总结与资源

核心要点回顾

  1. NGINX + RTMP模块 = 轻量级流媒体服务器

  2. 配置文件只有两大部分rtmp块(处理流媒体)+ http块(提供Web访问)

  3. 三种播放协议:RTMP(低延迟)、HLS(通用性强)、HTTP-FLV(折中选择)

  4. 核心应用场景:直播推流、多平台分发、RTSP转码、监控调流

参考资源

资源 链接
NGINX官方文档 https://nginx.org/en/docs/
nginx-rtmp-module https://github.com/arut/nginx-rtmp-module
FFmpeg下载 https://ffmpeg.org/download.html
Video.js播放器 https://videojs.com/

写在最后

这篇博客从一个音视频开发者的使用角度出发,应该已经覆盖了你90%的使用场景。配置NGINX并不难,关键是理解推流→转发→拉流这条主线。

如果你在配置过程中遇到问题,欢迎在评论区留言交流。觉得有用的话,别忘了点赞+收藏,让更多需要的朋友看到。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐