javascript - 使用 setTimeout 循环播放视频

标签 javascript html html5-video settimeout

我想循环播放视频。出于某种原因,我不想在结束事件上更改视频 src。
所以我在一个循环中为每个视频创建了视频元素。我也有视频 src 和数组中的持续时间。

这是我的想法:
只有当前正在播放的视频标签可见。其他人将被隐藏。
我想使用 setTimeout 函数,而不是使用结束事件。视频的持续时间将是延迟参数。

但他们都一起玩。我无法让他们按顺序播放。

这是我到目前为止所做的:

videoArray = [
    {"video":video1.mp4, "duration": 5},
    {"video":video2.mp4, "duration": 7},
    {"video":video3.mp4, "duration": 9},
    {"video":video4.mp4, "duration": 10},
]

for (var j = 0; j < videoArray.length; j++){
    var video = document.createElement("video");
    video.src=videoArray[j];
    video.id="video-"+j;
    video.preload = "metadata";
    video.type="video/mp4";
    video.autoplay = true; 
    video.style.display="none";
    document.body.appendChild(video); 
}

for (var count = 0; count < videoArray.length; count++) {
    (function(num){
        setTimeout(function() {
            videoArray[num].video.style.display="block";
            videoArray[num].video.play();
        }, 1000 * videoArray[num].duration);
        videoArray[num].video.style.display="none";
    })(count);
}

最佳答案

免责声明

I know that the question was asked without the ended event, but I do not think that set time out is the way to go.
Think of the scenario where you have video buffering, or slowing down for any reason, your setTimeout will be out of sync.

At the bottom I've added another solution that answers the requirement of not using the ended event, but again, I do not recommend using it.



解决方案

这个想法是在视频结束时设置一个事件监听器,在这种情况下,即使您以不同的速度运行视频,无论持续时间如何,您仍将运行下一个视频。

另一个好处是您不需要首先知道视频的持续时间。

PS。
你需要监听的事件监听器是video.addEventListener("ended", callback);
非常欢迎您运行代码或查看 working example I've created for you

工作示例

    const videoUrls = [
        'https://videos-play-loop.netlify.com/video1.mp4',
        'https://videos-play-loop.netlify.com//video2.mp4',
        'https://videos-play-loop.netlify.com//video3.mp4',
    ];

    const createVideo = ({id, src, width, cls = 'video', display = 'block', playbackRate = 1, muted = true, type = 'video/mp4', autoplay = false, controls = true}) => {
        const videoElement = document.createElement("video");
        videoElement.id = id;
        videoElement.src = src;
        videoElement.classList.add(src);
        videoElement.type = type;
        videoElement.autoplay = autoplay;
        videoElement.controls = controls;
        videoElement.style.display = display;
        videoElement.muted = muted;
        videoElement.playbackRate = playbackRate;
        return videoElement;
    };


    const addVideos = (container, videoUrls) => {
        const videos = videoUrls.map((url, index) => {
            const first = index === 0;
            const display = first ? 'block' : 'none';
            return createVideo({id: `video-${index}`, src: url,display, width: 640, autoplay: first, playbackRate: 3});
        });
        videos.forEach((video, index) => {
            const last = index === videos.length - 1;
            const playNext = (element) => {
                element.target.style.display = "none";
                const nextElementIndex = last ? 0 : index + 1;
                const nextElement = videos[nextElementIndex];
                nextElement.autoplay = true;
                nextElement.style.display="block";
                nextElement.load();
            };
            video.addEventListener("ended", playNext);
            container.appendChild(video)
        });
    };
    const videoWrapper = document.getElementById('video-wrapper');
    addVideos(videoWrapper, videoUrls);
#video-wrapper video {
    max-width: 600px;
}
<div id="video-wrapper"></div>


使用 setTimeout 的工作解决方案(请使用上面的解决方案)

const videoUrls = [{
    url: `https://videos-play-loop.netlify.com/video3.mp4`,
    duration: 3,
  },
  {
    url: `https://videos-play-loop.netlify.com/video2.mp4`,
    duration: 4
  },
  {
    url: `https://videos-play-loop.netlify.com/video1.mp4`,
    duration: 5
  }
];


const createVideo = ({
  id,
  src,
  width,
  cls = 'video',
  display = 'block',
  duration,
  playbackRate = 1,
  muted = true,
  type = 'video/mp4',
  autoplay = false,
  controls = true
}) => {
  const videoElement = document.createElement("video");
  videoElement.id = id;
  videoElement.src = src;
  videoElement.classList.add(src);
  videoElement.type = type;
  videoElement.autoplay = autoplay;
  videoElement.controls = controls;
  videoElement.style.display = display;
  videoElement.muted = muted;
  videoElement.playbackRate = playbackRate;
  videoElement.setAttribute('data-duration', duration);
  return videoElement;
};

const playNext = (videos, index) => {
  const current = videos[index];
  const activeVideoDuration = parseInt(current.dataset.duration) * 1000;
  setTimeout(() => {
    const last = index === videos.length - 1;
    current.style.display = "none";
    current.pause();
    const activeVideoIndex = last ? 0 : index + 1;
    const next = videos[activeVideoIndex];
    next.autoplay = true;
    next.style.display = "block";
    next.load();
    next.play();
    playNext(videos, activeVideoIndex);
  }, activeVideoDuration);
};


const addVideos = (container, videoUrls) => {
  const videos = videoUrls.map((video, index) => {
    const {
      url,
      duration
    } = video;
    const first = index === 0;
    const display = first ? 'block' : 'none';
    return createVideo({
      id: `video-${index}`,
      src: url,
      duration,
      display,
      width: 640,
      autoplay: first,
    });
  });

  videos.forEach(video => container.appendChild(video));
  playNext(videos, 0);
};

const videoWrapper = document.getElementById('video-wrapper');
addVideos(videoWrapper, videoUrls);
#video-wrapper video {
  max-width: 600px;
}
<div id="video-wrapper"></div>

关于javascript - 使用 setTimeout 循环播放视频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60635606/

相关文章:

javascript - 什么触发 android chrome 显示 "make page mobile-friendly"面板?

javascript - 使用下一个和上一个按钮从 JSON 文件播放 HTML5 视频

javascript - Javascript 中的异步循环

javascript - 按下鼠标按钮时继续上下移动元素

javascript - 从嵌入式 iframe 中获取全局变量

javascript - 使用 HTML5 视频元素反向播放视频

html - 在 IE6 CSS 的 anchor 标记内设置跨度样式时遇到问题

javascript - HTML5 视频在 iPad 上逐帧前进和倒带问题

html - 使用 HTML5 视频标签播放本地(硬盘)视频文件?

javascript - 从数组值生成数组菜单