2013-10-04 54 views
28

我想每5秒从视频捕捉一帧。使用HTML5和JavaScript从视频捕获帧

这是我的JavaScript代码:

video.addEventListener('loadeddata', function() { 
    var duration = video.duration; 
    var i = 0; 

    var interval = setInterval(function() { 
     video.currentTime = i; 
     generateThumbnail(i); 
     i = i+5; 
     if (i > duration) clearInterval(interval); 
    }, 300); 
}); 

function generateThumbnail(i) {  
    //generate thumbnail URL data 
    var context = thecanvas.getContext('2d'); 
    context.drawImage(video, 0, 0, 220, 150); 
    var dataURL = thecanvas.toDataURL(); 

    //create img 
    var img = document.createElement('img'); 
    img.setAttribute('src', dataURL); 

    //append img in container div 
    document.getElementById('thumbnailContainer').appendChild(img); 
} 

我是生成的第一两个图像的问题是相同的,并且不产生持续时间-5第二图像。我发现缩略图是在< video>标记中显示特定时间的视频帧之前生成的。

例如,当video.currentTime = 5时,生成帧0的图像。然后视频帧跳到时间5秒。所以当video.currentTime = 10时,会产生第5帧的图像。

+1

什么是theCanvas您generateThumbnail功能?你能否提供这个问题的html标签更有用?我正在尝试做同样的事情,但我不确定应如何在页面上声明Canvas。谢谢! – alejosoft

回答

36

原因

的问题是,寻求视频(通过设置它的currentTime)是异步的。

您需要聆听seeked事件,否则会冒险考虑可能是您的旧值的实际当前帧。

由于它是异步的,因此它不能使用setInterval(),因为它也是异步的,并且在下一帧搜索时无法正确同步。没有必要使用setInterval(),因为我们将使用seeked事件来代替,这将保持一切都是同步的。

解决方案

通过重新编写代码一点,你就可以使用seeked事件经过的视频捕捉正确的帧作为本次活动,确保我们,我们实际上是在我们要求通过设置在框架currentTime属性。

// global or parent scope of handlers 
var video = document.getElementById("video"); // added for clarity: this is needed 
var i = 0; 

video.addEventListener('loadeddata', function() { 
    this.currentTime = i; 
}); 

此事件处理程序添加到方:

video.addEventListener('seeked', function() { 

    // now video has seeked and current frames will show 
    // at the time as we expect 
    generateThumbnail(i); 

    // when frame is captured increase, here by 5 seconds 
    i += 5; 

    // if we are not passed end, seek to next interval 
    if (i <= this.duration) { 
     // this will trigger another seeked event 
     this.currentTime = i; 
    } 
    else { 
     // Done!, next action 
    } 
}); 

Demo here

+2

我试过使用你的代码。现在我有另一个问题。由于查找,当我通过点击时间线查看视频时,图像也会生成。但我不想那样。 **编辑**我已经解决了这个问题。谢谢。 – Lin

+0

'video.currentTime = i;'不会为我引发任何查找事件。 – Michael

+0

@迈克尔当时是否解决了你的问题? – Martian2049