Webcams, Canvas’s and Observables with React
Webcams are a unique resource in the front end environment. In this short article I will show you how I was able to integrate a webcam and a canvas with observable architecture cleanly.
In the modern version of web development things have rightly become more functional. However resources like webcams present a challenge because they are singular, and imply a very procedural approach to their use.
The snippet above has a ref that updates a videoElement variable once the component has mounted. This should trigger concern about having proper functional, event driven management of the resource which we will cover. A canvas element is also present. It acts as the place the video is actually shown. Having the canvas as the place for the video allows us to have more control over the video. We can control the frame-rate, capture images e.t.c.
Of course the webcam needs to be initiated and requires the user’s permission in order to work correctly. the
navigator.getUserMedia helps make this happen. The Promise wraps the
getUserMedia functionality in order to give us control over the asynchronous behaviour. Finally, the
from function allows us to treat the promise as an observable by converting it.
The true value of the above function is it encases the impure nature of the resources cleanly and in a single location. If all goes well a simple observable is exposed and the webcam is back in the universe of pure functions.
Now that we can safely create the webcam, get permission, and have the process encased in an observable, we need to be able to draw the images produced on the canvas. Since the
createWebcam function simply return an observable, we can use access the data processed through pipe-able operators.
What I like about the implementation is two fold. Even though the resources is question are passed by reference, they are computed very declaratively and functionally. Drawing on the canvas is predicated clearly on the video element being properly registered and this is visually clear even if you don’t know how observables work.
To make the moving pictures we draw each picture on the canvas at intervals. In this case we are drawing at 40 ms intervals. The timer observable works to control the emission’s of each image. At each emission we simply draw the image on the canvas using the
drawImageOnCanvas function used above and seen in detail below.
What is great about this is how nicely this can fit into your pre-existing front end architecture using
rxjs for asynchronous control and processing. Here is an example of it being used to take a picture of the webcam 5 times a second, within an Epic. Epics are containers for observables in the redux-observable library.
Once the start webcam action is processed, we initialize the webcam and simply use the normal observable behaviour to change the image data on the canvas to a jpeg. The image is then stored in the redux global state.
I hope this was as interesting for you to read as it was for me to discover.
Please take the time to like and share. People need to know …. you know?