一、不止 TS 分片,HLS 还支持 fmp4 碎片 MP4 格式
大部分新手接触 HLS,看到的分片后缀都是.ts,很多人以为 HLS 只能用 TS 分片。实际上 HLS 协议也支持 fmp4 碎片 MP4(也叫 CMAF)分片,分片后缀是.m4s。
现在很多云厂商转码、低延迟 LL‑HLS 方案会输出 fmp4 格式分片。很多开发第一次碰到 fmp4 的 M3U8 会比较陌生,分不清它和传统 TS 分片有什么区别,踩不少小坑。
从 M3U8 索引文本看,fmp4 和普通 TS 的 M3U8 标签大体很像,但是 M3U8 头部会多出#EXT‑X‑MAP标签,这个标签就是 fmp4 分片的初始化片段。没有正确加载初始化片段,分片就无法解码,直接黑屏。
很多坑点很隐蔽:VLC 可以播放 fmp4,但是老版本 hls.js 不兼容;复制 M3U8 的时候忽略 EXT‑X‑MAP 对应的初始化片段地址,分片 404,播放直接失败。
调试 fmp4 格式的 HLS 流,我会使用 m3u8live.cn 网页调试工具,查看 M3U8 原始文本,重点观察 #EXT‑X‑MAP 标签,确认初始化片段地址是否可以正常访问。
二、fmp4 碎片 MP4 和传统 TS 分片简单对比
- 传统 TS 分片:后缀.ts;不需要独立初始化片段;每一个 TS 分片内部自带解码初始化信息;HLS 版本 3 就完全支持;兼容性极好。
- fmp4 碎片 MP4(CMAF) :后缀 m4s;必须有
#EXT‑X‑MAP标签,指向独立初始化 moov 片段;播放器必须先下载这个初始化片段,再加载各个 m4s 分片;适合 LL‑HLS 低延迟 HLS;老版本 hls.js 对 fmp4 支持不完善。
重点坑:fmp4 的 #EXT‑X‑MAP 里面记录初始化片段的 URL,如果这个地址 404、路径写错,哪怕所有 m4s 分片全部正常,视频依旧黑屏无法解码。
三、fmp4 分片高频踩坑
坑 1:忽略 #EXT‑X‑MAP 初始化片段
M3U8 里面有 EXT‑X‑MAP 标签,但是初始化片段地址写错、404。m4s 分片全部 200,但是没有初始化片段,无法解码,直接黑屏。很多人只看 m4s 分片,完全忽略 MAP 标签。
坑 2:hls.js 版本过低,不支持 fmp4 分片
老版本 hls.js 对 fmp4/CMAF 支持有 BUG,升级库版本才可以正常播放。同样一份 fmp4 流,新版工具播放正常,老业务页面黑屏。
坑 3:做 Nginx 代理改写 M3U8,只替换 m4s 分片,漏掉 EXT‑X‑MAP 内的 URL
代理改写 M3U8 报文的时候,只替换 m4s 分片地址,没有替换 #EXT‑X‑MAP 标签里面的初始化片段 URL,初始化片段请求 404。
坑 4:把 fmp4 的 m4s 分片当成普通 TS 分片去下载单独播放
m4s 碎片分片不能直接双击打开播放,必须配合初始化片段,组合起来才可以解码。不能像 TS 分片那样直接独立播放。
四、fmp4 流排查简单步骤
第一步,fmp4 格式 M3U8 粘贴网页调试工具,查看原始 M3U8 文本,寻找#EXT‑X‑MAP标签。 第二步,F12 网络面板,确认 MAP 标签对应的初始化片段可以正常 200 访问,没有 404、403。 第三步,如果业务页面播放黑屏,确认项目引入的 hls.js 库版本,过低版本需要升级。 第四步,Nginx 代理场景,改写 M3U8 报文,记得同时替换 EXT‑X‑MAP 内部的 URL。
五、选型简单建议
- 普通点播、普通直播,追求最大兼容性,优先传统 TS 分片;
- 如果业务使用 LL‑HLS 低延迟直播,会产出 fmp4/CMAF 分片,需要保证播放器库版本足够新;
- 做代理改写 M3U8 报文,不要漏掉 #EXT‑X‑MAP 里面的初始化片段地址。
六、总结
HLS 分片不只有 TS,还有 fmp4 碎片 MP4(CMAF)分片。fmp4 流 M3U8 会出现 #EXT‑X‑MAP 初始化片段标签,播放器必须先加载初始化片段,分片才能解码。很多故障 m4s 分片访问正常,但初始化片段 404,直接黑屏。老版本 hls.js 对 fmp4 支持存在缺陷。借助网页调试工具查看 M3U8 原始文本,重点核对 EXT‑X‑MAP 标签对应的资源地址,可以快速定位 fmp4 分片的播放故障。