我有一个 Chrome 扩展程序,其中我尝试通过设置视频对象的
currentTime
属性来向前或向后跳转(基于用户命令)到视频中的特定时间。在尝试设置currentTime
之前,各种操作都工作得很好。例如:
document.getElementsByTagName("video")[1].play(); // works fine
document.getElementsByTagName("video")[1].pause(); // works fine
document.getElementsByTagName("video")[1].muted = true; // works fine
document.getElementsByTagName("video")[1].muted = false; // works fine
但是一旦我尝试通过执行以下操作跳到视频中的特定点:
document.getElementsByTagName("video")[1].currentTime = 500; // doesn't work
不会引发任何错误,视频会暂停,此后尝试的任何操作都不会执行任何操作。因此,尝试设置
currentTime
后,上面显示的项目(播放/暂停/静音/取消静音)不再起作用。如果我在设置后读取 currentTime
的值,它会正确显示我刚刚设置的新时间。然而,我所做的任何事情都无法使其播放,事实上,即使尝试通过单击内置工具栏来播放视频也不再起作用。因此,显然设置 currentTime 会对视频播放器造成各种破坏。然而,如果我重新加载视频,只要我不尝试设置 currentTime,一切都会像以前一样工作。
我可以通过滑动工具栏上的滑块轻松跳转到各个时间(向后或向前),因此内部必须有某种方法可以做到这一点。有什么方法可以发现哪些代码可以成功进行时间跳跃?因为它是一个 Chrome 扩展,我可以将自定义 js 注入到正在执行的 Hulu js 中,但我不知道我会发送什么命令。
有什么想法吗?
好吧,我摆弄了一会儿,看看如何在播放器上重现点击事件,并提出了以下解决方案:
handleViewer = function(){
var thumbnailMarker = $('.thumbnail-marker'),
progressBarTotal = thumbnailMarker.parent(),
controlsBar = $('.controls-bar'),
videoPlayer = $('#content-video-player');
var init = function(){
thumbnailMarker = $('.thumbnail-marker');
progressBarTotal = thumbnailMarker.parent();
controlsBar = $('.controls-bar');
videoPlayer = $('#content-video-player');
},
check = function(){
if(!thumbnailMarker || !thumbnailMarker.length){
init();
}
},
show = function(){
thumbnailMarker.show();
progressBarTotal.show();
controlsBar.show();
},
hide = function(){
controlsBar.hide();
},
getProgressBarWidth = function(){
return progressBarTotal[0].offsetWidth;
};
return {
goToTime: function(time){
var seekPercentage,
duration;
check();
duration = videoPlayer[0].duration;
if(time > 0 && time < duration){
seekPercentage = time/duration;
this.jumpToPercentage(seekPercentage);
}
},
jumpToPercentage: function(percentage){
check();
if(percentage >= 1 && percentage <= 100){
percentage = percentage/100;
}
if(percentage >= 0 && percentage < 1){
show();
thumbnailMarker[0].style.left = (getProgressBarWidth()*percentage)+"px";
thumbnailMarker[0].click();
hide();
}
}
}
}();
代码初始化后,您可以执行以下操作:
handleViewer.goToTime(500);
或者
handleViewer.jumpToPercentage(50);
我已经在 MacBook Pro 上的 Chrome 中对此进行了测试。如果您遇到任何问题,请告诉我。
与其尝试找到负责改变时间的 JavaScript,为什么不尝试模拟导致时间改变的用户事件呢?
找出触发时间变化的鼠标事件的确切顺序。 这可能是 mouseover、mousedown、mouseup 和 click 的某种组合。
然后综合地重新创建这些事件并将它们分派到适当的元素。
这是Stream Keys和Vimium等扩展所采用的方法。
在设置 currentTime 之前,视频应该已准备好播放。
尝试在设置 currentTime 之前添加此行?
document.getElementsByTagName("video")[1].play();
document.getElementsByTagName("video")[1].currentTime = 500;
看起来如果您先暂停,然后设置 currentTime,然后再次播放,它就会起作用。
document.getElementsByTagName("video")[1].pause()
document.getElementsByTagName("video")[1].currentTime = 800.000000
document.getElementsByTagName("video")[1].play()
可能需要挂钩一些事件,例如 onseeked 来放入播放命令以使其更加健壮。
你可以试试,我试过了,效果很好
var sliderContainer = document.querySelector('.Timeline__slider');
var maxTime = parseInt(sliderContainer.getAttribute('aria-valuemax'));
var targetTime = " + value + ";
var targetPosition = (targetTime / maxTime) * 100;
var sliderWidth = sliderContainer.offsetWidth;
var sliderLeft = sliderContainer.getBoundingClientRect().left;
var mouseX = sliderLeft + (sliderWidth * targetPosition / 100);
var pointerDownEvent = new MouseEvent('pointerdown', {
bubbles: true,
cancelable: true,
view: window,
clientX: mouseX
});
sliderContainer.dispatchEvent(pointerDownEvent);
var pointerUpEvent = new MouseEvent('pointerup', {
bubbles: true,
cancelable: true,
view: window,
clientX: mouseX
});
sliderContainer.dispatchEvent(pointerUpEvent);