繁体   English   中英

如何使用HTML5创建帧精确的视频序列器 <video> ?

[英]How to create a frame-accurate video sequencer with HTML5 <video>?

我正在尝试构建一个能够无缝串联播放视频URL列表的视频序列器。 视频之间不能有差距; 播放需要尽可能接近帧精确。

尝试#1我使用了一种相当明显和直接的方法,类似于这个线程中提到的方法。 HTML 5视频或音频播放列表

这种方法的问题在于,每当一个视频结束并且后续视频被指定为新源时,新视频仍然需要加载,从而导致可能存在长的差距。 如果甚至可以在video.src中命名之前强制所有视频都进行预加载,那么这种方法仍然有效。

尝试#2我重写了脚本,因此列表中的每个视频都会导致创建一个单独的视频元素,但不会附加到文档中(使用createElement)。 然后,当每个视频结束时,我删除了前一个节点并附加了下一个元素。

在页面加载时执行的代码:

for (i in timelinePlay)
    if (timelinePlay[i] != null)        
    {
        var element = document.createElement('video');
        element.id = 'video1-' + (i);
        element.src = timelinePlay[i]['URL'];
        element.preload = 'load';
        video1Array[i] = element;
    }

视频'已结束'活动代码:

videoElement.addEventListener("ended", function (event) {
    if (this.currentTime > 0)
    {
        if (player.hasChildNodes())
            while (player.childNodes.length > 0)
                player.removeChild(player.firstChild);

        player = document.getElementById('canvas-player');
        player.appendChild(video1Array[timelineCurrent]);

        nextVideo = document.getElementById('video1-' + timelineCurrent);

        nextVideo.play();

        timelineCurrent++;
    }
}, false);

(请注意,这些代码示例是部分的,并且有些简化。另外,我确实认识到我将对象用作关联数组不是最佳实践)

这种修改的结果更接近,因为视频现在在他们被要求播放时加载,但视频之间仍然存在短暂且不一致的差距。

尝试#3我用'timeupdate'监听器替换了'ends'事件监听器,开头如下:

nextVideo.addEventListener("timeupdate", function (event)
{
    if (this.currentTime > (this.duration - 0.1)  && this.currentTime > 1)
    {
        this.removeEventListener("timeupdate", function () { return; }, false);

('this.currentTime> 1'只是为了确保以前的视频实际播放)

我希望视频之间的差距足够接近以保持一致,即在上一个视频结束之前的任意0.1秒开始下一个视频会将间隙纠正到可接受的程度。 结果是时间确实更好,但它正在跳过视频。 我将跳过的视频归因于'timeupdate'事件的失误,但我可能会弄错。

我也考虑过的其他备选方案:SMIL脚本(似乎已经过时,并且可能会有相同的同步问题)ffmpeg在后端连接视频(我的主机不允许shell脚本)

仅供参考我目前正在为Safari 5.0.3开发

由于你的提示,我有一个类似的问题,我现在设法解决了。 结果是可能动态的视频元素列表,可以一个接一个地播放而没有间隙。

我在几个视频元素上使用jwplayer而不是原生视频标签。 在启动时,所有元素开始播放一秒,暂停并重绕为零。 然后逐个播放并使用display:block显示。

<ul class="playlist">
    <li>
        <video class="playlist" id="vid01" poster="img/preview.jpg">
            <source src="vid/v01.mp4" type="video/mp4">
        </video>
    </li>
    <li>
        <video class="playlist" id="vid02" poster="img/preview.jpg">
            <source src="vid/v02.mp4" type="video/mp4">
        </video>
    </li>
    <li>
        <video class="playlist" id="vid03" poster="img/preview.jpg">
            <source src="vid/v03.mp4" type="video/mp4">
        </video>
    </li>
    <li>
        <video class="playlist" id="vid04" poster="img/preview.jpg">
            <source src="vid/v04.mp4" type="video/mp4">
        </video>
    </li>
</ul>

在添加到舞台上,“预加载”视频一两秒钟:(摘录)

var isPrebuffering = false,
    isSeeking = false;

$player = jwplayer(videoId).setup({
    width: '800px',
    height: '450px',
    autoplay: false,
    modes: [
        { type: 'html5' }
    ],
    events: {
        onReady: function(e) {
            prebuffer();
        },
// There is a quirk in jwplayer that makes it impossible to pause at the 
// new position directly after seeking. So we have to work around that.
        onTime: function(e) {
            if((e.position > 1.0 && isPrebuffering) || isSeeking) {
                finishPrebuffering();
            }
        }
    }
});

function prebuffer() {
    isPrebuffering = true;
    $player.setMute(true);
    $player.play();
};

function finishPrebuffering() {
    if(isPrebuffering) {
        isPrebuffering = false;
        isSeeking = true;
        $player.seek(0);
    }

    if($player.getPosition() === 0) {
        isSeeking = false;
        $player.pause();
        $player.setMute(false);
    }
};

你可以用http://popcornjs.org/这样做。 他们使用html5视频标签在一帧一帧的视频中提供js钩子。 有很多活动等

HTML5的mediaElement接口有时会在preload,load和buffered之间相当混乱。 但是,您是否尝试在视频结束前3秒检测视频事件? 然后在ajax中尝试在新的div中加载下一个视频。 在您的视频结束事件中,您可以切换div,以便您的下一个视频足够加载以进行播放。 等等下一个视频。

http://www.w3.org/TR/html5/video.html#media-elements

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM