Search code examples
javascriptpromisemicrophonegetusermedia

getUserMedia - what if user makes no choice?


I've adapted a library to record MP3 audio via the user's microphone. If the user allows or rejects the microphone access request, I'm fine, but I note that MDN says this:

Note that it is possible for the returned promise to neither resolve nor reject, as the user is not required to make a choice.

But it doesn't seem to say what, if anything, I can do catch that "no choice made" action. If the user merely quits the dialog, or blurs out of it without making a choice, can I catch that and adjust my UI accordingly?

Here's my current code:

navigator.mediaDevices.getUserMedia({audio: true}).then(function(stream) {
    build_ui();
    startUserMedia(stream);
}).catch(function(e) { //<-- doesn't fire if no choice made
    cfg.no_device_callback && cfg.no_device_callback(e);
});

Solution

  • You could implement a timeout on the promise you have.

    For instance, you could extend the Promise object and prototype as follows:

    Promise.wait = function (ms) {
        return new Promise(function (resolve) {
            setTimeout(resolve, ms);
        });
    };
    
    Promise.prototype.timeout = function(ms) {
        return Promise.race([
            this, 
            Promise.wait(ms).then(function () {
                throw new Error("time out");
            })
        ])
    };
    

    Once you have that, you can just chain in a .timeout(10000):

    navigator.mediaDevices.getUserMedia({audio: true})
             .timeout(10000).then(function(stream) {
    //       ^^^^^^^^^^^^^^^
        build_ui();
        startUserMedia(stream);
    }).catch(function(e) { //<-- now also fires if no choice made within 10 secs
        cfg.no_device_callback && cfg.no_device_callback(e);
    });