Is it possible to apply constraints to a running live audio track? It doesn't seem to work for me, at least on Chrome v80.
Suppose I have a stream:
const stream = await navigator.mediaDevices.getUserMedia({
audio: {
autoGainControl: true
channelCount: 2
echoCancellation: true
noiseSuppression: true
},
video: false
});
Now, later on I want to change some of those parameters:
for (const track of stream.getAudioTracks()) {
track.applyConstraints({
autoGainControl: false,
echoCancellation: false,
noiseSuppression: false
});
}
This has no effect. If I call track.getConstraints()
, I see my new constraints but audibly they have no effect until I reload the page and apply them from the beginning. Additionally, when I call track.getSettings()
, I see that my new constraints haven't been applied.
I have also tried calling track.enabled = false
before applying the constraints, with track.enabled = true
afterwards, with no luck.
Any advice on how to get this to work without making a fresh call to getUserMedia()
?
SO user jib, which works on Firefox and adapter.js projects wrote a blog post in 2017 about this exact feature.
Here is how they did apply the constraints to the track:
async function apply(c) {
await track.applyConstraints(Object.assign(track.getSettings(), c));
update();
}
c
is an object with the particular constraints to add.
They do it this way because all the properties that are omitted when passing the MediaTrackConstraints dictionary will get reset to their defaults when applied.
Now, your solution should have worked too for the properties you did set.
So using this fiddle I did try the few UAs I have on my macOS machine:
As you reported, settings are not applied.
Here is the issue tracking the upcoming implementation.
From this issue's comments you can also find a workaround which implies requesting a new MediaStream from the same deviceId
as the one you got, and applying the desired constraints.
Here is a fork of jib's fiddle with such a workaround. Note that the deviceId
is gotten from track.getSettings()
async function apply(c) {
track.stop(); // required
const new_constraints = Object.assign(track.getSettings(), c, );
const new_stream = await gUM({ audio: new_constraints });
updateSpectrum( audio.srcObject = new_stream );
track = new_stream.getAudioTracks()[0];
update();
}
Works seamlessly.
Badly crashes. On my machine, running the original fiddle, with only the tweak of the spectrum will completely crash the gUM of the whole browser. - The current stream is stopped - Any attempt to get a new stream fails - until reboot of the whole app.
The forked fiddle we made for Chrome at least doesn't crash, but it doesn't seem to produce any audible change either...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With