这个模块允许 Nginx 直接支持 FLV (Flash Video) 格式,并通过 HTTP-FLV 协议实现低延迟的直播和点播,它也极大地优化了 MP4 的点播体验,支持 伪流,即可以拖动进度条到任意位置开始播放,而无需等待整个文件下载。

核心概念:伪流 vs. 真流
在开始之前,理解这两个概念非常重要:
-
伪流
- 原理:MP4 文件是一个容器,里面包含了多个
moov(元数据) 和mdat(媒体数据) 块,伪流技术通过在服务器端解析 MP4 文件,找到moov块并将其移动到文件的最前面,这样,播放器在请求时可以快速获取到视频的时长、分辨率等关键信息,并根据请求的时间点(如start=30)计算出对应的字节偏移量,直接从mdat块中读取数据开始播放。 - 优点:
- 实现简单,无需对现有 MP4 文件做特殊处理(只需一次预处理)。
- 普通 HTTP 服务器即可支持。
- 支持拖动进度条。
- 缺点:
- 每次拖动都需要服务器重新计算和响应,对服务器有一定开销。
- 对于非常大的文件,首次加载(获取
moov元数据)可能会慢一些。
- 原理:MP4 文件是一个容器,里面包含了多个
-
真流
- 原理:视频文件被分割成一系列小的、连续的片段(如
.ts文件),并生成一个索引文件(如.m3u8文件),播放器首先下载.m3u8文件,然后按顺序下载并播放各个.ts片段。 - 优点:
- 首次加载极快,因为索引文件非常小。
- 拖动非常高效,直接定位到对应的片段即可。
- 适合网络传输,可以轻松实现不同码率的自适应码率流。
- 缺点:
需要一个“转码”或“封装”的过程,将原始 MP4 文件转换成 HLS (m3u8) 或 DASH 格式,这需要额外的工具(如 FFmpeg)和存储空间。
(图片来源网络,侵删)
- 原理:视频文件被分割成一系列小的、连续的片段(如
Nginx + nginx-http-flv-module 主要优化了伪流体验,并增加了对 HTTP-FLV 直播的支持。
MP4 伪流点播服务器(推荐)
这是最常见的需求,即让用户可以在网页上直接播放 MP4 文件,并能拖动进度条。
步骤 1:安装 Nginx (带 nginx-http-flv-module)
你不能直接用 apt 或 yum 安装的 Nginx,因为它默认不包含这个模块,你需要自己从源码编译。
-
安装依赖
(图片来源网络,侵删)# CentOS / RHEL sudo yum groupinstall "Development Tools" sudo yum install pcre-devel zlib-devel openssl-devel git # Ubuntu / Debian sudo apt update sudo apt install build-essential libpcre3-dev zlib1g-dev libssl-dev git
-
下载 Nginx 源码和模块
# 下载 Nginx (请替换为最新稳定版) wget http://nginx.org/download/nginx-1.24.0.tar.gz tar -xzvf nginx-1.24.0.tar.gz # 下载 nginx-http-flv-module git clone https://github.com/winshu/nginx-http-flv-module.git
-
编译和安装
cd nginx-1.24.0 # 配置编译参数 # --add-module= 指向你下载的模块路径 ./configure --prefix=/usr/local/nginx \ --add-module=/path/to/nginx-http-flv-module \ --with-http_ssl_module \ --with-http_v2_module # 编译和安装 make sudo make install安装完成后,Nginx 可执行文件通常在
/usr/local/nginx/sbin/nginx。
步骤 2:配置 Nginx
编辑 Nginx 的配置文件,通常是 /usr/local/nginx/conf/nginx.conf。
user nobody;
worker_processes 1;
error_log logs/error.log warn;
pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
#======== MP4 伪流配置 ========#
server {
listen 80;
server_name localhost;
# 设置 MP4 文件根目录
location ~ \.mp4$ {
# 核心指令,启用 MP4 伪流
mp4;
# 可选:设置文件根目录
root html;
# 可选:默认文件名
index index.html;
# 可选:限制单个请求的速率,防止带宽被占满
limit_rate_after 5m;
limit_rate 512k;
}
# 可选:一个简单的测试页面
location / {
root html;
index index.html index.htm;
}
}
}
配置详解:
location ~ \.mp4$:匹配所有以.mp4结尾的 URL 请求。mp4;:这是最关键的指令,它告诉 Nginx 对这个 location 启用 MP4 伪流功能,Nginx 会自动处理moov元数据,并解析start参数。
步骤 3:准备测试文件和启动 Nginx
- 将你的 MP4 文件放到 Nginx 的
html目录下。/usr/local/nginx/html/my_video.mp4。 - 启动 Nginx:
/usr/local/nginx/sbin/nginx
- 访问
http://localhost/my_video.mp4,你可以在浏览器中直接打开,也可以在支持 HTML5 video 标签的网页中测试。
HTML5 测试代码示例 (index.html):
<!DOCTYPE html>
<html>
<head>MP4 Pseudo-Streaming Test</title>
</head>
<body>
<h1>MP4 Pseudo-Streaming Test</h1>
<video width="800" height="450" controls>
<!-- 注意这里的 URL,可以添加 start 参数来测试拖动 -->
<!-- http://localhost/my_video.mp4?start=30 -->
<source src="/my_video.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
</body>
</html>
你可以在浏览器中打开这个页面,视频播放器会加载,并且你可以拖动进度条到任意位置,视频会从该点开始播放。
低延迟直播服务器(HTTP-FLV)
这个方案需要有一个推流端(如 OBS、FFmpeg)将视频流推送到 Nginx,然后用户通过 Nginx 拉流观看。
步骤 1:安装 Nginx
安装过程与方案一完全相同,必须包含 nginx-http-flv-module。
步骤 2:配置 Nginx
在 nginx.conf 中添加直播相关的配置。
http {
# ... 其他配置 ...
#======== 直播流媒体配置 ========#
server {
listen 8080; # 直播服务监听端口
server_name localhost;
# HTTP-FLV 直播配置
location /live {
# 核心指令,启用直播功能
flv_live on;
# 设置直播流的应用名
chunked_transfer_encoding on; # 开启分块传输,对直播很重要
# 可选:设置 HLS 录制
hls on;
hls_path /usr/local/nginx/hls; # 录制文件存放目录
hls_fragment 3s; # 每个切片时长
hls_cleanup on; # 自动清理旧的录制文件
}
# 可选:配置 HLS 点播(录制后的文件)
location /hls {
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /usr/local/nginx;
add_header Cache-Control no-cache; # HLS 需要不缓存
}
}
}
配置详解:
listen 8080;:直播服务使用不同的端口,避免与普通 Web 服务冲突。location /live:所有推流和拉流的请求都以/live开头。flv_live on;:核心指令,启用 HTTP-FLV 直播模式。chunked_transfer_encoding on;:对于直播这种持续长连接的场景,开启分块传输是标准做法。hls on;:可选功能,开启 HLS 录制,这样直播流可以被录制下来,形成.m3u8和.ts文件供后续点播。
步骤 3:启动 Nginx 和推流
-
启动 Nginx:
/usr/local/nginx/sbin/nginx
-
使用 FFmpeg 推流: 假设你有一个视频文件
input.mp4,想推送到 Nginx 的my_live_stream这个流名。ffmpeg -re -i input.mp4 -c copy -f flv "http://localhost:8080/live?app=my_live_stream&stream=my_live_stream"
-re:以文件本身的帧率读取,模拟实时流。-i input.mp4:输入文件。-c copy:直接复制流,不做转码,速度最快。-f flv:指定输出格式为 FLV。http://...:推流地址。app和stream是自定义的应用名和流名。
-
观看直播: 使用支持 FLV 的播放器(如
flv.js)或 VLC 播放器,拉取流地址:http://localhost:8080/live?app=my_live_stream&stream=my_live_streamHTML5 + flv.js 示例:
<!DOCTYPE html> <html> <head> <title>Live Stream Test</title> <script src="https://cdn.jsdelivr.net/npm/flv.js@1.6.2/dist/flv.min.js"></script> </head> <body> <video id="videoElement" controls width="800" height="450"></video> <script> if (flvjs.isSupported()) { const videoElement = document.getElementById('videoElement'); const flvPlayer = flvjs.createPlayer({ type: 'flv', url: 'http://localhost:8080/live?app=my_live_stream&stream=my_live_stream' }); flvPlayer.attachMediaElement(videoElement); flvPlayer.load(); flvPlayer.play(); } </script> </body> </html>
总结与建议
| 特性 | MP4 伪流点播 | HTTP-FLV 直播 |
|---|---|---|
| 适用场景 | 存在大量 MP4 文件,用户可在线观看和拖动。 | 实时视频直播,如会议、教学、游戏直播。 |
| 核心模块 | nginx-http-flv-module (提供 mp4 指令) |
nginx-http-flv-module (提供 flv_live 指令) |
| 配置关键 | location ~ \.mp4$ { mp4; } |
location /live { flv_live on; } |
| 优点 | 配置简单,利用现有文件,拖动体验好。 | 延迟低(通常在 1-3 秒),协议成熟。 |
| 缺点 | 不适合实时直播,大文件首次加载可能慢。 | 需要推流端,服务器需持续处理长连接。 |
最终建议:
- 如果你只是想让网站上的 MP4 视频文件支持在线播放和拖动,方案一(MP4 伪流) 是最简单、最直接的选择。
- 如果你需要搭建一个低延迟的直播平台,方案二(HTTP-FLV 直播) 是非常好的选择,它比传统的 RTMP 直播在穿透性上更有优势(基于 HTTP),延迟也足够低。
- 对于更高要求的直播场景,可以结合 HLS 或 DASH,虽然延迟稍高(10-20秒),但兼容性最好,特别是移动端,这通常需要 FFmpeg 在推流时进行转码封装。
