gunkiss/index.html

109 lines
4.0 KiB
HTML

<!doctype html>
<html>
<body>
<!-- WebGL output will be drawn here through Emscripten -->
<canvas id="canvas"></canvas>
<!-- navigator.mediaDevices.getUserMedia streams the webcam video directly, displayed for testing -->
<!-- <video id="webcam"></video> -->
<script>
const FPS = 15;
const BPP = 4;
// Direct output of webcam (hidden)
var video = document.createElement("video");
video.width = 320;
video.height = 240;
// Undisplayed canvas which is used to draw the video frame and access 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()
{
process_video();
},
// Tell Emscripten to use this canvas for display
canvas: document.getElementById("canvas")
};
function open_camera()
{
// 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);
});
}
function close_camera()
{
video.pause();
video.srcObject = null;
streaming = false;
}
// 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 process_video()
{
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 at roughly the FPS
let begin = Date.now();
let delay = 1000/FPS - (Date.now() - begin);
setTimeout(process_video, delay);
}
catch (err)
{
console.log(err);
}
}
</script>
<!-- This file is built by Emscripten when compiling the program -->
<script src="gunkiss.js"></script>
</body>
</html>