Javascript 在html5/js中完美同步播放多个视频

Javascript 在html5/js中完美同步播放多个视频,javascript,html,html5-video,Javascript,Html,Html5 Video,我有一个标准的HTML5前端,javascript后端设置。我需要同步播放8个视频 问题是,它是一个音乐网站,所以视频必须完全同步播放。 我有8个视频播放器,我等待每个视频的canplaythrough事件,然后循环播放(项目)以使用项目启动视频。play(): if(videosStillBuffering == 0){ if(!videosHavePlayed){ videosHavePlayed = true; videoContainerArray

我有一个标准的HTML5前端,javascript后端设置。我需要同步播放8个视频

问题是,它是一个音乐网站,所以视频必须完全同步播放。 我有8个视频播放器,我等待每个视频的canplaythrough事件,然后循环播放(项目)以使用项目启动视频。play()

if(videosStillBuffering == 0){
    if(!videosHavePlayed){
        videosHavePlayed = true;
        videoContainerArray.forEach(function(item) {
    item.currentTime = 0;
 });
    }
     videoContainerArray.forEach(function(item) {
    item.play();
 });
但是这些视频并不是在同一时间播放的,播放的时间大约不到半秒。那还是太多了。有没有办法向网站解释视频必须一起播放,或者有没有办法至少进一步缩小视频之间的差异?比如,异步给视频播放命令

以下是js源代码:

const videoContainerCollection = document.getElementsByClassName('video-container');
const videoContainerArray = [...videoContainerCollection];
const playPauseButton = document.getElementById('playPause');

var shouldPlay = false;
var playPauseButtonSaysPlay = true;
var videosHavePlayed = false;

playPauseButton
    .addEventListener('click', function () {
       if(playPauseButtonSaysPlay){
             shouldPlay = true;
                 playIfBuffered();
       } else {
             shouldPlay = false;
             pause();
                 playPauseButton.className = playPauseButton.className.replace( /(?:^|\s)blue(?!\S)/g , 'green' );
                 playPauseButton.innerHTML = "Play";
                 playPauseButtonSaysPlay = true;
         }
}, true);

videoContainerArray.forEach(function(item) {
    item.addEventListener('canplaythrough', (event) => {
        console.log("canplaythrough " );
        if(shouldPlay){
             playIfBuffered();
        }
});
});

videoContainerArray.forEach(function(item) {
    item.addEventListener('waiting', (event) => {
            console.log("waiting " );
        if(shouldPlay){
            playIfBuffered();
     }
});
});

function checkReady() {
    var countReady = 0;
    videoContainerArray.forEach(function(item) {
        if ( item.readyState >= 3 ) {   // it's loaded
            countReady++;
        }
    });
    return countReady;
}

function playIfBuffered() {
    const videosStillBuffering = videoContainerArray.length - checkReady()
    if(videosStillBuffering == 0){
        if(!videosHavePlayed){
            videosHavePlayed = true;
            videoContainerArray.forEach(function(item) {
        item.currentTime = 0;
     });
        }
         videoContainerArray.forEach(function(item) {
        item.play();
     });
         playPauseButton.innerHTML = "Pause";
         playPauseButton.className = playPauseButton.className.replace( /(?:^|\s)green(?!\S)/g , 'blue' );
         playPauseButtonSaysPlay = false;
    } else {
        pause();
        playPauseButton.className = playPauseButton.className.replace( /(?:^|\s)green(?!\S)/g , 'blue' );
        playPauseButton.innerHTML = videosStillBuffering + " of " + videoContainerArray.length + " vidoes are buffering. Please Wait.";
    }
}

function pause() {
    videoContainerArray.forEach(function(item) {
           item.pause();
    });
}

document.getElementById('stop')
    .addEventListener('click', function () {
        shouldPlay = false;
        playPauseButtonSaysPlay = true;
        playPauseButton.innerHTML = "Play";
        playPauseButton.className = playPauseButton.className.replace( /(?:^|\s)blue(?!\S)/g , 'green' );
        videoContainerArray.forEach(function(item) {
            item.pause();
            item.currentTime = 2;
     });
     videosHavePlayed = false;
    }, false);

videoContainerArray.forEach(toggleMute);
function toggleMute(item, index) {
  item.addEventListener('click', function() {
    if (item.muted === true) {
      item.muted = false;
      item.style.opacity = "1";
      item.style.filter  = 'alpha(opacity=100)'; // IE fallback
    }
    else if (item.muted === false) {
      item.muted = true;
      item.style.opacity = "0.5";
      item.style.filter  = 'alpha(opacity=50)'; // IE fallback
    }
  });
}
}

答案是每500毫秒检查一次所有视频,如果视频的当前时间超过第一个视频时间的0.1秒。如果是,请将视频的当前时间设置为第一个视频的当前时间:

setInterval(
    function(){
          videoContainerArray.forEach(function(item) {
          var currentTime = videoContainerArray[0].currentTime;
          var videoTime = item.currentTime;
              if (Math.abs(currentTime - videoTime) > 0.1) {
                  item.currentTime = currentTime;
              }
     });        
}, 500);
事实上,我认为视频的同步性不是我们案例中的问题,其中一个视频可能只是被错误地剪切了:(