iOS Safari中onwaiting事件后如何判断视频就绪可播放?
解决Safari中暂停状态下视频准备就绪的判断问题
针对你遇到的Safari视频事件异常问题——waiting事件后不触发canplay,暂停状态下onplay/onplaying也失效,这里给你几个可靠的判断方案:
核心判断依据:readyState属性
视频元素的readyState属性是判断播放就绪最直接的标准,完全不受Safari的事件兼容问题影响:
HAVE_ENOUGH_DATA(对应数值4):表示视频已加载足够数据,即使当前处于暂停状态,也可以随时开始播放。- 其他状态比如
HAVE_CURRENT_DATA(2)或HAVE_FUTURE_DATA(3)只能保证当前帧或后续几帧可播放,稳定性不足。
你可以直接通过video.readyState >= 4来判断视频是否准备好播放。
实现方案:事件监听+主动检查
因为Safari不会主动触发合适的事件通知状态变化,我们需要结合事件监听和主动轮询来覆盖所有场景:
1. 监听关键事件触发检查
针对数据加载和seek操作,监听以下事件,每次触发时检查readyState:
progress:视频加载数据时会持续触发,适合监听数据加载完成的状态seeked:seek操作完成后触发,此时需要检查是否已加载足够数据
2. 补充短轮询兜底
如果担心某些场景下事件未触发(比如网络波动导致的断续加载),可以添加一个短间隔的轮询,直到满足就绪条件后停止。
完整代码示例
const video = document.getElementById('your-video-element'); let checkInterval = null; // 判断是否准备好播放的核心函数 function isVideoReady() { return video.readyState >= 4; // HAVE_ENOUGH_DATA } // 处理就绪状态的逻辑 function handleVideoReady() { console.log('视频已准备好播放(即使当前暂停)'); // 在这里执行你的业务逻辑,比如更新UI提示等 // 停止轮询 if (checkInterval) { clearInterval(checkInterval); checkInterval = null; } } // 监听事件触发检查 video.addEventListener('progress', () => { if (isVideoReady()) { handleVideoReady(); } }); video.addEventListener('seeked', () => { if (isVideoReady()) { handleVideoReady(); } else { // 如果seek后还没就绪,启动轮询检查 if (!checkInterval) { checkInterval = setInterval(() => { if (isVideoReady()) { handleVideoReady(); } }, 500); // 每隔500ms检查一次,可根据需求调整间隔 } } }); // 初始加载时也可以直接检查一次 if (isVideoReady()) { handleVideoReady(); }
这个方案不需要依赖Safari的事件兼容性,直接通过标准的readyState属性判断,同时结合事件和轮询覆盖所有可能的场景,确保不会遗漏就绪状态。
内容的提问来源于stack exchange,提问作者Istoma
相关产品推荐
相关产品推荐

