H5 Browser Custom User Control

Posted by kevintynfron on Wed, 22 Jan 2020 02:12:04 +0100

Reference article:
https://css-tricks.com/custom...
https://blog.hellojs.org/crea...

Native User Control

For the <video>tag, there is a property called'controls', which adds native pause/start, progress bar, volume, video maximization to the player as follows.

<video id="myVideo" controls ></video>

However, native controls often do not meet some of our needs, so it is necessary to customize user controls.
First, we declare a variable, and we define <video id="video"></video> as follows

let videoElement = document.getElementById('video');
let $videoElement = $('#video');

Custom User Control

How to implement a custom control is easy to say, with the help of events and attributes from several H5 players:

Pause and Start

Pause and start are basic functions and easy to implement
Start:

videoElement.play()

Pause:

videoElement.pause()

So you just need to call the play() method when the current video is paused to continue playing, just as you can call pause() when the video is playing.
"Judging if the current video is paused" is mentioned.
There may be an error in using only videoElement.paused to judge video pauses

The play() request was interrupted by a call to pause().

After querying, the isPlaying variable is used to determine if the video is paused

let isPlaying = videoElement.currentTime > 0 && !videoElement.paused && !videoElement.ended && videoElement.readyState > 2;

The final pause/start event is as follows:

        let playpauseToggle = function(e){
            let isPlaying = videoElement.currentTime > 0 && !videoElement.paused && !videoElement.ended && videoElement.readyState > 2;
            if(!isPlaying) {
                videoElement.play();
            }
            else {
                videoElement.pause();
            }
            return false;
        }

Current/Total Video Length

This is easy, with the help of two parameters;
Duration to get the total video duration
CurrtTime can get the current duration of the video

The total video duration can be obtained once after the video is loaded.
The current time of the video is different, and each time the video progress is updated, the current time of the video needs to be updated accordingly
loadedmetadata event: Get video metadata.
timeupdate event: An event that updates the progress of a video after it has been played.There will be clear progress changes, and you can get current Time
It is worth mentioning that the data format obtained with duration and currentTime retains several decimal places, a value in seconds, and usually needs to be formatted as needed. To format Ten Minutes Twenty-Four Seconds as 10:24, I created the following method

    let numberToTime = function(number){
            number = parseInt(number,10);
            let minues = 0;
            let second = 0;
        
            minues = parseInt(number / 60, 10);
            second = number % 60

            if(minues<10){
                minues = '0'+ minues
            }

            if(second<10){
                second = '0'+ second
            }

            return minues + ':' + second;
        }

And the code to listen for the corresponding event and update the current time is as follows

    $videoElement.on('loadedmetadata', function() {
       $('.duration').text(numberToTime(videoElement.duration));
    });

    $videoElement.on('timeupdate', function() {
       $('.current').text(numberToTime(videoElement.currentTime));
    });
 <div class="progressTime">
   <span class="current">00:00</span> / <span class="duration">00:00</span>
</div>

Progress bar

Video without a progress bar is not a good video, it is important to achieve a progress bar
Declare one point: The style here in the progress bar uses the bootstrap dom structure as follows

<div class="progress">
  <div class="progress-bar progress-bar-primary" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 0%;">  </div>
  <div class="bufferBar progress-bar progress-bar-buffered"></div>
</div>

There are two items, one is the current progress and the other is the buffer progress.
The basic principle is also simple, get the current time/total time* 100% value, and assign it to the'width'in the style of the progress bar corresponding to the dom, which is updated continuously through the timeupdate event.

    $videoElement.on('timeupdate', function() {
        let currentPos = videoElement.currentTime;
        let maxduration = videoElement.duration;
        let percentage = 100 * currentPos / maxduration;
        $('.progress-bar-primary').css('width', percentage + '%');
     })

The buffer progress bar is essentially the same as the above implementation, corresponding to the current Pos value above

let currentBuffer = videoElement.buffered.end(0)

A progress bar can not only see progress, but also drag it
The idea for dragging progress is to determine how much the current progress changes based on the changes in the X coordinates (plus or minus) of the mouse's mousedown event and mouseup event on the progress bar.

The code is as follows:

let timeDrag = false;   /* Drag status */
$('.progress').mousedown(function(e) {
    timeDrag = true;
    updatebar(e.pageX);
});
$(document).mouseup(function(e) {
    if(timeDrag) {
        timeDrag = false;
        updatebar(e.pageX);
    }
});
$(document).mousemove(function(e) {
    if(timeDrag) {
        updatebar(e.pageX);
    }
});
 
let updatebar = function(x) {
    let progress = $('.progress');
    let maxduration = videoElement.duration; //Total Video Duration
    let position = x - progress.offset().left; //Variation
    let percentage = 100 * position / progress.width();
 
    //Out-of-range fixes
    if(percentage > 100) {
        percentage = 100;
    }
    if(percentage < 0) {
        percentage = 0;
    }
 
    //Update progress bar and current time
    $('progress-bar').css('width', percentage+'%');
    videoElement.currentTime = maxduration * percentage / 100;
};

volume

Volume control is easy, with the help of the following methods and properties, specific interaction can be achieved at will.Previously, I read an article about the volume keys of a psychotic person who can learn to learn [funny]: http://adquan.com/post-10-410...

videoElement.muted = true //Mute
videoElement.muted = false //un-mute

videoElement.volume = 1 //Set volume to maximum
videoElement.volume = 0.5 //Set the volume to 50%
videoElement.volume = 0 //Set the minimum volume

Full screen

Full screen is a slightly cumbersome compatibility feature.
If you want to write a user control for firefox, call the full-screen api with the common parent element <video> and <div class="controls"> <div>, otherwise you will find that your user control will not be visible after the full-screen.(However, firefox's native user control is 100 times better than chrome's, so if you want to use the native user control, you can just use element.requestFullscreen()
We also note this tips: it's not just <video>that can call the full-screen api

<div class="live__player">
    <video></video>
    <div class="controls"></div>
</div>
//Full screen
function fullScreenOn(element) {
    if(element.requestFullscreen) {
        element.requestFullscreen();
    } else if(element.mozRequestFullScreen) {
        $('.live__player')[0].mozRequestFullScreen();
    } else if(element.msRequestFullscreen){ 
        element.msRequestFullscreen(); 
    } else if(element.oRequestFullscreen){
        element.oRequestFullscreen();
    } else if(element.webkitRequestFullscreen)
    {
        element.webkitRequestFullScreen();
    } else{

        var docHtml = document.documentElement;
        var docBody = document.body;
        var videobox = document.getElementById('sfLive');
        var cssText = 'width:100%;height:100%;overflow:hidden;';
        docHtml.style.cssText = cssText;
        docBody.style.cssText = cssText;
        videobox.style.cssText = cssText+';'+'margin:0px;padding:0px;';
        document.IsFullScreen = true;

    }
    $controls.css('z-index','2147483647');
    
}

The value passed in here is the videoElement

<small>`(videoElement = document.getElementById('video');)`</small>

Another thing the last line of code does is set the z-index property of our custom control to the browser maximum.The reason is that when the browser in the webkit kernel is in full screen, the z-index of the video changes to the maximum value allowed by the browser. By setting the z-index of the custom control to the maximum value, we can prevent the user control from being obscured by the video.

Similarly, the code to exit full screen mode is as follows:

function fullScreenOff() {
    if (document.exitFullscreen) {
        document.exitFullscreen();
    } else if (document.msExitFullscreen) {
        document.msExitFullscreen();
    } else if (document.mozCancelFullScreen) {
        document.mozCancelFullScreen();
    } else if(document.oRequestFullscreen){
        document.oCancelFullScreen();
    } else if (document.webkitExitFullscreen){
        document.webkitExitFullscreen();
    } else {
        var docHtml = document.documentElement;
        var docBody = document.body;
        var videobox = document.getElementById('sfLive');
        docHtml.style.cssText = "";
        docBody.style.cssText = "";
        videobox.style.cssText = "";
        document.IsFullScreen = false;
    }

    $('.live__playcontrol').css('z-index','1');
}

The code to check whether the video is full screen is as follows:

let isFullScreen =  document.fullscreenElement ||
                    document.webkitFullscreenElement ||
                    document.mozFullScreenElement ||
                    document.msFullscreenElement

Treadpit

  1. Judgment of video start/pause

    Written, code as follows
    let isPlaying = videoElement.currentTime > 0 && !videoElement.paused && !videoElement.ended && videoElement.readyState > 2;
  2. Custom user controls disappeared after firefox full screen

    Written in this article, unlike other browsers, firefox does not call `requestFullscreen()'with the `<video>' element's dom object, but with the `<video>'element's parent element.
    
  3. shadowDom Hidden Issues
    If you find that you have explicitly removed the attribute control of the <video>element, but the native control is still displayed, then you have to remove it with CSS only

video::-webkit-media-controls-enclosure {
  display:none !important;
}
Published 60 original articles. Accepted 13. Visited 50,000+
Private letter follow

Topics: Firefox Attribute