Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set videoElement.currentTime in Hulu video player doesn't work, and breaks the player

I have a Chrome extension in which I'm trying to jump forward or backward (based on a user command) to a specific time in the video by setting the currentTime property of the video object. Before trying to set currentTime, a variety of operations work just fine. For example:

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

BUT as soon as I try to jump to a specific point in the video by doing something like this:

document.getElementsByTagName("video")[1].currentTime = 500; // doesn't work

No errors are thrown, the video pauses, and any attempted actions after this point do nothing. So the items shown above (play/pause/mute/unmute) no longer work after attempting to set currentTime. If I read the value of currentTime after setting it, it correctly displays the new time that I just set it to. Yet nothing I do will make it play, and in fact even trying to make the video play by clicking the built-in toolbar no longer works. So, apparently setting currentTime wreaks all kinds of havoc in the video player. Yet if I reload the video, all works as before as long as I don't try to set currentTime.

I can easily jump to various times (backward or forward) by sliding the slider on the toolbar, so there must be some way internally to do that. Is there some way I can discover what code does a successful time jump? Because it's a Chrome extension I can inject custom js into the executing Hulu js, but I don't know what command I would send.

Any ideas?

like image 796
HerrimanCoder Avatar asked Apr 23 '17 05:04

HerrimanCoder


3 Answers

Okay I fiddled around with it for a little while to see how I could reproduce the click event on the player and came up with the following solution:

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

Once that code is initialized you can do the following:

handleViewer.goToTime(500);

Alternatively

handleViewer.jumpToPercentage(50);

I've tested this in chrome on a MacBook pro. Let me know if you run into any issues.

like image 128
Trevor Avatar answered Oct 02 '22 15:10

Trevor


Rather than try to find the javascript responsible for changing the time, why not try to simulate the user events that cause the time to change?

Figure out the exact sequence of mouse events that trigger the time change. This is probably some combination of mouseover, mousedown, mouseup, and click.

Then recreate those events synthetically and dispatch them to the appropriate elements.

This is the approach taken by extensions like Stream Keys and Vimium.

like image 27
Eejdoowad Avatar answered Oct 02 '22 15:10

Eejdoowad


The video should be ready to play before setting the currentTime.

Try adding this line before setting currentTime?

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

like image 43
Fionna Avatar answered Oct 02 '22 16:10

Fionna