112 lines
4.3 KiB
HTML
112 lines
4.3 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
|
|
|
<html lang="en">
|
|
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<style>
|
|
body
|
|
{
|
|
background: #000;
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<!-- WebGL output will be drawn here through Emscripten -->
|
|
<canvas id="canvas"></canvas>
|
|
|
|
<!-- navigator.mediaDevices.getUserMedia will stream the webcam video directly here for testing -->
|
|
<video id="webcam"></video>
|
|
|
|
<script>
|
|
const FPS = 15;
|
|
const BPP = 4;
|
|
|
|
// Direct output of webcam
|
|
var video = document.getElementById("webcam");
|
|
video.width = 320;
|
|
video.height = 240;
|
|
|
|
// Undisplayed canvas which is used to draw the video frame and then read the pixel data directly
|
|
var intermediate = document.createElement("canvas");
|
|
intermediate.width = video.width;
|
|
intermediate.height = video.height;
|
|
var context = intermediate.getContext("2d");
|
|
|
|
// Indicates whether webcam is opened or not
|
|
var streaming = false;
|
|
|
|
// Address of the webcam frame pixel data on the Emscripten heap
|
|
var image_heap_address;
|
|
|
|
var Module = {
|
|
onRuntimeInitialized: function()
|
|
{
|
|
|
|
// Open the webcam and start displaying frames if successfully opened. Allocate space for 32-bit RGBA frame pixel data
|
|
// on the Emscripten heap.
|
|
navigator.mediaDevices.getUserMedia({video: {width: video.width, height: video.height}, audio: false})
|
|
.then(function(stream) {
|
|
video.srcObject = stream;
|
|
video.play();
|
|
streaming = true;
|
|
|
|
// Get the memory address of the pixel data
|
|
image_heap_address = Module._malloc(video.width * video.height * BPP);
|
|
|
|
// Pass the address to the C++ program
|
|
Module.set_heap_offset(image_heap_address);
|
|
})
|
|
.catch(function(err) {
|
|
console.log('Camera Error: ' + err.name + ' ' + err.message);
|
|
});
|
|
|
|
// This function will run continuously, drawing the webcam frame to the intermediate canvas, reading the pixel data,
|
|
// storing the data on the heap, and setting the new frame available flag.
|
|
function processVideo()
|
|
{
|
|
try
|
|
{
|
|
if (streaming)
|
|
{
|
|
// Draw the webcam frame on a hidden canvas
|
|
context.drawImage(video, 0, 0, video.width, video.height);
|
|
|
|
// Read the pixel data
|
|
image_data = context.getImageData(0, 0, video.width, video.height).data;
|
|
|
|
// Get a memory view object that provides access to the heap at the previously allocated address
|
|
image_heap_data = new Uint8Array(Module.HEAPU8.buffer, image_heap_address, video.width * video.height * BPP);
|
|
|
|
// Write the pixel data to the heap
|
|
image_heap_data.set(image_data);
|
|
|
|
// Flag the C++ that new data is available
|
|
Module.flag_frame();
|
|
}
|
|
|
|
// Loop processVideo at roughly the FPS
|
|
let begin = Date.now();
|
|
let delay = 1000/FPS - (Date.now() - begin);
|
|
setTimeout(processVideo, delay);
|
|
}
|
|
catch (err)
|
|
{
|
|
console.log(err);
|
|
}
|
|
}
|
|
processVideo();
|
|
},
|
|
|
|
// Tell Emscripten to use this canvas for display
|
|
canvas: document.getElementById("canvas")
|
|
};
|
|
</script>
|
|
|
|
<!-- This file is built by Emscripten when compiling the program -->
|
|
<script src="browser_webcam_test.js"></script>
|
|
</body>
|
|
</html>
|