requestAnimFrame выполняется несколько раз

У меня есть обнаружение эмоций, работающее с openCV.js для обнаружения лиц и tensorflow.js для классификации эмоций. Когда я запускаю обнаружение эмоций, я вызываю функцию requestAnimFrame(myProcessingLogic) и передаю свою логику обнаружения в параметр обратного вызова. Моя логика обработки снова вызывает requestAnimFrame(myProcessingLogic).

При отключении обнаружения эмоций устанавливается глобальная переменная, которая затем отключает рекурсивный вызов requestAnimFrame. Это прекрасно работает.

...но при каждой повторной активации обнаружения эмоций вызов requestAnimFrame вызывается еще раз дополнительно. Это вызывает проблемы с производительностью.

Я попытался сохранить возвращенный идентификатор requestAnimFrame() глобально, чтобы вызвать cancelAnimFrame(), когда обнаружение остановлено, но это, похоже, не дало эффекта.

Первый звонок:

function startVideoProcessing() {
    if (!streaming) {
        console.warn("Please startup your webcam");
        return;
    }

    canvasInput = document.createElement('canvas');
    canvasInput.width = videoWidth;
    canvasInput.height = videoHeight;
    canvasInputCtx = canvasInput.getContext('2d');

    canvasBuffer = document.createElement('canvas');
    canvasBuffer.width = videoWidth;
    canvasBuffer.height = videoHeight;
    canvasBufferCtx = canvasBuffer.getContext('2d');

    srcMat = new cv.Mat(videoHeight, videoWidth, cv.CV_8UC4);
    grayMat = new cv.Mat(videoHeight, videoWidth, cv.CV_8UC1);

    requestAnimId = requestAnimationFrame(processVideo);
}

Логика обработки

function processVideo() {
    if(!streaming) {
        return;
    }

    /*
    logic removed to simplify
    */

    requestAnimId = requestAnimationFrame(processVideo);
}
function stopEmotionTracking() {
    stopCamera();
    cancelAnimationFrame(requestAnimId);
    requestAnimId = null;

}

Я просмотрел анализ времени выполнения firefox и увидел, что при каждой повторной активации выполняется дополнительный вызов функции.

Изображение анализа во время выполнения


person Giuseppe    schedule 07.07.2019    source источник


Ответы (1)


Баг нашел сам. Это не имело ничего общего с кодом, опубликованным выше. При каждом запуске отслеживания эмоций я добавлял EventListener к видеоэлементу. С другой стороны, EventListener выполнил startVideoProcessing. Поскольку эти прослушиватели событий накладываются друг на друга, они выполнялись несколько раз.

Для тех, кто сталкивается с той же проблемой, позаботьтесь о своих слушателях событий;)

person Giuseppe    schedule 09.07.2019