使用VideoJS与videojs-contrib-hls播放S3/CloudFront托管m3u8的异常问题
我来帮你排查这个VideoJS Code 4错误的问题!既然两个播放列表在同一S3/CloudFront环境下,那问题大概率出在bad-browser-playlist.m3u8本身或者它关联的分片文件上,咱们一步步来定位:
1. 先检查HLS播放列表的语法与结构
首先把两个m3u8文件的内容拉出来对比,重点关注这些细节:
- 是否符合HLS核心规范:比如开头必须有
#EXTM3U标记,分片对应的#EXTINF时长要合理,不能有语法错误 - 分片路径是否正确:因为两个播放列表在不同文件夹,要确认
bad-browser-playlist.m3u8里的TS分片路径是相对路径还是绝对路径,有没有拼写错误(比如把../bad-segments/xxx.ts写成了../good-segments/xxx.ts) - 加密配置是否兼容:如果播放列表里有
#EXT-X-KEY加密标签,要确认密钥URL能正常访问,且是VideoJS支持的加密方式(比如AES-128是没问题的,其他小众加密可能不支持)
2. 验证TS分片的编码与完整性
HLS播放失败很多时候是分片本身的问题,你可以用工具检查:
- 编码格式:VideoJS + videojs-contrib-hls对H.264视频+AAC音频的兼容性最好,如果
bad的分片用了H.265、VP9这类编码,很大概率会触发格式不支持的Code4错误 - 分片完整性:直接通过CloudFront URL访问单个TS分片,看能不能下载并用本地播放器(比如VLC)打开,如果分片损坏或者无法访问,那肯定会加载失败
- 媒体信息:用
ffmpeg -i xxx.ts或者MediaInfo工具查看分片的编码参数,和能正常播放的good分片对比差异
3. 核对CloudFront与S3的配置细节
虽然两个播放列表在同一分发下,但还是要确认这些容易忽略的点:
- 内容类型(Content-Type):S3中m3u8文件的Content-Type必须是
application/vnd.apple.mpegurl,TS文件必须是video/MP2T!如果类型设成了text/plain或者其他错误值,浏览器会识别不了媒体格式,这是非常常见的坑 - 缓存策略:会不会
bad-browser-playlist.m3u8被CloudFront缓存了旧的错误版本?可以手动刷新CloudFront缓存试试(控制台操作或者用aws cloudfront create-invalidation命令) - CORS配置:虽然另一个播放列表正常,但万一
bad的分片路径触发了不同的CORS检查?确认S3桶的CORS规则允许播放器所在域名的GET请求
4. 用浏览器开发者工具抓细节
打开浏览器F12的Network标签,播放视频时观察:
- m3u8文件的请求状态:是不是200 OK?有没有403/404错误?
- TS分片的请求:能不能正常加载?有没有4xx/5xx错误?
- Console控制台:有没有更详细的错误日志?比如解码失败、加密密钥无法获取的提示,这些能直接帮你区分是加载失败还是格式不支持
5. 交叉测试验证
- 用VLC直接播放
bad-browser-playlist.m3u8的CloudFront URL:如果VLC能播放,说明问题出在VideoJS/videojs-contrib-hls的兼容性上;如果VLC也不能播放,那肯定是播放列表或分片本身的问题 - 换不同浏览器测试:比如Safari原生支持HLS,不用插件,用它测试能帮你区分是插件问题还是媒体本身的问题
举个我之前遇到的类似案例:有个用户的bad播放列表用了H.265编码的分片,而videojs-contrib-hls对H.265的支持很差,换成H.264后就正常了;还有一次是S3里的m3u8文件Content-Type设成了text/plain,改成正确类型后就解决了。
内容的提问来源于stack exchange,提问作者John Alexander
相关产品推荐
相关产品推荐

