video streaming component

I’m new to Dash (apologies upfront.)

I’ve written a video streamer for a Raspberry Pi camera using Flask and socket.io. The frames are grabbed from the camera, compressed and streamed across a socket.io channel and then uncompressed and rendered into an html5 canvas on the client end. I’m using Jsmpeg, which works very well — fast, low-latency and efficient. Here’s what it looks like normally without Dash:

	<canvas id="video-canvas", width=640, height=480></canvas>

	var canvas = document.getElementById('video-canvas');
	var socket = io.connect(); // initialize socket.io
	VideoStreamer.init(canvas,  socket);  // pass in canvas and socket object

	socket.on('connect', function() {
		console.log('connect');
		VideoStreamer.start();
		console.log('started');
	});
	socket.on('disconnect', function() {
		console.log('disconnect');
		VideoStreamer.stop();
	});

It just creates a canvas object and passes it into the streamer object. Socket.io takes care of the rest in the background— the frames just show up in the canvas.

I want to create interactive and live computer vision applications using Dash and the Raspberry Pi, and I’ve done so, in a hacked way using DangerouslySetInnerHTML to insert the canvas and append_script to add the code to initialize the VideoStreamer object. There was a chicken-egg problem where the initializer couldn’t grab the canvas because it hadn’t been created yet. This was fixed with a, uh, timeout… anyway, it works fine despite being a mess and shows my colleagues that Dash could do everything that we want (and more!)

I’ve created a skeleton Dash component using cookiecutter and I can see what needs to be done for the most part, but…

I’m still going to have a chicken-egg problem with the VideoStreamer object and the canvas. On the server side there is some similarly simple code that needs to instantiate a python object and accept frames.

This component is a different kind of component from what I can see, and I could use some advice. Are there similar components out there I could use for reference? It would be cool (eventually) to have the ability to scale the component, select regions, save as image… but these are down the road. For now, I just want to get a non-messy component working.

thanks!

Keep a ref on the canvas in your component. In componentDidMount you can be sure the canvas will exist in the DOM and initialize the socket/VideoStreamer there. For the socket part, you can take the url to the socket as prop. If you want to also provide code for the backend, like a socket route handler you can add to dash, you can have a different package in your project and include that in setup.py.

Thanks Philippe! I’ll give these suggestions a go and see where I get. You made it sound pretty straightforward, which is encouraging :slight_smile:

1 Like