提示

返回博客列表

HLS 流媒体全链路拆解:m3u8 切片、AES 加密、nginx 分发与播放排错

HLS 流媒体全链路拆解:m3u8 切片、AES 加密、nginx 分发与播放排错

HLS(HTTP Live Streaming)是今天点播和直播最普遍的传输协议之一。本文从"一段 MP4 怎么变成 m3u8 + ts 分片"讲起,一路讲到 AES-128 加密、nginx 分发和播放端常见排错,帮你把流媒体全链路吃透。

一、HLS 是什么

HLS 把视频切成一堆几秒长的小分片(通常是 .ts.fmp4),再用一个 .m3u8 索引文件按顺序列出来。播放器先拉 m3u8,再按列表逐个下载分片播放。好处是:

  • 天然适配 HTTP/CDN,不怕防火墙;
  • 支持自适应码率(多份分片,网络差自动降清);
  • 边下边播,秒开体验好。

二、m3u8 与分片结构

一个最基础的 VOD m3u8 长这样:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:10
#EXTINF:10.0,
seg0.ts
#EXTINF:10.0,
seg1.ts
#EXT-X-ENDLIST

#EXT-X-ENDLIST 表示点播结束;直播则没有它,播放器会不断轮询刷新。

2.1 VOD 与 Live 的区别

维度 点播 VOD 直播 Live
是否有 ENDLIST
分片是否变化 固定 滚动追加
播放器行为 顺序播完 持续追新
时移 不支持 可保留滑动窗口

三、用 FFmpeg 切片生成 HLS

3.1 基础切片

ffmpeg -i in.mp4 -c:v h264 -c:a aac -hls_time 10 ^
  -hls_list_size 0 -hls_segment_filename seg%d.ts index.m3u8
  • -hls_time 10:每片约 10 秒;
  • -hls_list_size 0:保留全部分片(点播);直播设为窗口大小;
  • 输出 index.m3u8 即为索引。

3.2 多码率自适应(Master Playlist)

生成 1080p / 720p / 480p 三档,再用 master playlist 串起来:

ffmpeg -i in.mp4 \
  -map 0:v:0 -map 0:a:0 -b:v:0 3000k -s:v:0 1920x1080 -profile:v:0 high \
  -map 0:v:0 -map 0:a:0 -b:v:1 1500k -s:v:1 1280x720  -profile:v:1 main \
  -map 0:v:0 -map 0:a:0 -b:v:2 800k  -s:v:2 854x480   -profile:v:2 baseline \
  -f hls -var_stream_map "v:0,a:0 v:1,a:0 v:2,a:0" \
  -master_pl_name master.m3u8 -hls_segment_filename v%v/seg%d.ts v%v/index.m3u8

播放器读 master.m3u8,根据用户带宽切换 v0/v1/v2

四、AES-128 加密与密钥分发

HLS 原生支持 #EXT-X-KEY 对分片加 AES-128:

ffmpeg -i in.mp4 -hls_time 10 -hls_key_info_file keyinfo.list index.m3u8

keyinfo.list 内容为:

http://example.com/key/key.bin
/path/local/key.bin

密钥通过 HTTP 下发。要"防盗链",关键是密钥接口做鉴权

  • URL 带临时 token,校验通过才返回 key;
  • 回源校验 Referer / IP 白名单;
  • 密钥定期轮换,老分片失效。

提醒:AES-128 保护的是"传输层不让轻易下载整段",不是内容版权的最终方案;合规使用、尊重版权始终是前提。

4.1 防盗链:URL 鉴权 + 回源校验

在 nginx 上对 /key//v*/auth_request 子请求校验:

location /key/ {
    auth_request /auth_key;
    ...
}
location = /auth_key {
    internal;
    proxy_pass http://auth-backend/verify?$args;
}

五、用 nginx 分发 HLS

5.1 MIME 与 CORS

types {
    application/vnd.apple.mpegurl m3u8;
    video/mp2t ts;
}
location /hls/ {
    add_header Access-Control-Allow-Origin *;
    add_header Cache-Control "max-age=3600";
}

m3u8 的 MIME 必须是 application/vnd.apple.mpegurl,否则部分播放器拒绝解析。

5.2 断点续传与 Range 支持

分片要支持 Range 请求(nginx 默认 Accept-Ranges: bytes),否则拖动进度条会重新下载整片:

location /hls/ {
    mp4;
    flv;
}

六、播放端排错

现象 可能原因 排查
跨域报错 缺 CORS 头 nginx 加 Access-Control-Allow-Origin
403 密钥/分片鉴权失败 检查 token、Referer 白名单
卡顿 分片过大或码率过高 减小 -hls_time、降码率
花屏 关键帧间隔大 -g 30 缩短 GOP
直播延迟高 分片时长 + 列表窗口 用 LL-HLS 或减小分片

缩短 GOP 让切片更密,能改善seek 体验:

ffmpeg -i in.mp4 -g 30 -hls_time 4 index.m3u8

七、下载与本地备份的合规边界

HLS 把内容切成公开 URL,技术上可以逐片下载再 cat 合并。但请注意:

  • 仅对自己拥有版权或已授权的内容做备份/离线;
  • 不要绕过付费/鉴权批量抓取他人付费内容;
  • 尊重平台的 robots 与服务条款。

VidDown 的定位是"帮用户更方便地处理自己有权使用的媒体",合规是底线。

八、小结

HLS 全链路 = 切片(FFmpeg)→ 索引(m3u8)→ 加密(AES-128 + 鉴权 key)→ 分发(nginx + CORS/Range)→ 播放(自适应切换)。每一环都有明确的排错抓手,按本文表格逐项核对,绝大多数"播不了/卡顿/403"都能快速定位。

想亲手试试?用 VidDown 一键解析下载

粘贴视频链接即可解析,多平台支持、网页端即用;下载桌面客户端解锁海外平台本地解析,开通会员更享不限次下载。

顶部