1

I am trying to implement a microphone switch feature where, whilst being on a live call on the browser, i am able to replace my current in-use microphone with a new one.

After selecting the new microphone I want to change to, I receive a NotReadableError: Concurrent mic process limit. error message. This error message is only replicable on firefox, on chromium browsers no error is shown however the issue of not being able to switch to another microphones persists anyway.

This is because the previous device isnt being deactivated/destroyed before adding the new device, this is visible from the permission icons here:

enter image description here

The old microphone is still active and thus when permitting the new device i receive the concurrent mic process limit error.

I am using replaceTrack() to swap to the new selected device, and the below function runs when selecting a new microphone to activate to.

async onMicrophoneSelected(event: any) {

// selectedDeviceId holds the deviceId of the microphone i want to switch to

        const selectedDeviceId = event?.value;

        var newAudioTrack;
        var constraints;
        var mediaStream: MediaStream;
        var audioTrack: MediaStreamTrack;

// Looping through all available devices here 

        await navigator.mediaDevices.enumerateDevices().then((res) => {
            res.forEach((device) => {

                // Here checking if the available device is an audioinput and if its id matches the one which we want to swap to.

                if (device.kind === 'audioinput' && device.deviceId === selectedDeviceId) {
                    newAudioTrack = device;

                    // constraints specified here with new deviceId of microphone

                    constraints = {
                        video: { facingMode: 'user' },
                        audio: { deviceId: { exact: newAudioTrack['deviceId'] } },
                    };

                }
            });
        });     

        // Passing constraints into mediaStream

        mediaStream = await navigator.mediaDevices.getUserMedia(constraints);
        audioTrack = mediaStream.getVideoTracks()[0];

        // Custom replaceTrack() function here 

        this.localUsersService
            .getWebcamPublisher()
            .replaceTrack(audioTrack)
            .then(() => {
                this.publishAudio(true);
                this.hasAudioDevices = true;
            });
    }

How can I completely deactivate the previous microphone / camera before switching to the new set of microphone and camera permissions ?

richardrobu
  • 143
  • 15

1 Answers1

2

As you already mentioned this is a limitation in Firefox which is currently being worked on.

https://bugzilla.mozilla.org/show_bug.cgi?id=1238038

You can stop the current stream before asking for another one by calling stop on all of its tracks.

mediaStream.getTracks().forEach((track) => track.stop());
chrisguttandin
  • 7,025
  • 15
  • 21
  • track.stop() as i mentioned in my answer below, is very unstable and literally just doesnt work everytime. I experimented with making some sort of a `track.stop()` checker using the `onended()` event, but this hasnt worked so far for me, it also wont work outside of ngOninit() at all for some reason. So my code in the below answer is in ngOninit() of some component when it should be in the `onMicrophoneSelected()` function that I mentioned in the question – richardrobu Nov 11 '21 at 21:47
  • Sorry, I can't say why calling `stop()` doesn't work for you in any case. I'm not aware of any bugs. But that does of course not mean that there aren't any. – chrisguttandin Nov 11 '21 at 22:06