Websocket Video Stream
Stream camera capture from the browser to Node-RED using websockets.
Requirements
[{"id":"310ea8f8.e72128","type":"tab","label":"websocket stream","disabled":false,"info":""},{"id":"4f45bd28.fe7ea4","type":"http in","z":"310ea8f8.e72128","name":"","url":"/cam","method":"get","upload":false,"swaggerDoc":"","x":220,"y":120,"wires":[["1db9868.3f9a7fa"]]},{"id":"fc8f27e5.3f4af","type":"http response","z":"310ea8f8.e72128","name":"","statusCode":"","headers":{},"x":630,"y":120,"wires":[]},{"id":"1db9868.3f9a7fa","type":"template","z":"310ea8f8.e72128","name":"","field":"payload","fieldType":"msg","format":"html","syntax":"plain","template":"<html>\n<head>\n <title>Streamer</title>\n</head>\n<body>\n <video autoplay></video>\n <script>\n // get video dom element\n const server = window.location.hostname;\n const video = document.querySelector('video');\n \n // request access to webcam\n navigator.mediaDevices.getUserMedia({video: {width: 360, height: 240}}).then((stream) => video.srcObject = stream);\n \n // returns a frame encoded in base64\n const getFrame = () => {\n const canvas = document.createElement('canvas');\n canvas.width = video.videoWidth;\n canvas.height = video.videoHeight;\n canvas.getContext('2d').drawImage(video, 0, 0);\n const data = canvas.toDataURL('image/png');\n return data;\n }\n\n const WS_URL = `ws://${server}:1880/ws/cam`;\n console.log(WS_URL);\n const FPS = 10;\n const ws = new WebSocket(WS_URL);\n ws.onopen = () => {\n console.log(`Connected to ${WS_URL}`);\n setInterval(() => {\n ws.send(getFrame());\n }, 1000 / FPS);\n }\n </script>\n</body>\n</html>","output":"str","x":420,"y":120,"wires":[["fc8f27e5.3f4af"]]},{"id":"15b57638.12e582","type":"websocket in","z":"310ea8f8.e72128","name":"","server":"524d85f.8ebbc7c","client":"","x":230,"y":220,"wires":[["41baab0f.c85904"]]},{"id":"29a75706.39bef8","type":"image","z":"310ea8f8.e72128","name":"","width":"360","data":"payload","dataType":"msg","thumbnail":false,"active":true,"pass":false,"outputs":0,"x":840,"y":220,"wires":[]},{"id":"e7cc856b.d2f17","type":"comment","z":"310ea8f8.e72128","name":"http://localhost:1880/cam","info":"Go to <http://localhost:1880/cam>","x":270,"y":60,"wires":[]},{"id":"41baab0f.c85904","type":"jimp-image","z":"310ea8f8.e72128","name":"","data":"payload","dataType":"msg","ret":"img","parameter1":"8","parameter1Type":"num","parameter2":"","parameter2Type":"msg","parameter3":"","parameter3Type":"msg","parameter4":"","parameter4Type":"msg","parameter5":"","parameter5Type":"msg","parameter6":"","parameter6Type":"msg","parameter7":"","parameter7Type":"msg","parameter8":"","parameter8Type":"msg","parameterCount":1,"jimpFunction":"posterize","selectedJimpFunction":{"name":"posterize","fn":"posterize","description":"apply a posterization effect with n level","parameters":[{"name":"n","type":"num","required":true,"hint":"the amount to adjust the contrast, minimum threshold is two"}]},"x":600,"y":220,"wires":[["29a75706.39bef8"]]},{"id":"524d85f.8ebbc7c","type":"websocket-listener","z":"","path":"/ws/cam","wholemsg":"false"}]