如何同步自动播放/循环中的两个 HTML 视频元素?

Posted

技术标签:

【中文标题】如何同步自动播放/循环中的两个 HTML 视频元素?【英文标题】:How can I sync two HTML video elements that are on autoplay/loop? 【发布时间】:2022-01-13 20:18:42 【问题描述】:

我有两个 html 视频元素,它们在页面加载时开始自动播放,并继续无限循环,直到用户离开页面。两个视频都有 8 秒长,我需要它们始终彼此同步,但当然它们确实会不同步。对于音频,视频 1 播放完整的歌曲编曲,视频 2 仅播放同一首歌曲中的一种乐器,因此,为了显示它们相关,它们必须保持同步。

 <video id="first-video" autoplay="" muted="" loop="" playsinline="" loading="lazy" src="videos/video-1.mp4"></video>
<video id="second-video" autoplay="" muted="" loop="" playsinline="" loading="lazy" src="videos/video-2.mp4"></video>

这个 SO 问题有几种解决方案: Is there a way to keep two videos synchronized in a webpage without plugins?

但是当我尝试实施时,我发现同步质量没有变化,它们很容易不同步。我是 JS 新手,但我的猜测是有一些方法可以检测视频的第一帧和最后一帧,然后可以使用这些方法开始/停止第二个视频,并且视频在“循环”上,这可以继续无限期地。如果有人可以为我指明正确的方向或任何其他解决方案,那将非常有帮助!

谢谢。

【问题讨论】:

【参考方案1】:

简单回答

假设两个轨道在相同的当前时间 (0) 开始并以相同的速率播放,您可以不断地将第二个视频的位置更改为第一个视频的位置。这并不准确或不准确,但应该可以大致完成工作:

function syncVideos() 
    const first = document.getElementById('first-video');
    const second = document.getElementById('second-video');

    // keep track of if video's seeking to avoid constant changes to position
    // don't know if this is really necessary
    let isSeeking = false;
    second.addEventListener('seeking', () => isSeeking = true);
    second.addEventListener('seeked', () => isSeeking = false);

    const thresholdMilliseconds = 50; // some ms threshold of difference to avoid excessive seeking
    const nudgeOffsetMilliseconds = 5; // just a guess that you may need to assume that seeking won't be instantaneous. I don't know if this is necessary or helpful

    // listen for time updates on the first video's position
    first.addEventListener('timeupdate', () => 
        const deltaMilliseconds = (second.currentTime - first.currentTime) * 1000;
        if (Math.abs(delta) >= thresholdMilliseconds) 
            if (isSeeking) 
                console.warn('not in sync, but currently seeking');
                return;
            
            console.log(`out of sync by $deltaMillisecondsms. Seeking to $first.currentTime`);

            // adding a bit of nudge b/c syncing may not be instant. Not an exact science...for that use MSE
            second.currentTime = first.currentTime + nudgeOffsetMilliseconds;
        
    );

syncVideos();

“正确的方式”

使用 MSE(媒体源扩展),这可能允许更准确的搜索和同步。这可能会有所帮助:Playing one of multiple audio tracks in sync with a video

您可能想在 github 上查找库。我没有看过,但正在搜索“音频混音器”或某些东西可能会指向您某个地方...

【讨论】:

另一种选择是将两个视频并排编码,然后将每个“片段”绘制到不同的画布上。可以使视频标签不可见,同时保持其声音播放。

以上是关于如何同步自动播放/循环中的两个 HTML 视频元素?的主要内容,如果未能解决你的问题,请参考以下文章

HTML 如何让几个视频连续并循环播放,给段代码

下面的HTML代码,如何设置循环播放?

HTML5音频和视频

HTML5中audio标签的使用

如何完美同步两个或多个 html5 视频标签?

如何同步 HTML5 视频?