fix: re-acquire mic track when effects require specific audio constraints#99
fix: re-acquire mic track when effects require specific audio constraints#99antsukanova wants to merge 4 commits intomainfrom
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e903658ce5
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 54f77fd9d6
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0769169e4f
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| newTrack.enabled = wasEnabled; | ||
| this.inputStream.removeTrack(oldTrack); | ||
| this.inputStream.addTrack(newTrack); | ||
| this.addTrackHandlers(newTrack); |
There was a problem hiding this comment.
Ignore stale re-acquire results before swapping tracks
handleConstraintsRequired is async and can be invoked again before a previous getUserMedia call finishes, but this block always applies whichever request resolves last without checking whether a newer constraints event already superseded it. In practice, quick enable/disable or model-switch emissions can leave the stream on outdated constraints because an older in-flight request still replaces inputTrack and re-wires effects after a newer request was processed. Add request sequencing (or a mutex) and discard late completions before mutating stream/effect state.
Useful? React with 👍 / 👎.
bbaldino
left a comment
There was a problem hiding this comment.
Couple comments. Some impressive catches by codex as well 👀
| * emits empty constraints (disable / dispose / model switch to one with no | ||
| * special requirements). | ||
| */ | ||
| let savedConstraints: Record<string, MediaTrackConstraints[keyof MediaTrackConstraints]> = {}; |
There was a problem hiding this comment.
Do we have the possibility of multiple "layers" of saving constraints? Or currently can there only ever be one? I.e.: we have some constraints, a single thing can change them, and then the only other possible transition would be going back to those original constraints?
| * Empty constraints ({}): restore the previously saved values so the track | ||
| * returns to the user's original settings. |
There was a problem hiding this comment.
Out of curiosity: did you consider emitting different events for when new constraints are required and when they're no longer required (as opposed to overloading the value of the constraints parameter here)? It seems like it would simplify the logic below a decent amount.
Summary
Adds a
handleConstraintsRequiredhandler inLocalStream.addEffect()that listens forConstraintsRequiredevents from effects (e.g.web-media-effectsnoise reduction). When an effect needs specific audio processing properties on the microphone track, the handler re-acquires the track viagetUserMedia()sinceapplyConstraints()is silently ignored by Chrome for audio constraints. Original track settings are saved and restored when the effect emits empty constraints on disable/dispose.What's changed
constraints-requiredevents on effects. Non-empty constraints triggergetUserMediawith the requested values merged over current settings. Empty constraints ({}) restore the saved originals.oldTrack.stop()to prevent spuriousendedevents. The old track is stopped beforegetUserMediato force Chrome to create a fresh audio pipeline (required for independent AEC/AGC/NS control).getUserMediais called with{ ...oldSettings, ...constraintsToApply, deviceId: { exact } }to preserve the current device and non-affected settings while applying the requested constraints.constraints-requiredlistener is unregistered when the effect is disposed.Testing
autoGainControl: false,noiseSuppression: false,echoCancellation: truein logs after re-acquisition