【问题标题】:How can I sync two HTML video elements that are on autoplay/loop?如何同步自动播放/循环中的两个 HTML 视频元素?
【发布时间】: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 新手,但我的猜测是有一些方法可以检测视频的第一帧和最后一帧,然后可以使用这些方法开始/停止第二个视频,并且视频在“循环”上,这可以继续无限期地。如果有人可以为我指明正确的方向或任何其他解决方案,那将非常有帮助!

谢谢。

【问题讨论】:

    标签: javascript html video synchronization html5-video


    【解决方案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 ${deltaMilliseconds}ms. 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 上查找库。我没有看过,但正在搜索“音频混音器”或某些东西可能会指向您某个地方...

    【讨论】:

    • 另一种选择是将两个视频并排编码,然后将每个“片段”绘制到不同的画布上。可以使视频标签不可见,同时保持其声音播放。
    猜你喜欢
    • 1970-01-01
    • 2022-11-01
    • 1970-01-01
    • 2015-08-27
    • 2015-11-26
    • 1970-01-01
    • 2016-12-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多