E T
E T

Reputation: 391

How to detect if microphone permissions have been granted in chrome

I would liked to detect whether or not microphone permissions have been granted on my site when it loads without actually running something like the following:

navigator.webkitGetUserMedia({audio: active}, 
    function(){alert('worked')}, 
    function(){alert('failed')});

Is there a simple API to detect whether the user has permanently granted microphone access to my application (which runs over https)?

Upvotes: 27

Views: 33562

Answers (4)

Mostafa Mohammadzadeh
Mostafa Mohammadzadeh

Reputation: 911

I guess this would be helpful:

function isMicrophoneAllowed(){
    navigator.permissions.query({
        name: 'microphone'
    }).then(function(permissionStatus){
        return permissionStatus.state !== 'denied';
    });
}

Upvotes: 1

asiop
asiop

Reputation: 727

navigator.getUserMedia is now obsolete, replaced by MediaDevices.getUserMedia, which returns a promise. If the promise gets rejected you get an DOMException with indication of the problem. Insufficient permissions is one of the options there.

Details here: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia

Upvotes: 1

Endless
Endless

Reputation: 37935

Update

microphone has been added to the Permission API even if it's not yet available on Safari nor Internet Explorer.

You could hope that it would be accessible from the permission api, but it isn't :(

Perhaps in the feature this could work like the rest of this:

navigator.permissions.query(
    // { name: 'camera' }
    { name: 'microphone' }
    // { name: 'geolocation' }
    // { name: 'notifications' } 
    // { name: 'midi', sysex: false }
    // { name: 'midi', sysex: true }
    // { name: 'push', userVisibleOnly: true }
    // { name: 'push' } // without userVisibleOnly isn't supported in chrome M45, yet
).then(function(permissionStatus){

    console.log(permissionStatus.state); // granted, denied, prompt

    permissionStatus.onchange = function(){
        console.log("Permission changed to " + this.state);
    }

})

Old answer

The only way i see it possible is if you keep track of this yourself with a key/value item in localStorage when you ask for permission.

Unfortunately it doesn't notify you when it has been changed

// initialization
if( localStorage.getItem('voice_access') === null ){
    // just assume it is prompt
    localStorage.setItem('voice_access', 'prompt');
}

// Then somewhere
navigator.getUserMedia({ audio: true }, function (e) {
    // http://stackoverflow.com/q/15993581/1008999
    //
    // In chrome, If your app is running from SSL (https://),
    // this permission will be persistent.
    // That is, users won't have to grant/deny access every time.
    localStorage.setItem("voice_access", "granted");

}, function (err) {
    if (err.name === 'PermissionDismissedError') {
        localStorage.setItem('voice_access', 'prompt')
    }
    if (err.name === 'PermissionDeniedError') {
        localStorage.setItem('voice_access', 'denied')
    }
})

You could go the extra mile and build a nice little wrapper with this code above and extend/replace the permission api to handle more enum names and create a broadcast api to tell the other tabs when it changes. but why make it so complicated...? The localStorage can't be 100% trusted. it can be changed anywhere any time both with permission and storage cleared

Upvotes: 37

Zezura
Zezura

Reputation: 126

you already got the polling method for checking permissions. here is some information from MDN: https://developer.mozilla.org/en-US/docs/Web/API/Navigator.getUserMedia

and some more: https://developer.mozilla.org/en-US/docs/WebRTC

here is an example:

navigator.getMedia (
// constraints
   {
      video: true,
      audio: true
   },

   // successCallback
   function(localMediaStream) {
      var video = document.querySelector('video');
      video.src = window.URL.createObjectURL(localMediaStream);
      video.onloadedmetadata = function(e) {
         // Do something with the video here.
      };
   },

   // errorCallback
   function(err) {
    console.log("The following error occured: " + err);
   }

);

Upvotes: 1

Related Questions