Spaces:
Build error
Build error
File size: 5,226 Bytes
30c32c8 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
(function () {
const BENCHMARK_THROTTLE = 250;
const INTERVAL = 33;
const video = document.createElement('video');
navigator.getUserMedia({
audio: false,
video: {
width: {min: 480, ideal: 640},
height: {min: 360, ideal: 480}
}
}, stream => {
video.autoplay = true;
video.src = window.URL.createObjectURL(stream);
// Get the track to hint to the browser the stream needs to be running
// even though we don't add the video tag to the DOM.
stream.getTracks();
video.addEventListener('play', () => {
video.width = video.videoWidth;
video.height = video.videoHeight;
});
}, err => {
// eslint-disable-next-line no-console
console.log(err);
});
const VideoMotion = window.Scratch3VideoSensingDebug.VideoMotion;
const VideoMotionView = window.Scratch3VideoSensingDebug.VideoMotionView;
// Create motion detector
const motion = new VideoMotion();
// Create debug views that will render different slices of how the detector
// uses a frame of input.
const OUTPUT = VideoMotionView.OUTPUT;
const outputKeys = Object.keys(OUTPUT);
const outputValues = Object.values(OUTPUT);
const views = outputValues
.map(output => new VideoMotionView(motion, output));
const view = views[0];
const defaultViews = [OUTPUT.INPUT, OUTPUT.XY_CELL, OUTPUT.T_CELL, OUTPUT.UV_CELL];
// Add activation toggles for each debug view.
const activators = document.createElement('div');
activators.style.userSelect = 'none';
outputValues.forEach((output, index) => {
const checkboxLabel = document.createElement('label');
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.checked = defaultViews.indexOf(output) !== -1;
const checkboxSpan = document.createElement('span');
checkboxSpan.innerText = outputKeys[index];
checkboxLabel.appendChild(checkbox);
checkboxLabel.appendChild(checkboxSpan);
const _view = views[index];
_view.canvas.style.display = checkbox.checked ? '' : 'none';
_view.active = checkbox.checked;
checkbox.onchange = event => {
_view.canvas.style.display = checkbox.checked ? '' : 'none';
_view.active = checkbox.checked;
event.preventDefault();
return false;
};
activators.appendChild(checkboxLabel);
});
document.body.appendChild(activators);
// Add a text line to display milliseconds per frame, motion value, and
// motion direction
const textContainer = document.createElement('div');
const textHeader = document.createElement('div');
textHeader.innerText = 'duration (us) :: motion amount :: motion direction';
textContainer.appendChild(textHeader);
const textEl = document.createElement('div');
textEl.innerText = `0 :: 0 :: 0`;
textContainer.appendChild(textEl);
document.body.appendChild(textContainer);
let textTimer = Date.now();
// Add the motion debug views to the dom after the text line, so the text
// appears first.
views.forEach(_view => document.body.appendChild(_view.canvas));
// Create a temporary canvas the video will be drawn to so the video's
// bitmap data can be transformed into a TypeArray.
const tempCanvas = document.createElement('canvas');
tempCanvas.width = view.canvas.width;
tempCanvas.height = view.canvas.height;
const ctx = tempCanvas.getContext('2d');
const loop = function () {
const timeoutId = setTimeout(loop, INTERVAL);
try {
// Get the bitmap data for the video frame
ctx.scale(-1, 1);
ctx.drawImage(
video,
0, 0, video.width || video.clientWidth, video.height || video.clientHeight,
-tempCanvas.width, 0, tempCanvas.width, tempCanvas.height
);
ctx.resetTransform();
const data = ctx.getImageData(0, 0, tempCanvas.width, tempCanvas.height);
// Analyze the latest frame.
const b = performance.now();
motion.addFrame(data.data);
motion.analyzeFrame();
// Every so often update the visible debug numbers with duration in
// microseconds, the amount of motion and the direction of the
// motion.
if (Date.now() - textTimer > BENCHMARK_THROTTLE) {
const e = performance.now();
const analyzeDuration = ((e - b) * 1000).toFixed(0);
const motionAmount = motion.motionAmount.toFixed(1);
const motionDirection = motion.motionDirection.toFixed(1);
textEl.innerText = `${analyzeDuration} :: ${motionAmount} :: ${motionDirection}`;
textTimer = Date.now();
}
views.forEach(_view => _view.active && _view.draw());
} catch (error) {
// eslint-disable-next-line no-console
console.error(error.stack || error);
clearTimeout(timeoutId);
}
};
loop();
}());
|