配置的核心逻辑是 **“按需缓存”**:只有当用户实际访问某个 ts 文件(比如视频播放到对应分片时),Nginx 才会回源拉取该 ts 文件并缓存;而 m3u8 文件本身会被缓存,但 Nginx 原生功能无法主动 “解析 m3u8 内容、批量预加载所有 ts”—— 这个 “主动预加载” 能力需要依赖之前的 Lua 脚本,而当前纯 Nginx 方案已移除 Lua 依赖,因此不具备自动解析 m3u8 并缓存所有 ts 的功能。
为什么不自动预加载?
Nginx 原生模块(如proxy_cache)仅能对 “用户实际发起的请求” 进行缓存,无法主动分析文件内容(如解析 m3u8 中的 ts 路径)并发起额外请求。要实现 “解析 m3u8→批量缓存 ts”,必须借助 Lua、Python 等脚本语言的逻辑处理能力,而当前方案为了规避 Lua 模块依赖,选择了纯 Nginx 原生配置,因此牺牲了 “主动预加载” 能力,仅保留 “被动按需缓存”。
如果希望接近 “自动缓存所有 ts” 的效果,且不依赖 Lua,可通过 **“定时脚本主动访问 ts”** 实现(需手动维护热门 m3u8 列表),示例如下:
1. 编写 Shell 预加载脚本(prefetch_ts.sh)
#!/bin/bash
# 热门m3u8列表(需根据实际业务补充)
m3u8_urls=(
"https://dy1.51fxzq.com/2022/10/13/WetPalms1/index.m3u8"
"https://dy2025.51fxzq.com/2025/08/09/3fbcc2a4/index.m3u8"
)
# 循环访问每个m3u8,解析并预加载ts
for m3u8 in "${m3u8_urls[@]}"; do
# 1. 拉取m3u8内容
m3u8_content=$(curl -s "$m3u8")
if [ -z "$m3u8_content" ]; then
echo "拉取m3u8失败:$m3u8"
continue
fi
# 2. 解析m3u8中的ts路径(提取非注释行的.ts路径)
ts_paths=$(echo "$m3u8_content" | grep -v "^#" | grep -E "\.ts$" | sed 's/^[ \t]*//;s/[ \t]*$//')
if [ -z "$ts_paths" ]; then
echo "未找到ts路径:$m3u8"
continue
fi
# 3. 循环预加载每个ts(用curl发起请求,触发Nginx缓存)
echo "开始预加载m3u8的ts:$m3u8"
echo "$ts_paths" | while read -r ts; do
# 处理相对路径(拼接完整URL)
if [[ "$ts" != http* ]]; then
# 提取m3u8的基础路径(如https://dy1.51fxzq.com/2022/10/13/WetPalms1/)
base_url=$(echo "$m3u8" | sed -E 's|/[^/]*\.m3u8$|/|')
ts_url="${base_url}${ts}"
else
ts_url="$ts"
fi
# 发起HEAD请求(仅触发缓存,不下载完整文件,节省带宽)
curl -s -I -X HEAD "$ts_url" > /dev/null
if [ $? -eq 0 ]; then
echo "预加载成功:$ts_url"
else
echo "预加载失败:$ts_url"
fi
done
done
2. 设置定时任务(每天凌晨执行,预加载热门 ts)
# 编辑定时任务
crontab -e
# 添加以下内容(每天2点执行预加载)
0 2 * * * /path/to/prefetch_ts.sh > /var/log/prefetch_ts.log 2>&1
3. 脚本效果
- 每天凌晨自动拉取配置好的 m3u8 文件,解析所有 ts 路径;
- 通过
curl -I(HEAD 请求)触发 Nginx 回源并缓存 ts,无需下载完整文件,节省带宽; - 后续用户访问时,所有 ts 已提前缓存,实现 “秒开” 效果。
总结
- 当前纯 Nginx 配置:仅 “按需缓存”,用户访问哪个 ts 才缓存哪个,不自动解析 m3u8 预加载;
- 折中方案(脚本预加载):通过 Shell 脚本定时解析热门 m3u8 并预缓存 ts,接近 “自动预加载” 效果,且无 Lua 依赖;
- 取舍建议:若业务中热门视频较少,“按需缓存” 即可满足需求;若热门视频多、需优化首次播放体验,可搭配定时脚本使用。














