2 min read

Recently I have been working for a project called pagenodes with my internship company, IcedDev. We basically forked IBM's node-red and implanted it into a single page app. We have been working on the project for about two months, and we have put in several fine additions, such as arduino control via johnny-five. We also have base nodes for things such as input, p2p messaging, http requests, and camera.

When we first implemented camera's node it was a simple, you basically used the time old tradition of invoking the getUserMedia library and then opening up a generic video device. This will work just fine on an https, or localhost.

One thing that we've run into recently was that the feature for camera stopped working, and we couldn't figure out why. Typically when making any kind of image request the answer has always been to make the best possible coverage for different browser api's with something like:

navigator.getUserMedia = navigator.getUserMedia ||
                         navigator.webkitGetUserMedia ||
                         navigator.mozGetUserMedia;

-MDN

What we found is about a month ago during a refactor that camera was spitting errors. Interestingly enough it was only happening with Chrome(that's pretty rare).

So what happens when this breaks, or if they make a major change to the API? Well the answer is simply to start cruising MDN until you find out what the issue is. In our case the camera would turn on; however, it wasn't killing off. This makes sense in the case of our code because one of those 3 apis is going to fire on our browser. The problem probably wasn't going to be the API firing.

So, we set breakpoints, and dug into the API and found the permissions needed. What we found is that recently there had been a deprecation of navigator.getUserMedia in favor of navigator.MediaDevices. This in turn resolves to the MediaStream API. Following the api guide we were running into the issue of the camera starting, but never stopping. In previous versions it was simple enough to simply append streamname.stop(). With the API changes they had introduced a more verbose method by returning a MediaStream promise.

In order to stop the video stream, it would be necessary to call MediaStream.getTracks(), find our track, and then kill it with MediaStream.removeTrack().

The result was a pretty rudimentary and crude:

mediaStream.getTracks().forEach(function(track){track.stop()});

Obviously if you need to specify which track you need to close then that is something that can be created out in userland; however, for our fix, this was enough to suffice as a fix.

!!

Sam Clark

Sam Clark

Read more posts by this author.