From 0d5beb0c4e4edbf900fa98cceae7a72a93a89420 Mon Sep 17 00:00:00 2001 From: Gabriel Borlea Date: Wed, 8 Dec 2021 09:27:17 +0200 Subject: [PATCH] fix(facial-expressions) load worker as a blob --- react/features/facial-recognition/actions.js | 20 +++++++++- .../facialExpressionsWorker.js | 40 +++++++++---------- .../features/facial-recognition/middleware.js | 1 - 3 files changed, 37 insertions(+), 24 deletions(-) diff --git a/react/features/facial-recognition/actions.js b/react/features/facial-recognition/actions.js index e8a681d000..85b87c3c8a 100644 --- a/react/features/facial-recognition/actions.js +++ b/react/features/facial-recognition/actions.js @@ -56,7 +56,20 @@ export function loadWorker() { return; } - worker = new Worker('libs/facial-expressions-worker.min.js', { name: 'Facial Expression Worker' }); + let baseUrl = ''; + const app: Object = document.querySelector('script[src*="app.bundle.min.js"]'); + + if (app) { + const idx = app.src.lastIndexOf('/'); + + baseUrl = `${app.src.substring(0, idx)}/`; + } + let workerUrl = `${baseUrl}facial-expressions-worker.min.js`; + + const workerBlob = new Blob([ `importScripts("${workerUrl}");` ], { type: 'application/javascript' }); + + workerUrl = window.URL.createObjectURL(workerBlob); + worker = new Worker(workerUrl, { name: 'Facial Expression Worker' }); worker.onmessage = function(e: Object) { const { type, value } = e.data; @@ -89,6 +102,11 @@ export function loadWorker() { } } }; + worker.postMessage({ + id: 'SET_MODELS_URL', + url: baseUrl + }); + dispatch(startFacialRecognition()); }; } diff --git a/react/features/facial-recognition/facialExpressionsWorker.js b/react/features/facial-recognition/facialExpressionsWorker.js index b9a92916a7..58778d3df1 100644 --- a/react/features/facial-recognition/facialExpressionsWorker.js +++ b/react/features/facial-recognition/facialExpressionsWorker.js @@ -7,6 +7,11 @@ import * as faceapi from 'face-api.js'; */ let modelsLoaded = false; +/** + * The url where the models for the facial detection of expressions are located. + */ +let modelsURL; + /** * A flag that indicates whether the tensorflow backend is set or not. */ @@ -41,22 +46,26 @@ const window = { }; - onmessage = async function(message) { + if (message.data.id === 'SET_MODELS_URL') { + modelsURL = message.data.url; + } + // Receives image data if (message.data.id === 'SET_TIMEOUT') { - - if (message.data.imageData === null || message.data.imageData === undefined) { - return; + if (!message.data.imageData || !modelsURL) { + self.postMessage({ + type: 'facial-expression', + value: null + }); } // the models are loaded if (!modelsLoaded) { - await faceapi.loadTinyFaceDetectorModel('.'); - await faceapi.loadFaceExpressionModel('.'); + await faceapi.loadTinyFaceDetectorModel(modelsURL); + await faceapi.loadFaceExpressionModel(modelsURL); modelsLoaded = true; } - faceapi.tf.engine().startScope(); const tensor = faceapi.tf.browser.fromPixels(message.data.imageData); const detections = await faceapi.detectSingleFace( @@ -82,29 +91,17 @@ onmessage = async function(message) { } } faceapi.tf.engine().endScope(); - let facialExpression; if (detections) { facialExpression = detections.expressions.asSortedArray()[0].expression; } - - if (timeoutDuration === -1) { - + timer = setTimeout(() => { self.postMessage({ type: 'facial-expression', value: facialExpression }); - } else { - timer = setTimeout(() => { - self.postMessage({ - type: 'facial-expression', - value: facialExpression - }); - }, timeoutDuration); - } - - + }, timeoutDuration); } else if (message.data.id === 'CLEAR_TIMEOUT') { // Clear the timeout. if (timer) { @@ -112,5 +109,4 @@ onmessage = async function(message) { timer = null; } } - }; diff --git a/react/features/facial-recognition/middleware.js b/react/features/facial-recognition/middleware.js index 67f3faad6a..41430e6dc0 100644 --- a/react/features/facial-recognition/middleware.js +++ b/react/features/facial-recognition/middleware.js @@ -29,7 +29,6 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => action => { } if (action.type === CONFERENCE_JOINED) { dispatch(loadWorker()); - dispatch(startFacialRecognition()); return next(action); }