diff --git a/demo/browser.js b/demo/browser.js index 80826a1c..0038c529 100644 --- a/demo/browser.js +++ b/demo/browser.js @@ -134,10 +134,10 @@ async function drawResults(input) { const avgDetect = Math.trunc(10 * ui.detectFPS.reduce((a, b) => a + b, 0) / ui.detectFPS.length) / 10; const avgDraw = Math.trunc(10 * ui.drawFPS.reduce((a, b) => a + b, 0) / ui.drawFPS.length) / 10; const warning = (ui.detectFPS.length > 5) && (avgDetect < 5) ? 'warning: your performance is low: try switching to higher performance backend, lowering resolution or disabling some models' : ''; - document.getElementById('log').innerHTML = ` - video: ${ui.camera.name} | facing: ${ui.camera.facing} | screen: ${window.innerWidth} x ${window.innerHeight} camera: ${ui.camera.width} x ${ui.camera.height} ${processing}
- backend: ${human.tf.getBackend()} | ${memory}
- performance: ${str(result.performance)} FPS process:${avgDetect} refresh:${avgDraw}
+ document.getElementById('log').innerText = ` + video: ${ui.camera.name} | facing: ${ui.camera.facing} | screen: ${window.innerWidth} x ${window.innerHeight} camera: ${ui.camera.width} x ${ui.camera.height} ${processing} + backend: ${human.tf.getBackend()} | ${memory} + performance: ${str(result.performance)}ms FPS process:${avgDetect} refresh:${avgDraw} ${warning} `; @@ -169,7 +169,8 @@ async function setupCamera() { output.innerText += `\n${msg}`; log(msg); status(msg); - return null; + ui.busy = false; + return msg; } let stream; const constraints = { @@ -181,15 +182,20 @@ async function setupCamera() { try { stream = await navigator.mediaDevices.getUserMedia(constraints); } catch (err) { - if (err.name === 'PermissionDeniedError') msg = 'camera permission denied'; + if (err.name === 'PermissionDeniedError' || err.name === 'NotAllowedError') msg = 'camera permission denied'; else if (err.name === 'SourceUnavailableError') msg = 'camera not available'; - else msg = 'camera error'; + else msg = `camera error: ${err.message || err}`; output.innerText += `\n${msg}`; status(msg); - log(err); + log('camera error:', err); + ui.busy = false; + return msg; } if (stream) video.srcObject = stream; - else return null; + else { + ui.busy = false; + return 'camera stream empty'; + } const track = stream.getVideoTracks()[0]; const settings = track.getSettings(); // log('camera constraints:', constraints, 'window:', { width: window.innerWidth, height: window.innerHeight }, 'settings:', settings, 'track:', track); @@ -215,7 +221,7 @@ async function setupCamera() { // do once more because onresize events can be delayed or skipped // if (video.width > window.innerWidth) await setupCamera(); status(''); - resolve(video); + resolve(); }; }); } @@ -299,8 +305,10 @@ function runHumanDetect(input, canvas, timestamp) { bench.nextFrame(timestamp); } if (document.getElementById('gl-bench')) document.getElementById('gl-bench').style.display = ui.bench ? 'block' : 'none'; - if (result.error) log(result.error); - else { + if (result.error) { + log(result.error); + document.getElementById('log').innerText += `\nHuman error: ${result.error}`; + } else { lastDetectedResult = result; if (!ui.drawThread) drawResults(input); ui.framesDetect++; @@ -352,15 +360,19 @@ async function detectVideo() { status('paused'); video.pause(); } else { - await setupCamera(); - document.getElementById('play').style.display = 'none'; - for (const m of Object.values(menu)) m.hide(); - status(''); - document.getElementById('btnStart').className = 'button button-stop'; - document.getElementById('btnStart').innerHTML = 'pause
video'; - video.play(); + const cameraError = await setupCamera(); + if (!cameraError) { + document.getElementById('play').style.display = 'none'; + for (const m of Object.values(menu)) m.hide(); + status(''); + document.getElementById('btnStart').className = 'button button-stop'; + document.getElementById('btnStart').innerHTML = 'pause
video'; + await video.play(); + if (!ui.detectThread) runHumanDetect(video, canvas); + } else { + status(cameraError); + } } - if (!ui.detectThread) runHumanDetect(video, canvas); } // just initialize everything and call main function diff --git a/src/human.js b/src/human.js index ae6220a4..599a6c6d 100644 --- a/src/human.js +++ b/src/human.js @@ -348,6 +348,11 @@ class Human { timeStamp = now(); const process = image.process(input, this.config); + if (!process || !process.tensor) { + this.log('could not convert input to tensor'); + resolve({ error: 'could not convert input to tensor' }); + return; + } this.perf.image = Math.trunc(now() - timeStamp); this.analyze('Get Image:'); diff --git a/src/image.js b/src/image.js index 63f48405..df265d15 100644 --- a/src/image.js +++ b/src/image.js @@ -21,6 +21,11 @@ function process(input, config) { else if (config.filter.height > 0) targetWidth = originalWidth * (config.filter.height / originalHeight); if (config.filter.height > 0) targetHeight = config.filter.height; else if (config.filter.width > 0) targetHeight = originalHeight * (config.filter.width / originalWidth); + if (!targetWidth || !targetHeight) { + // eslint-disable-next-line no-console + console.log('Human: invalid input', input); + return null; + } if (!inCanvas || (inCanvas.width !== targetWidth) || (inCanvas.height !== targetHeight)) { inCanvas = (typeof OffscreenCanvas !== 'undefined') ? new OffscreenCanvas(targetWidth, targetHeight) : document.createElement('canvas'); if (inCanvas.width !== targetWidth) inCanvas.width = targetWidth;