2016-01-20 129 views
0

我有一个脚本,允许我在画布上显示摄像头,并在某些间隔内“下载”特定的帧。 当时间参数很大时(每2秒捕获30分钟),我遇到了麻烦。它工作顺利约15分钟,然后崩溃(Firefox关闭,内存不足错误)。此外,重新启动Firefox后,有时会在3-4分钟内拍摄很多0字节的照片,然后再次开始工作。我在放置在实验室中的旧的2 GB RAM机器上运行该程序,是否有减少内存使用量的方法?从画布中间隔拍摄照片

这是一段带参数和功能realizarCapturas的代码。 我可以添加静止代码,但我认为要优化的部分应该是这一个。

var frecuenciaComienzoCaptura = 1; // how long till next capture 
    var frecuenciaCaptura = 3; //seconds between photos 
    var duracion = 5; // amount of photos to capture 

    function realizarCapturas(){ 
    var i = 1; 
    var interval = setInterval(function(){ 
     if(i <= duracion){ 
     context.drawImage(video, 0, 0, 640, 480); 

     var imagen = document.getElementById("imagen"); 
     imagen.href = canvas.toDataURL("image/png"); 

     var now = new Date(); 
     var filename = formatNumber(now.getHours()) + "-" + formatNumber(now.getMinutes()) + "-" + formatNumber(now.getSeconds()); 

     imagen.download = filename + ".png"; // Make sure the browser downloads the image 
     imagen.click(); // Trigger the click 
     i = i+1; 
     }else{ 
     clearInterval(interval); 
     } 
    }, frecuenciaCaptura * 1000); 
    } 



    setInterval(function(){ 
    realizarCapturas(); 
    }, frecuenciaComienzoCaptura * 1000 * 60 * 60); 

    realizarCapturas(); 


}, false); 
+0

您可能会叠加未完成的操作。尝试使用单个'requestAnimationFrame'循环而不是多个间隔进行重构。使用开发工具监视资源使用情况。 – markE

回答

1

作为一个规则不要使用setInterval,因为它可以调用堆栈溢出,这是非常困难的代码来检测源。

你的问题是,你没有清除你正在产生的所有间隔,因此你每创建一个新的间隔事件3秒钟。最终,运行一小段代码所需的时间将比您创建的所有时间间隔事件所能处理的时间长,因此每个时间间隔将继续将其事件推送到调用堆栈中,但不会有机会成为直到有更多的时间间隔放在堆栈上,最终导致崩溃。 setInterval也不保证事件之间的时间是准确的。

改为使用setTimeout。这样,您只会根据需要生成事件,而且您无需保留关闭事件的句柄。

下面是您编写的代码,以便您永远不会有调用堆栈溢出。

var frecuenciaComienzoCaptura = 1 * 1000* 60 * 60; // how long till next capture 
var frecuenciaCaptura = 3 * 1000; //seconds between photos 
var duracion = 5; // amount of photos to capture 
var counter = 0; 
// the capture function 
var captura = function() {  
    counter = counter + 1; 
    if(counter < duracion){ // do we need more images? 
     // only create timer events as needed. 
     setTimeout(captura, frecuenciaCaptura); //set time till next image 
    } 
    context.drawImage(video, 0, 0, 640, 480); 
    var imagen = document.getElementById("imagen"); 
    imagen.href = canvas.toDataURL("image/png"); 

    var now = new Date(); 
    var filename = formatNumber(now.getHours()) + "-" + formatNumber(now.getMinutes()) + "-" + formatNumber(now.getSeconds()); 

    imagen.download = filename + ".png"; // Make sure the browser downloads the image 
    imagen.click(); // Trigger the click 
} 

function realizarCapturas() { 
    // request next batch of captures by only creating one timer event as we need 
    setTimeout(realizarCapturas,frecuenciaComienzoCaptura); 
    counter = 0; // reset counter 
    captura(); // capture timages 
} 

// start captures. 
realizarCapturas(); 
+0

似乎在今天下午工作完美,它也似乎更容易记忆的要求,因为图像创建几乎在同一时间的实际时间 –