我尝试加载视频,然后根据窗口的滚动播放该视频。我目前在Safari和Firefox中工作但不是Chrome。我在Chrome中遇到的错误是: 未捕获的InvalidStateError:无法设置' currentTime'属性' HTMLMediaElement':元素的readyState是HAVE_NOTHING。
有谁知道我做错了什么?
function updateVideo(video) {
var video = $('#trees').get(0);
var videoLength = video.duration;
var scrollPosition = $(document).scrollTop();
video.currentTime = (scrollPosition / ($(document).height() - $(window).height())) * videoLength;//(scrollPosition / SCROLL_SCRUB_SPEED) % videoLength;
}
$(window).scroll(function(e) {
updateVideo();
});
<video id="trees"><source src="/theme/pmc/files/video/trees_all.mov" type="video/quicktime"><source src="/theme/pmc/files/video/trees_all.webm" type="video/webm"></video>
答案 0 :(得分:9)
如果您在浏览器知道视频的currentTime
之前尝试设置duration
,则会抛出该错误。持续时间是“元数据”的一部分,“元数据”通常位于视频文件的标题中,包括高度和宽度。
通常,如果您的视频元素没有preload
属性,则浏览器会在您加载页面后尝试至少加载元数据。但是,根据浏览器的具体情况,页面上的其他内容以及网络连接的速度,可能直到您滚动至少一次后才会发生。
解决方案看起来像这样。
/*
memoize video, window and document so you don't have to create and
garbage-collect new objects every time you scroll
*/
var video = $('#trees').get(0),
$window = $(window),
$document = $(document);
function updateVideo() {
var duration = video.duration,
scrollPosition = window.scrollY;
if (duration) {
video.currentTime = (scrollPosition / ($document.height() - $window.height())) * duration;
}
}
// update video every time you scroll
$window.scroll(updateVideo);
// update video when metadata has loaded
$(video).on('loadedmetadata', updateVideo);
这应该会让错误消失。如果您尝试此操作且loadedmetadata
事件永远不会触发,请尝试将其添加到最后以强制它:
video.load();
修改:定义并设置scrollPosition
。这是一个工作示例:http://jsbin.com/vurap/1/edit
答案 1 :(得分:-1)
刚刚找到了一个更快速的代码集,并且使用更少的代码几乎完全相同:http://codepen.io/ollieRogers/pen/lfeLc/
// select video element
var vid = document.getElementById('v0');
//var vid = $('#v0')[0]; // jquery option
// pause video on load
vid.pause();
// pause video on document scroll (stops autoplay once scroll started)
window.onscroll = function(){
vid.pause();
};
// refresh video frames on interval for smoother playback
setInterval(function(){
vid.currentTime = window.pageYOffset/400;
}, 40);