页面加载时JWPlayer直播流自动回退60秒的代码修正方案
失效原因
原有代码无法生效有三个核心问题:
- 仅给
video4绑定了onBeforePlay事件,其余三个播放器实例无对应监听;且onBeforePlay触发时直播流尚未完成加载,此时调用getPosition()只能拿到0或无效值,seek操作不会生效 - 现有配置仅初始化了
video1一个播放器,video2、video3、video4未执行setup初始化,直接调用jwplayer方法会抛出JS错误中断执行 - DVR直播流的可seek范围需要等流元数据、DVR滑动窗口信息加载完成后才会生效,加载未完成时调用seek会被播放器直接忽略
修正代码
首先补全页面上的4个播放器容器,原代码仅保留了video1的节点,需要补充其余三个:
<div id="wrapvideo"> <div id='video1'></div> <div id='video2'></div> <div id='video3'></div> <div id='video4'></div> </div>
替换原有播放器初始化和事件绑定代码,统一初始化4个播放器,在流加载就绪后自动执行60秒回退:
// 通用播放器配置,替换file字段为实际DVR流地址即可 const baseConfig = { skin: { name: "alaska", url: "" }, logo: { file: "", position: "top-right", hide: "false" }, file: "替换为实际DVR m3u8播放地址", title: '', aspectratio: '16:9', stretching: 'exactfit', bufferlength: '5', height: '126px', width: '624px', primary: 'hls', sharing: 'false', controls: 'false', autostart: 'true', wmode: 'opaque', image: '', abouttext: '', aboutlink: '' }; // 遍历初始化4个播放器 ['video1','video2','video3','video4'].forEach(playerId => { const player = jwplayer(playerId); // 标记是否已完成初始延迟seek,避免重复触发 let hasInitSeek = false; player.setup(baseConfig); // 首帧加载完成后首次尝试seek player.on('firstFrame', () => { if (hasInitSeek) return; const currentPos = player.getPosition(); const targetPos = Math.max(0, currentPos - 60); player.seek(targetPos); hasInitSeek = true; }); // 兼容低版本jwplayer/慢流场景,缓冲完成时校验是否需要补执行seek player.on('bufferFull', () => { if (hasInitSeek) return; const currentPos = player.getPosition(); if (currentPos >= 60) { player.seek(currentPos - 60); hasInitSeek = true; } }); });
说明
- 代码无需绑定按钮点击事件,页面加载完成、播放器自动启播后会自动跳转到距直播边缘60秒的位置,保持固定延迟播放
- 加入了边界判断,当DVR窗口时长不足60秒时会自动seek到0位置,不会出现负数位置报错
- 一次性标记保证初始seek仅执行一次,不会在后续播放缓冲过程中重复触发回退
- 原代码中重复定义
jwplayer.key的部分可以删除,仅保留一个有效key即可,避免控制台抛出密钥重复警告
内容的提问来源于stack exchange,提问作者user19500487
相关产品推荐
相关产品推荐

