Search code examples
javascriptvideo-player

Custom javascript Video player stops after 11 seconds


I am currently developing a custom javascript videoplayer for my website to be able to show some showreels. It works perfectly fine in firefox but in chrome the demo video stops everytime after 11 seconds but the buffering process has already loaded more than 11s.

Here is the link to the videoplayer: https://www.cankarka.com/en/portfolio

Does anyone have an idea why this is happening? I got no errors in the console.

Thanks in advance :)

This is my HTML:

            <div class="custom-video-player">
                <video class="video" src="inc/video.mp4" preload="auto"></video>
                <div class="video-controls">
                    <div class="video-bar">
                        <div id="currentBuffer" class="currentBuffer"></div>
                        <div id="currentProcess" class="currentProcess"></div>
                    </div>

                    <div class="buttons">
                        <button id="skip-back" class="skipBack" type="button"></button>
                        <button id="playPause" type="button"></button>
                        <button id="skip-front" class="skipForward" type="button"></button>
                        <button id="volumeBtn" class="volumeHigh" type="button"></button>

                        <div class="volume-slider-container">
                            <div class="volume-slider-container-inner">
                                <div id="volume-slider" class="volume-slider"></div>
                            </div>
                        </div>
                        <div class="volume-slider-range"></div>

                        <div class="videoTimer-container">
                            <span id="videoCurrentTime" class="videoTimer"></span> <span id="slash" class="videoTimer">/</span> <span id="videoTime" class="videoTimer"></span>
                        </div>

                        <button id="fullscreenToggle" class="fullscreen" type="button"></button>
                    </div>
                </div>
            </div>

This is my javascript code:

function initializeVideoPlayer()
{
var videoPlayers = document.querySelectorAll('.custom-video-player');
for (var i = 0; i < videoPlayers.length; ++i)
    {
    initControls(videoPlayers[i]);
    }
}

function initControls(videoPlayerContainer)
{
var video = videoPlayerContainer.querySelector('.video');
var videoBarContainer = videoPlayerContainer.querySelector('.video-bar');
video.onerror = function()
    {
    console.log("Error: " + video.error.code);
    };

// Timelines
var currentProcess = videoPlayerContainer.querySelector("div.currentProcess");
var currentBuffer = videoPlayerContainer.querySelector("div.currentBuffer");

// Buttons
var playPauseBtn = videoPlayerContainer.querySelector('#playPause');

video.addEventListener('timeupdate', updateTimeline);
video.addEventListener('click', togglePlayPause);
video.addEventListener('progress', updateBuffer);
playPauseBtn.addEventListener('click', togglePlayPause);
skipBackward.addEventListener('click', skipBackwardFunction);
skipForward.addEventListener('click', skipForwardFunction);
volumeBtn.addEventListener('click', setVolumeByBtn);

let mouseDown = false;
videoBarContainer.addEventListener('click', scrub);
videoBarContainer.addEventListener('mousemove', (e) => mouseDown && scrub(e));
videoBarContainer.addEventListener('mousedown', () => mouseDown = true);
videoBarContainer.addEventListener('mouseup', () => mouseDown = false);

function scrub(e)
    {
    var scrubTime = (e.offsetX / videoBarContainer.offsetWidth) * video.duration;
    video.currentTime = scrubTime;
    }

function skipForwardFunction()
    {
    video.currentTime += skipTime;
    }

function skipBackwardFunction()
    {
    video.currentTime -= skipTime;
    }

function updateBuffer()
    {
    var duration = video.duration;
    if (duration > 0)
        {
        for (var i = 0; i < video.buffered.length; ++i)
            {
            if (video.buffered.start(video.buffered.length - 1 - i) < video.currentTime)
                {
                currentBuffer.style.width = (video.buffered.end(video.buffered.length - 1 - i) / duration) * 100 + "%";
                break;
                }
            }
        }
    }

function updateTimeline()
    {
    // Timeline updaten
    var percent = (video.currentTime / video.duration) * 100;
    currentProcess.style.width = percent + "%";

    // Aktuelle Zeit anzeigen
    var min = Math.floor(video.currentTime / 60);
    var sec = Math.floor(video.currentTime - min * 60);

    if (sec < 10)
        {
        sec = "0" + sec;
        }
    if (min < 10)
        {
        min = "0" + min;
        }
    if (min >= 60 && min < 120)
        {
        min = "01:" + (min - 60);
        }
    else if (min >= 120 && min < 180)
        {
        min = "02:" + (min - 120);
        }
    else if (min >= 180 && min < 240)
        {
        min = "03:" + (min - 180);
        }
    else if (min >= 240 && min < 300)
        {
        min = "04:" + (min - 240);
        }
    else if (min >= 300 && min < 360)
        {
        min = "05:" + (min - 300);
        }
    else
        {
        min = "00:" + min;
        }

    // Gesamte Zeit berechnen
    var minTotal = Math.floor(video.duration / 60);
    var secTotal = Math.floor(video.duration - minTotal * 60);
        
    if (secTotal < 10)
        {
        secTotal = "0" + secTotal;
        }
    if (minTotal < 10)
        {
        minTotal = "0" + minTotal;
        }
    if (minTotal >= 60 && minTotal < 120)
        {
        minTotal = "01:" + (minTotal - 60);
        }
    else if (minTotal >= 120 && minTotal < 180)
        {
        minTotal = "02:" + (minTotal - 120);
        }
    else if (minTotal >= 180 && minTotal < 240)
        {
        minTotal = "03:" + (minTotal - 180);
        }
    else if (minTotal >= 240 && minTotal < 300)
        {
        minTotal = "04:" + (minTotal - 240);
        }
    else if (minTotal >= 300 && minTotal < 360)
        {
        minTotal = "05:" + (minTotal - 300);
        }
    else
        {
        minTotal = "00:" + minTotal;
        }
        
    videoCurrentTime.innerHTML = min + ":" + sec;
    videoTime.innerHTML = minTotal + ":" + secTotal;

    if (video.ended)
        {
        playPauseBtn.className = "play";
        }
    }

function togglePlayPause()
    {
    if (video.paused)
        {
        playVideo();
        }
    else
        {
        playPauseBtn.className = "play";
        video.pause();
        }
    }

function playVideo()
    {
    var playPromise = video.play();
    if (playPromise !== undefined)
        {
        playPromise.then(_ => {
            // Video started successfully
            playPauseBtn.className = "pause";
        }).catch(error => {
            // Video was interrupted
            playPauseBtn.className = "play";
        });
        }
    }
}

window.onload = initializeVideoPlayer;

Solution

  • In order to debug the video, you can use this code:

    const videoElement = document.getElementsByTagName('video')[0];
    
    const b = HTMLMediaElement.prototype;
    
    const allNames = new Set();
    for (let o = b; o != Object.prototype; o = Object.getPrototypeOf(o)) {
      for (let name of Object.getOwnPropertyNames(o)) {
        allNames.add(name);
      }
    }
    
    const array = Array.from(allNames).filter(x => /^on/.test(x)).map(x => x.substring(2));
    
    array.forEach(x => videoElement.addEventListener(x, console.log));
    

    This shows that an Event of type error occurs, followed by timeupdate and then pause.

    To get the actual error, use videoElement.error which shows the following:

    {
        code: 3,
        message: "PIPELINE_ERROR_DECODE: Failed to send audio packet for decoding: {timestamp=12176542 duration=21250 size=516 is_key_frame=1 encrypted=0}"
    }
    

    That means your file is corrupted, try to encode it in a different way. Also, maybe this answer will help: Audio playback halts/stops on Chrome 64