如何实现Video.js加载HLS的m3u8文件返回404时自动重试
Video.js 加载暂不可用HLS流的重试实现方案
onPlayerReady()仅在播放器实例初始化完成时触发单次回调,确实无法覆盖资源加载阶段的失败重试逻辑,可通过两种方案实现m3u8资源加载失败后的自动重试:
方案1:使用Video.js HLS插件内置重试能力(推荐)
Video.js 7.0及以上版本默认集成@videojs/http-streaming解析HLS流,原生支持m3u8列表加载失败的重试配置,无需额外编写错误监听逻辑,初始化播放器时直接传入对应参数即可:
const player = videojs('your-video-dom-id', { autoplay: true, // HLS解析相关配置 html5: { hls: { playlistRetry: 10, // m3u8文件加载最大重试次数,根据服务启动耗时调整 playlistRetryInterval: 3000, // 单次重试间隔(单位:毫秒) overrideNative: true } }, sources: [{ // 建议拼接时间戳参数避免浏览器缓存404结果 src: `https://your-service-path/stream.m3u8?t=${Date.now()}`, type: 'application/x-mpegURL' }] });
该方案会在m3u8请求返回4xx/5xx网络错误时,按照配置的间隔自动重试,达到最大重试次数后才会抛出正式错误。
方案2:自定义错误监听实现灵活重试逻辑
如果需要更灵活的重试逻辑(比如重试时动态修改流地址、自定义错误提示、联动其他业务逻辑),可以通过监听播放器错误事件手动实现重试:
const player = videojs('your-video-dom-id', { autoplay: true, sources: [{ src: `https://your-service-path/stream.m3u8?t=${Date.now()}`, type: 'application/x-mpegURL' }] }); // 重试规则配置 const retrySetting = { maxCount: 10, interval: 3000, current: 0 }; player.on('error', () => { const err = player.error(); // 仅拦截网络类错误(m3u8 404属于该错误码,对应值为2),其他播放错误不触发重试 if (err.code === 2 && retrySetting.current < retrySetting.maxCount) { retrySetting.current += 1; // 清空播放器当前错误状态,否则会一直卡在错误提示层 player.error(null); setTimeout(() => { // 重载资源时更新时间戳避免缓存 player.src({ src: `https://your-service-path/stream.m3u8?t=${Date.now()}`, type: 'application/x-mpegURL' }); // 开启autoplay的场景下重置src后会自动尝试播放,若未自动触发可手动调用play() // player.play(); }, retrySetting.interval); } else if (retrySetting.current >= retrySetting.maxCount) { // 重试达到上限后的兜底逻辑,比如展示手动刷新提示 console.log('流资源加载失败,请稍后刷新页面重试'); } });
注意事项
- 无论使用哪种方案,都建议给m3u8地址拼接动态时间戳参数,避免浏览器缓存首次请求返回的404响应,导致后续重试直接读取缓存不发起真实请求
- 必须配置最大重试次数,禁止无限重试,避免外部服务异常时产生大量无意义请求
- 自定义重试逻辑时,重试前一定要调用
player.error(null)清空播放器错误状态,否则重载资源不会生效
内容的提问来源于stack exchange,提问作者P. H. Staub
相关产品推荐
相关产品推荐

