From 298645b34779f1124f3836150439a49fadfb45cf Mon Sep 17 00:00:00 2001 From: Harald Alvestrand Date: Thu, 6 Jun 2019 13:43:17 +0200 Subject: [PATCH] Add a demo for video->pixel data->video (#1195) * Add a demo for video->pixel data->video This demonstrates how to access raw data in a video pipeline, and allows us to measure the performance of that solution. Also adds the .js file for running a local webserver, and makes some .gitignore extensions. * Review comments, lint * Another lint message --- .gitignore | 4 +- .../capture/canvas-filter/css/main.css | 24 +++++++ src/content/capture/canvas-filter/index.html | 67 +++++++++++++++++++ src/content/capture/canvas-filter/js/main.js | 49 ++++++++++++++ web_server/server.js | 30 +++++++++ 5 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 src/content/capture/canvas-filter/css/main.css create mode 100644 src/content/capture/canvas-filter/index.html create mode 100644 src/content/capture/canvas-filter/js/main.js create mode 100644 web_server/server.js diff --git a/.gitignore b/.gitignore index 872556141..e003016dc 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,6 @@ validation-status.json .idea firefox_profile/* tests_output -*.log \ No newline at end of file +*.log +*~ +\#*# \ No newline at end of file diff --git a/src/content/capture/canvas-filter/css/main.css b/src/content/capture/canvas-filter/css/main.css new file mode 100644 index 000000000..246a06052 --- /dev/null +++ b/src/content/capture/canvas-filter/css/main.css @@ -0,0 +1,24 @@ +/* +* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. +* +* Use of this source code is governed by a BSD-style license +* that can be found in the LICENSE file in the root of the source +* tree. +*/ + +canvas { + background-color: #ccc; + --width: calc(45%); + width: var(--width); + height: calc(var(--width) * 0.75); + margin: 1em; + vertical-align: top; +} + +video { + --width: calc(45%); + width: var(--width); + height: calc(var(--width) * 0.75); + margin: 1em; + object-fit: cover; +} diff --git a/src/content/capture/canvas-filter/index.html b/src/content/capture/canvas-filter/index.html new file mode 100644 index 000000000..2f2fe9d7f --- /dev/null +++ b/src/content/capture/canvas-filter/index.html @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + Video to Canvas to video + + + + + + + + + + +
+ +

WebRTC samples Stream camera via a canvas to a video element +

+ + + + + + + +

The camera is captured to a video element, which is mapped onto a + canvas, and a red square is added.

+

The canvas is then captured to an ImageData object, and painted + onto a second canvas.

+

A stream is captured from the second canvas element using its + captureStream() method and set as the srcObject of the video element.

+ +

The inputStream, source, + canvasIn, canvasOut, + result, and stream variables are in global + scope, so you can + inspect them from the browser console.

+ + View source on GitHub + +
+ + + + + + diff --git a/src/content/capture/canvas-filter/js/main.js b/src/content/capture/canvas-filter/js/main.js new file mode 100644 index 000000000..f639aa0e4 --- /dev/null +++ b/src/content/capture/canvas-filter/js/main.js @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved. +* +* Use of this source code is governed by a BSD-style license +* that can be found in the LICENSE file in the root of the source +* tree. +*/ + +'use strict'; + +const source = document.querySelector('#source'); +// TODO(hta): Use OffscreenCanvas for the intermediate canvases. +const canvasIn = document.querySelector('#canvas-source'); +const canvasOut = document.querySelector('#canvas-result'); +const result = document.querySelector('#result'); + +const stream = canvasOut.captureStream(); +let inputStream = null; +let imageData = null; + +result.srcObject = stream; + +function loop() { + if (source.videoWidth > 0 && source.videoHeight > 0) { + canvasIn.width = source.videoWidth; + canvasIn.height = source.videoHeight; + let ctx = canvasIn.getContext('2d'); + ctx.drawImage(source, 0, 0); + // Put a red square into the image, to mark it as "processed". + ctx.fillStyle = '#FF0000'; + ctx.fillRect(10, 10, 80, 80); + imageData = ctx.getImageData(0, 0, canvasIn.width, canvasIn.height); + // At this point, we have data that can be transferred. + // We paint it on the second canvas. + canvasOut.width = source.videoWidth; + canvasOut.height = source.videoHeight; + let outCtx = canvasOut.getContext('2d'); + outCtx.putImageData(imageData, 0, 0); + } + window.requestAnimationFrame(loop); +} + +(async () => { + inputStream = await navigator.mediaDevices.getUserMedia({video: true}); + source.srcObject = inputStream; + source.play(); + result.play(); + window.requestAnimationFrame(loop); +})(); diff --git a/web_server/server.js b/web_server/server.js new file mode 100644 index 000000000..a85de6ce9 --- /dev/null +++ b/web_server/server.js @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ + /* eslint-env node */ + +'use strict'; + +var express = require('express'); +var https = require('https'); +var pem = require('pem'); + +pem.createCertificate({days: 1, selfSigned: true}, function(err, keys) { + var options = { + key: keys.serviceKey, + cert: keys.certificate + }; + + var app = express(); + + app.use(express.static('../')); + + // Create an HTTPS service. + https.createServer(options, app).listen(8080); + + console.log('serving on https://localhost:8080'); +});