Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect UserMedia Permission Before Requesting It

I'd like to explain to users why the camera/microphone is needed before asking them, so that they can make a better choice if they want to grant it or not.

In order to implement that I need a way to detect if the permission has previously been granted, so that I can explain the request to the user before actually asking them. I also don't want to ask everytime (even though I already have permissions!).

like image 245
Florian Wendelborn Avatar asked Dec 18 '16 01:12

Florian Wendelborn


2 Answers

navigator.mediaDevices.enumerateDevices().then(devices => 
  devices.forEach(device => console.log(device.label)))

When not yet permitted device.label == ""
When permitted device.label != ""

like image 105
Tanaka Kenji Avatar answered Oct 06 '22 14:10

Tanaka Kenji


Use a cookie or localStorage to remember that you've asked them before and gotten a yes.

Some browsers let users grant permission for each use of the camera or microphone so if your metric is you don't want to ask them every time, then don't tie your message to whether you've been granted permanent access.

The navigator.mediaDevices.enumerateDevices trick mentioned in another answer presently detects persistent permission to camera and/or microphone fairly well - but you don't know which one or whether you've been granted both.

Also, this may break over time, as the spec was updated recently to untie the access to labels from the persistent access of camera and/or microphone, in part to support single-use permission use-cases better. Once browsers update to the spec, it would no longer imply persistent camera and/or microphone permission in those situations.

The long-term answer to whether permission has been persisted is to use query, but as you can see from running this, browsers don't support it yet for "camera" and "microphone" (or in some cases at all):

navigator.permissions.query({name: "camera"})
.then(({state}) => console.log(state),
      e => console.log(e.name +": "+ e.message));
like image 31
jib Avatar answered Oct 06 '22 15:10

jib