在Hulu视频播放器中设置videoElement.currentTime不起作用,并且会破坏播放器

问题描述 投票:0回答:5

我有一个 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 中,但我不知道我会发送什么命令。

有什么想法吗?

javascript google-chrome-extension html5-video
5个回答
3
投票

好吧,我摆弄了一会儿,看看如何在播放器上重现点击事件,并提出了以下解决方案:

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 中对此进行了测试。如果您遇到任何问题,请告诉我。


2
投票

与其尝试找到负责改变时间的 JavaScript,为什么不尝试模拟导致时间改变的用户事件呢?

找出触发时间变化的鼠标事件的确切顺序。 这可能是 mouseover、mousedown、mouseup 和 click 的某种组合。

然后综合地重新创建这些事件并将它们分派到适当的元素。

这是Stream KeysVimium等扩展所采用的方法。


1
投票

在设置 currentTime 之前,视频应该已准备好播放。

尝试在设置 currentTime 之前添加此行?

document.getElementsByTagName("video")[1].play();
document.getElementsByTagName("video")[1].currentTime = 500;


0
投票

看起来如果您先暂停,然后设置 currentTime,然后再次播放,它就会起作用。

document.getElementsByTagName("video")[1].pause()
document.getElementsByTagName("video")[1].currentTime = 800.000000
document.getElementsByTagName("video")[1].play()

可能需要挂钩一些事件,例如 onseeked 来放入播放命令以使其更加健壮。


0
投票

你可以试试,我试过了,效果很好

                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);

© www.soinside.com 2019 - 2024. All rights reserved.