一、什么是 ngx_http_hls_module
ngx_http_hls_module
是 NGINX 商业订阅版提供的 HTTP Live Streaming (HLS) 服务器端支持模块,可直接对 .mp4
、.m4v
、.mov
、.qt
等 MP4/MOV 格式的媒体文件切片并输出 HLS .m3u8
播放列表与 .ts
片段。
- 支持编解码:H.264 视频、AAC/MP3 音频
- 零重打包:无需预先生成 TS 文件,按需切片
- 可选参数:按时间偏移、时长动态生成列表
二、模块编译与启用
-
前提:商业订阅版 NGINX 源码
-
编译参数
./configure \ --with-http_hls_module \ [其他模块选项…] make && make install
-
验证
nginx -V 2>&1 | grep hls # 应包含 --with-http_hls_module
三、核心指令详解
指令 | 作用 | |
---|---|---|
hls | 在 location 块中开启 HLS 支持 | |
hls_buffers <n> <size> | 读写 TS 片段时使用的缓冲区数量与单区大小 | |
**`hls_forward_args on | off`** | 将播放列表请求中的查询参数自动附加到 TS 片段 URI |
hls_fragment <time> | 默认切片时长(秒/时间单位),对应 .m3u8?len= 参数 | |
hls_mp4_buffer_size <size> | 初始内存缓冲区大小,用于解析 MP4/MOV 元数据 | |
hls_mp4_max_buffer_size <size> | 最大 MP4 缓冲区,解析大型 moov 原子时需增大此值 |
- 所有指令可在
http
、server
、location
上使用(hls
仅location
)。
四、基本配置示例
http {
server {
listen 8080;
server_name hls.example.com;
# 1) HLS 切片服务根目录
root /var/video;
location / {
hls; # 启用 HLS
hls_fragment 5s; # 默认 5 秒一片
hls_buffers 8 2m; # 8 个 2MB 缓冲区
hls_mp4_buffer_size 512k; # 初始 512KB
hls_mp4_max_buffer_size 10m; # 上限 10MB
}
}
}
-
对应文件
/var/video/movie.mp4
-
播放列表:
http://hls.example.com/movie.mp4.m3u8
-
片段:
http://hls.example.com/movie.mp4.ts?start=0.000&end=5.000
-
五、动态参数使用
-
start
&end
:指定播放区间(秒)/movie.mp4.m3u8?start=10&end=30
-
offset
:偏移起点offset=5
:从第 5 秒开始offset=-10
:倒数第 10 秒开始
-
len
:切片时长/movie.mp4.m3u8?len=8
-
片段 URI 可选
/movie.mp4.ts?start=10&end=18
六、携带原参数到片段(hls_forward_args
)
开启后,播放列表中的 TS URI 会自动附加原始查询参数,方便统一授权或打点。
location / {
hls;
hls_forward_args on;
}
示例:请求
/movie.mp4.m3u8?token=abc&lang=en
生成播放列表后,每行片段类似:
movie.mp4.ts?start=0.000&end=5.000&token=abc&lang=en
七、流媒体安全:结合 ngx_http_secure_link_module
通过 HLS Forward Args,并配合 Secure Link,能动态校验每个片段的访问合法性。
http {
# 提取 base URI
map $uri $hls_uri {
~^(?<base>.*)\.m3u8$ $base;
~^(?<base>.*)\.ts$ $base;
default $uri;
}
server {
...
location /hls/ {
hls;
hls_forward_args on;
alias /var/videos/;
# Secure Link 设置
secure_link $arg_md5,$arg_expires;
secure_link_md5 "$secure_link_expires$hls_uri$remote_addr mysecret";
if ($secure_link = "") { return 403; }
if ($secure_link = "0") { return 410; }
}
}
}
- 所有
.m3u8
与.ts
请求都需带上?md5=…&expires=…
,片段 URI 同样校验。
八、性能与调优
场景 | 建议配置 |
---|---|
小文件、高并发 | hls_buffers 4 1m ,减小缓冲区减少内存占用 |
长视频、大 moov 原子 | hls_mp4_max_buffer_size 50m |
受限内存部署 | hls_mp4_buffer_size 256k |
云端对象存储 | 关闭 hls_mp4_* ,先使用本地打包工具生成 TS |
九、客户端播放测试
-
VLC / ffplay:
ffplay http://hls.example.com/movie.mp4.m3u8
-
JavaScript 播放器:
使用 hls.js:<video id="video" controls></video> <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script> <script> const video = document.getElementById('video'); if (Hls.isSupported()) { const hls = new Hls(); hls.loadSource('http://hls.example.com/movie.mp4.m3u8'); hls.attachMedia(video); } </script>
十、常见问题与解答
-
500 错误:
moov atom is too large
- 增大
hls_mp4_max_buffer_size
,或预先使用ffmpeg -movflags faststart
重排moov
。
- 增大
-
播放列表延迟
- 减小
hls_fragment
时长(如2s
),限制 TS 时长。
- 减小
-
内存抖动
- 调整
hls_buffers
与hls_mp4_buffer_size
,确保平衡吞吐与内存。
- 调整
十一、结语
通过本文,你已掌握如何使用 NGINX 商业版的 ngx_http_hls_module
:
- 零打包:动态切片无需多余转码
- 参数化:按需指定播放区间和时长
- 安全控流:结合 Forward Args 与 Secure Link
- 性能调优:缓冲区和 MP4 解析配置
部署高效、可控、安全的 HLS 流媒体服务,从此变得轻而易举。欢迎在评论区分享你的实践经验或遇到的挑战!