从零搭建NGINX+RTMP流媒体服务器:音视频小白也能看懂的多端推流实战
作为一名音视频开发者,我经常需要搭建一个轻量级的直播服务器来做测试。尝试过几款流媒体服务器后,发现最顺手、最不容易出错的还是NGINX + RTMP模块这套组合拳。但说实话,我第一次接触NGINX配置文件时也是一脸懵。http块、rtmp块、location……这些都是什么?为什么一个Web服务器还能处理视频流?如果你也有这些困惑,这篇博客就是为你准备的。我会从使用的角度出发,手把手教你配置一个能
关键词: 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推流(图形化工具)
-
打开OBS → 设置 → 推流
-
服务器:
rtmp://你的服务器IP:1935/live -
推流码:
test(可自定义) -
开始推流
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;
}
}
九、总结与资源
核心要点回顾
-
NGINX + RTMP模块 = 轻量级流媒体服务器
-
配置文件只有两大部分:
rtmp块(处理流媒体)+http块(提供Web访问) -
三种播放协议:RTMP(低延迟)、HLS(通用性强)、HTTP-FLV(折中选择)
-
核心应用场景:直播推流、多平台分发、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并不难,关键是理解推流→转发→拉流这条主线。
如果你在配置过程中遇到问题,欢迎在评论区留言交流。觉得有用的话,别忘了点赞+收藏,让更多需要的朋友看到。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐


所有评论(0)