16

I am working on media control functionality. I am displaying device name to select from a dropdown and it's working fine on chrome but on firefox it will not fetching label or device name.

J.Zong
  • 43
  • 7
Anuj Negi
  • 628
  • 1
  • 6
  • 27

4 Answers4

20

To complement the answers, on Firefox, the device labels obtained from navigator.mediaDevices.enumerateDevices() will also be set to the blank string in the case where there is no more active MediaStream, even though the application has been previously temporarily authorized to access the devices by calling navigator.mediaDevices.getUserMedia().

In the code below, the navigator.mediaDevices.enumerateDevices() will display the labels first (because the permission was granted from navigator.mediaDevices.getUserMedia()):

let stream = null

navigator.mediaDevices.getUserMedia({audio: true, video: false})
.then(s => {
  stream = s
  navigator.mediaDevices.enumerateDevices().then(devices => {
    devices.forEach(device => {
      console.log('device.label :', device.label)
    })
  })
})
.catch(error => {
  console.log('Error :', error)
})

But if you clear the tracks of the created MediaStream, calling navigator.mediaDevices.enumerateDevices() again will result in labels being empty:

stream.getTracks().forEach(track => {
  track.stop()
})

// No more active MediaStream => empty labels
navigator.mediaDevices.enumerateDevices().then(devices => { 
  devices.forEach(device => {
    console.log('device.label :', device.label)
  })
})

And you actually have to call navigator.mediaDevices.getUserMedia() again for a temporary permission to access the devices:

navigator.mediaDevices.getUserMedia({audio: true, video: false})
.then(s => {
  navigator.mediaDevices.enumerateDevices().then(devices => {
    devices.forEach(device => {
      console.log('device.label :', device.label)
    })
  })
})
.catch(error => {
    console.log('Error :', error)
})

Example here: https://codesandbox.io/s/pensive-hawking-hswzi

Reference: https://developer.mozilla.org/en-US/docs/Web/API/MediaDeviceInfo/label

Dharman
  • 30,962
  • 25
  • 85
  • 135
Philippe Sultan
  • 2,111
  • 17
  • 23
  • 3
    This should be the accepted answer. Stopping the acquired stream before enumerating the devices leads to empty labels (on Firefox). Thanks for your detailed answer. – Marco Sacchi Oct 21 '21 at 15:42
  • 1
    This is a complete answer. Thanks. – Priyanjit Apr 11 '22 at 07:17
  • 1
    Great answer, thankyou. I've extended the example to to show the third block (enumerating with getUserMedia) as solving the blank lablel: https://codesandbox.io/s/ecstatic-microservice-rzy2tm?file=/src/index.js – Stafford Williams Aug 11 '22 at 02:38
15

navigator.mediaDevices.enumerateDevices() will return an empty label attribute value in the media device info if the respective permissions are not granted.

To make it work, I placed this function after all of the media permissions have been granted so it returns a label attribute value as well.

Manik
  • 1,495
  • 11
  • 19
Anuj Negi
  • 628
  • 1
  • 6
  • 27
  • It's Working fine for me. – Softobiz T Oct 10 '17 at 06:22
  • 1
    It will get device label only if permissions are allowed. – Anuj Negi Oct 11 '17 at 08:32
  • 2
    As an addendum to this, if you use [this code sample](https://developers.google.com/web/updates/2015/10/media-devices#enumeratedevices) to prefill a user's audio and video device list, you can add a refresh button next to the list, which will request the appropriate mic and camera permissions and then allow you to refill the device list with their proper labels if granted. `function refreshDeviceList() { navigator.mediaDevices.getUserMedia({ audio: true, video: true }).then(stream => { stream.getTracks().forEach(t=>t.stop()); fillDeviceList() }) }` (don't forget to handle any errors) – samthecodingman Apr 27 '20 at 07:26
2

navigator.mediaDevices.enumerateDevices() returns a promise that's fulfilled with an array of MediaDeviceInfo instances.

It worked for me in Firefox 56.0 (64-bit).

You can do something like this:

navigator.mediaDevices.enumerateDevices()
.then((data) => {
  console.log('data', data);
})
.catch((err) => {
  console.log('error getting MediaDeviceInfo list', err);
});

where data is the array that contains the list of all MediaDeviceInfo instances.

more info here: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices

Manik
  • 1,495
  • 11
  • 19
0

You need to grant the permissions first. try this code

if (navigator.mediaDevices.getUserMedia) {
            console.log('getUserMedia supported.');

            const constraints = {audio: true};
            let chunks = [];

            let onSuccess = function (stream) {

                if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {
                    console.log("enumerateDevices() not supported.");
                    return false;
                }

                //List microphones.
                navigator.mediaDevices.enumerateDevices().then(function (devices) {
                    devices.forEach(function (device) {

                        if (device.kind === "audioinput") {
                            console.log(device.label);//Other parameters device.kind/device.deviceId
                        }

                    });
                }).catch(function (err) {
                    console.log(err.name + ": " + err.message);
                });

            }

            let onError = function (err) {
                console.log('The following error occured: ' + err);
            }

            navigator.mediaDevices.getUserMedia(constraints).then(onSuccess, onError);

        } else {
            console.log('getUserMedia not supported on your browser!');
        }
Optimaz Prime
  • 857
  • 10
  • 11