2012-07-26 70 views
0

我试图生成一组缩略图的浏览器进行使用帆布与此代码HTML5视频:捕获组

 var fps = video_model.getFps(); //frames per second, comes from another script 
     var start = shot.getStart(); //start time of capture, comes from another script 
     var end = shot.getEnd(); //end time of capture, comes from another script 

     for(var i = start; i <= end; i += 50){ //capture every 50 frames 
      video.get(0).currentTime = i/fps; 

      var capture = $(document.createElement("canvas")) 
       .attr({ 
        id: video.get(0).currentTime + "sec", 
        width: video.get(0).videoWidth, 
        height: video.get(0).videoHeight 
       }) 

      var ctx = capture.get(0).getContext("2d"); 
      ctx.drawImage(video.get(0), 0, 0, video.get(0).videoWidth, video.get(0).videoHeight); 

      $("body").append(capture, " "); 

     } 

的捕获量是正确的,但问题在Chrome中,所有画布都显示为黑色,而在Firefox中,它们总是显示相同的图像。

也许问题在于循环太快而不能让画布上色,但我读过.drawImage()是异步的,因此理论上应该让画布在跳到下一行之前进行绘制。

有关如何解决此问题的任何想法? 谢谢。

回答

0

经过数小时的战斗后,我终于想出了一个基于“seeked”事件的解决方案。对于这项工作,视频必须被完全加载:

的代码是这样的:

 var fps = video_model.getFps(); //screenshot data, comes from another script 
     var start = shot.getStart(); 
     var end = shot.getEnd(); 


     video.get(0).currentTime = start/fps; //make the video jump to the start 


     video.on("seeked", function(){ //when the time is seeked, capture screenshot 
      setTimeout(//the trick is in giving the canvas a little time to be created and painted, 500ms should be enough 
       function(){ 
        if(video.get(0).currentTime <= end/fps){ 

         var capture = $(document.createElement("canvas")) //create canvas element on the fly 
         .attr({ 
          id: video.get(0).currentTime + "sec", 
          width: video.get(0).videoWidth, 
          height: video.get(0).videoHeight 
         }) 
         .appendTo("body"); 

         var ctx = capture.get(0).getContext("2d"); //paint canvas 
         ctx.drawImage(video.get(0), 0, 0, video.get(0).videoWidth, video.get(0).videoHeight); 

         if(video.get(0).currentTime + 50/fps > end/fps){ 
          video.off("seeked"); //if last screenshot was captured, unbind 
         }else{ 
           video.get(0).currentTime += 50/fps; //capture every 50 frames 
         } 


        } 
       } 
       , 500); //timeout of 500ms 


     }); 

这为我在Chrome和Firefox的工作,我读过的seeked事件可能是越野车在某些版本的特定浏览器中。

希望这对任何人都有用。如果有人想出一个更清洁,更好的解决方案,很高兴看到它。