Work with getUserMedia across browsers

The web has seen a great technology added to it which provides access to the user's microphone and webcam. The specification for these tools is still evolving over time.

Closest to the spec most modern browsers deliver access to getUserMedia through javascript Promises so I've tried to build a simple function which unifies the different browsers so that they behave the same.

javascript
function requestUserMedia (constraints)
{

    if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia)
        return navigator.mediaDevices.getUserMedia(constraints);

    return new Promise(function (resolve, reject) {

        var getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
        if (getUserMedia)
            getUserMedia.call(navigator, constraints, resolve, reject);
        else {
            var err = new Error("Browser doesn't support getUserMedia.");
            err.name = "NOT_SUPPORTED";
            reject(err);
        }

    });

}

// USAGE
requestUserMedia({ audio: true })
    .then(function (stream) {})
    .catch(function (err) {});

In every case calling requestUserMedia will return a promise, which resolves a MediaStream. Promises are supported in every browser in which getUserMedia is supported, there is no danger in using them.

A Promise stub or a polyfill perhaps would be necessary for older browsers so that the appropriate error can be returned. But that is outside the scope of this article.

Another notable way in which getUserMedia differs between browsers is when you want to stop the stream. Some browsers return a list and others want you to stop directly. The following snippet will normalise behaviour.

javascript
if (stream.getTracks)
    stream.getTracks().forEach(function (track) { track.stop(); });
else
    stream.stop();

This should be all you need getting started using getUserMedia.