在 iPad(iOS v. 5.1.1)上,Safari 似乎不会根据规范保留视频元素的
readyState
值。即使从视频源加载,readyState
也等于零。
我制作了一个演示jsfiddle,它不断检查视频的
readyState
。一个有趣的观察:只有在单击播放按钮后,readyState
才会发生变化。
实际上,我预计
readyState
在加载期间会切换到更高的数字(因为我测试过的桌面上的所有浏览器都是这种情况 - 包括 Safari)。有解决方法吗?我这里有什么问题吗?
来自Apple开发者文档:
注意:Safari 5.0 及更高版本支持 preload 属性。 iOS 上的 Safari 从不预加载。
根据 Apple 的说法,移动设备上期望的行为是仅在您主动请求资源后才开始加载,以免浪费带宽或电池。
关于你的问题,这意味着苹果遵守该规范。由于不会发生预加载并且仅在单击播放按钮后才开始加载,因此在该时间点之前
readyState
为零。
但是,
video
标签有特殊事件,应该比readyState
提供更多信息。
onCanplay
onCanplaythrough
onProgress
注意:在 iPad 上,Safari 在用户单击海报或占位符之前不会开始下载。目前,以这种方式开始的下载不会发出进度事件。
我最近遇到了这个问题并找到了解决方案,所以我想我来分享一下。
如果您想使用 JavaScript 控制视频,基本模式是等待视频加载,然后使用代码推进帧。像这样的东西:
// Select the video element
const video = document.querySelector("video");
// Use an animation frame to wait for it to load
let req;
function wait(){
req = window.requestAnimationFrame(wait);
// readyState will never reach 4 on mobile Safari...
if (video.readyState === 4) {
window.cancelAnimationFrame(req);
doSomethingWithYourVideo();
}
}
req = wait();
我也看到人们这样做
window.setInterval
而不是window.requestAnimationFrame
,但基本思想是相同的。
但是,在移动 Safari 上,
readyState
永远不会到达 4
,即使您将视频元素设置为 muted
。您的视频将永远不会播放。
但是有一个简单的解决方法:
video.load()
。所以,这有效:
// Select the video element
const video = document.querySelector("video");
// Tell the browser to load the video
video.load();
// Use an animation frame to wait for it to load
let req;
function wait(){
req = window.requestAnimationFrame(wait);
// Now, readyState will reach 4 on mobile Safari...
if (video.readyState === 4) {
window.cancelAnimationFrame(req);
doSomethingWithYourVideo();
}
}
req = wait();
// example with audio
const audio = new Audio("url...");
audio.load(); // this is needed on iOS mobile
// example with video
const video = new Video("url...");
video.load(); // this is needed on iOS mobile
感谢哈里·史蒂文斯指出这一点。