Nginx 本身是一个高性能的 HTTP 和反向代理服务器,通过配合第三方模块(主要是 nginx-http-flv-module),它可以非常出色地处理 FLV/HLS 等格式的流媒体请求,实现直播、点播、拉流、推流等功能。

为什么选择 Nginx + nginx-http-flv-module?
在开始之前,我们先了解一下这个方案的优点:
- 高性能:Nginx 以其高并发、低内存消耗而闻名,非常适合作为流媒体服务器,能够处理大量的并发请求。
- 功能丰富:
nginx-http-flv-module提供了完整的流媒体功能,包括:- HLS (HTTP Live Streaming):将 FLV 实时流切片成 TS,生成 M3U8 播放列表,兼容性极好,支持几乎所有设备和浏览器(包括 iOS)。
- FLV 直播:直接通过 HTTP 协议进行 FLV 格式的直播播放。
- FLV 点播:支持 FLV 视频文件的在线播放。
- 拉流与推流:可以从其他 RTMP/FLV 服务器拉取直播流,也支持通过 HTTP POST 方式推流。
- HTTP-FLV 协议:一种基于长连接的 FLV 流协议,延迟极低(通常在 1-3 秒),比 HLS 延迟小得多,适合对实时性要求高的场景(如在线教育、游戏直播)。
- 易于集成:可以轻松与 Nginx 的其他功能(如负载均衡、防盗链)结合。
- 开源免费:Nginx 和
nginx-http-flv-module都是开源的,没有商业授权成本。
核心组件
- Nginx:Web 服务器,作为整个系统的核心。
nginx-http-flv-module:第三方 Nginx 模块,为 Nginx 添加了 FLV/HLS 流媒体处理能力。- FFmpeg:一个非常强大的多媒体处理工具,在直播场景中,它通常用于将摄像头捕获的视频/音频流(如 RTMP)转换为 FLV 格式,并推送到 Nginx 服务器。
- 流媒体播放器:用于播放视频流的客户端,常用开源播放器有:
- video.js:功能强大的 HTML5 视频播放器。
- flv.js:由阿里开源的纯 JavaScript HTML5 FLV 播放器,它通过 Media Source Extensions (MSE) API 在浏览器中播放 FLV,是配合
nginx-http-flv-module的绝佳选择。
环境准备与安装
我们将以在 Linux (CentOS 7) 系统上编译安装为例。
安装依赖
# 安装编译工具和必要的库 yum -y groupinstall "Development Tools" yum -y install pcre-devel openssl-devel zlib-devel
下载源码
我们需要下载 Nginx 源码和 nginx-http-flv-module 源码。
# 创建工作目录 mkdir -p /data/nginx_work cd /data/nginx_work # 下载 Nginx 源码 (以 1.18.0 为例,请选择较新稳定版) wget http://nginx.org/download/nginx-1.18.0.tar.gz tar -xzvf nginx-1.18.0.tar.gz # 下载 nginx-http-flv-module 源码 git clone https://github.com/winshining/nginx-http-flv-module.git
编译并安装 Nginx
关键一步是在 configure 命令中添加 nginx-http-flv-module。

# 进入 Nginx 源码目录 cd nginx-1.18.0 # 执行 configure 命令 # --add-module= 指向我们下载的 nginx-http-flv-module 路径 ./configure --prefix=/usr/local/nginx --add-module=../nginx-http-flv-module --with-http_ssl_module --with-http_v2_module --with-http_stub_status_module # 编译和安装 make make install
安装完成后,Nginx 会被安装到 /usr/local/nginx 目录下。
配置 Nginx 流媒体服务器
编辑 Nginx 的主配置文件 /usr/local/nginx/conf/nginx.conf。
这是一个完整的配置示例,包含了直播、点播、HLS 转码和防盗链等功能。
# /usr/local/nginx/conf/nginx.conf
user root; # 根据你的系统用户修改,如 nginx
worker_processes auto;
error_log logs/error.log notice;
pid logs/nginx.pid;
events {
worker_connections 1024;
}
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;
# FLV 直播/点播配置段
server {
listen 8080; # 监听端口,用于 HTTP-FLV 直播和点播
server_name localhost;
# 核心配置,启用 flv 模块
flv on;
# 直播流配置
location /live {
# 推流地址: rtmp://server_ip:1935/live/stream_key
# 播放地址: http://server_ip:8080/live?app=live&stream=stream_key
# flv_live on; # 如果需要更低的延迟,可以开启,但会增加服务器压力
chunked_transfer_encoding on; # 启用分块传输编码,适合长连接
# 防盗链配置 (示例)
valid_referers none blocked server_names *.example.com;
if ($invalid_referer) {
return 403;
}
}
# 点播配置
location /vod {
# 播放地址: http://server_ip:8080/vod/path/to/video.flv
alias /data/vod; # 指向你的视频文件存放目录
flv;
}
# HLS 转码配置 (可选)
location /hls {
# HLS 播放地址: http://server_ip:8080/hls/stream.m3u8
flv_live on;
hls on;
hls_path /tmp/hls; # HLS 片片存放目录
hls_fragment 3s; # 每个 TS 片段的时长
hls_playlist_length 60s; # M3U8 列表的总时长
}
# HTTP-FLV 播放器示例 (flv.js)
location /flvplayer {
alias /data/flvplayer; # 指向 flv.js 播放器文件存放目录
}
}
# RTMP 服务配置 (用于接收推流)
rtmp {
server {
listen 1935; # 标准的 RTMP 推流端口
chunk_size 4096;
application live {
live on; # 启用直播
# record off; # 不录制流
# record_path /data/rec; # 录制流存放路径
# record_unique on; # 录制文件名唯一
# record_all on; # 录制所有流
# HLS 转码
hls on;
hls_path /tmp/hls;
hls_fragment 3s;
hls_playlist_length 60s;
# 推流时进行转码 (示例)
# exec ffmpeg -i rtmp://localhost/live/$name -c:v libx264 -c:a aac -f flv rtmp://localhost/hls/$name;
}
}
}
}
配置说明:
rtmp块:定义了 RTMP 服务器,监听1935端口,用于接收来自 OBS、FFmpeg 等推流软件的流。application live:定义了一个名为live的应用,推流地址就是rtmp://your_server_ip:1935/live/+ 你的流密钥。server块:定义了 HTTP 服务器,监听8080端口,用于提供播放服务和 HLS 切片。location /live:处理 HTTP-FLV 直播流的请求,播放地址是http://your_server_ip:8080/live?app=live&stream=your_stream_key。location /vod:处理 FLV 点播请求。hls on:在 RTMP 应用或 HTTP location 中开启 HLS 转码,Nginx 会自动将接收到的 FLV 流切片成 TS 文件并生成 M3U8 播放列表。flv on:在 HTTP 的server或location块中开启 FLV 模块。
启动与使用
创建必要目录
# 创建 HLS 片段存放目录 mkdir -p /tmp/hls # 创建点播视频目录并放入一个示例视频 mkdir -p /data/vod # 将你的 .flv 文件放入 /data/vod 目录 # 创建 flv.js 播放器目录并下载播放器 mkdir -p /data/flvplayer cd /data/flvplayer wget https://github.com/Bilibili/flv.js/releases/download/1.6.2/flv.min.js
启动 Nginx
# 进入 Nginx 安装目录的 sbin 文件夹 cd /usr/local/nginx/sbin # 启动 Nginx ./nginx # 如果已启动,则重载配置 ./nginx -s reload
推流 (使用 FFmpeg)
假设你有一个视频文件 test.flv,想用它作为直播源推送到服务器。
# FFmpeg 命令示例 ffmpeg -re -i /path/to/your/test.flv -c copy -f flv rtmp://your_server_ip:1935/live/stream_key
-re:以帧率读取,模拟实时流。-i /path/to/your/test.flv:输入视频文件。-c copy:直接复制流,不做转码,速度最快。-f flv:指定输出格式为 FLV。rtmp://your_server_ip:1935/live/stream_key:推流地址,stream_key是你自定义的流密钥。
播放 (使用 flv.js)
在你的 HTML 页面中嵌入 flv.js 播放器来播放直播流。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">FLV.js Live Player</title>
<script src="/flvplayer/flv.min.js"></script>
<style>
video { width: 800px; height: 450px; background-color: #000; }
</style>
</head>
<body>
<video id="videoElement" controls autoplay></video>
<script>
if (flvjs.isSupported()) {
var videoElement = document.getElementById('videoElement');
var flvPlayer = flvjs.createPlayer({
type: 'flv', // 指定类型为 flv
url: 'http://your_server_ip:8080/live?app=live&stream=stream_key' // 播放地址
});
flvPlayer.attachMediaElement(videoElement);
flvPlayer.load(); // 加载
flvPlayer.play(); // 播放
} else {
alert('Your browser does not support flv.js');
}
</script>
</body>
</html>
将此 HTML 文件放在你的 Web 服务器(Nginx 的 html 目录)中,然后用浏览器访问即可看到直播画面。
总结与进阶
Nginx + nginx-http-flv-module 是一个非常灵活和强大的流媒体解决方案。
- 优点:高性能、低延迟(HTTP-FLV)、功能全面、易于部署。
- 缺点:需要手动编译 Nginx,配置相对复杂一些;对于大规模集群,可能需要结合专业的流媒体 CDN。
进阶方向:
- 集群与负载均衡:当单台服务器无法满足高并发需求时,可以搭建 Nginx RTMP 负载均衡集群。
- CDN 分发:将推流到中心节点,然后通过 CDN 分发到边缘节点,降低源站压力,提高全球用户的访问速度和稳定性。
- 更强大的转码:在 Nginx 配置中使用
exec指令调用 FFmpeg,实现直播流的实时转码(如分辨率、码率转换),以适应不同网络条件的用户。 - 录像与时移:通过配置
record相关指令,可以实现直播流的录制和时移回看功能。
希望这份详细的指南能帮助你成功搭建自己的 Nginx FLV 流媒体服务器!
