feat: Add TURN server support
All checks were successful
Queue Release Build / prepare (push) Successful in 15s
Deploy Web Apps / deploy (push) Successful in 5m35s
Queue Release Build / build-linux (push) Successful in 24m45s
Queue Release Build / build-windows (push) Successful in 13m52s
Queue Release Build / finalize (push) Successful in 23s
All checks were successful
Queue Release Build / prepare (push) Successful in 15s
Deploy Web Apps / deploy (push) Successful in 5m35s
Queue Release Build / build-linux (push) Successful in 24m45s
Queue Release Build / build-windows (push) Successful in 13m52s
Queue Release Build / finalize (push) Successful in 23s
This commit is contained in:
@@ -10,6 +10,7 @@ import { LatencyProfile } from '../realtime.constants';
|
||||
import { PeerData } from '../realtime.types';
|
||||
import { WebRTCLogger } from '../logging/webrtc-logger';
|
||||
import { NoiseReductionManager } from './noise-reduction.manager';
|
||||
import { loadVoiceSettingsFromStorage } from '../../../domains/voice-session/infrastructure/util/voice-settings-storage.util';
|
||||
import {
|
||||
TRACK_KIND_AUDIO,
|
||||
TRACK_KIND_VIDEO,
|
||||
@@ -105,6 +106,12 @@ export class MediaManager {
|
||||
private callbacks: MediaManagerCallbacks
|
||||
) {
|
||||
this.noiseReduction = new NoiseReductionManager(logger);
|
||||
|
||||
// Read the persisted noise-reduction preference so enableVoice()
|
||||
// uses the correct value even before voice-controls loads.
|
||||
try {
|
||||
this._noiseReductionDesired = loadVoiceSettingsFromStorage().noiseReduction;
|
||||
} catch { /* keep default */ }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -226,7 +233,7 @@ export class MediaManager {
|
||||
: stream;
|
||||
|
||||
// Apply input gain (mic volume) before sending to peers
|
||||
this.applyInputGainToCurrentStream();
|
||||
await this.applyInputGainToCurrentStream();
|
||||
|
||||
this.logger.logStream('localVoice', this.localMediaStream);
|
||||
|
||||
@@ -296,7 +303,7 @@ export class MediaManager {
|
||||
}
|
||||
|
||||
// Apply input gain (mic volume) before sending to peers
|
||||
this.applyInputGainToCurrentStream();
|
||||
await this.applyInputGainToCurrentStream();
|
||||
|
||||
this.bindLocalTracksToAllPeers();
|
||||
this.isVoiceActive = true;
|
||||
@@ -447,7 +454,7 @@ export class MediaManager {
|
||||
}
|
||||
|
||||
// Re-apply input gain to the (possibly new) stream
|
||||
this.applyInputGainToCurrentStream();
|
||||
await this.applyInputGainToCurrentStream();
|
||||
|
||||
// Propagate the new audio track to every peer connection
|
||||
this.bindLocalTracksToAllPeers();
|
||||
@@ -479,8 +486,7 @@ export class MediaManager {
|
||||
}
|
||||
|
||||
if (this.localMediaStream) {
|
||||
this.applyInputGainToCurrentStream();
|
||||
this.bindLocalTracksToAllPeers();
|
||||
void this.applyInputGainToCurrentStream().then(() => this.bindLocalTracksToAllPeers());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -840,12 +846,22 @@ export class MediaManager {
|
||||
* If a gain pipeline already exists for the same source stream the gain
|
||||
* value is simply updated. Otherwise a new pipeline is created.
|
||||
*/
|
||||
private applyInputGainToCurrentStream(): void {
|
||||
private async applyInputGainToCurrentStream(): Promise<void> {
|
||||
const stream = this.localMediaStream;
|
||||
|
||||
if (!stream)
|
||||
return;
|
||||
|
||||
// When gain is unity (1.0) skip the Web Audio pipeline entirely and
|
||||
// use the raw microphone stream. This avoids unnecessary AudioContext
|
||||
// overhead when no volume adjustment is needed.
|
||||
if (this.inputGainVolume === 1.0) {
|
||||
this.teardownInputGain();
|
||||
this.preGainStream = stream;
|
||||
this.applyCurrentMuteState();
|
||||
return;
|
||||
}
|
||||
|
||||
// If the source stream hasn't changed, just update gain
|
||||
if (this.preGainStream === stream && this.inputGainNode && this.inputGainCtx) {
|
||||
this.inputGainNode.gain.value = this.inputGainVolume;
|
||||
@@ -855,9 +871,15 @@ export class MediaManager {
|
||||
// Tear down the old pipeline (if any)
|
||||
this.teardownInputGain();
|
||||
|
||||
// Build new pipeline: source → gain → destination
|
||||
// Build new pipeline: source -> gain -> destination
|
||||
this.preGainStream = stream;
|
||||
this.inputGainCtx = new AudioContext();
|
||||
|
||||
// Ensure the AudioContext is running before connecting nodes.
|
||||
if (this.inputGainCtx.state !== 'running') {
|
||||
await this.inputGainCtx.resume();
|
||||
}
|
||||
|
||||
this.inputGainSourceNode = this.inputGainCtx.createMediaStreamSource(stream);
|
||||
this.inputGainNode = this.inputGainCtx.createGain();
|
||||
this.inputGainNode.gain.value = this.inputGainVolume;
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
* a clean output stream that can be sent to peers instead.
|
||||
*
|
||||
* Architecture:
|
||||
* raw mic → AudioContext.createMediaStreamSource
|
||||
* → NoiseSuppressorWorklet (AudioWorkletNode)
|
||||
* → MediaStreamDestination → clean MediaStream
|
||||
* raw mic -> AudioContext.createMediaStreamSource
|
||||
* -> NoiseSuppressorWorklet (AudioWorkletNode)
|
||||
* -> MediaStreamDestination -> clean MediaStream
|
||||
*
|
||||
* The manager is intentionally stateless w.r.t. Angular signals;
|
||||
* the owning MediaManager / WebRTCService drives signals.
|
||||
@@ -138,7 +138,7 @@ export class NoiseReductionManager {
|
||||
|
||||
/**
|
||||
* Build the AudioWorklet processing graph:
|
||||
* rawStream → source → workletNode → destination
|
||||
* rawStream -> source -> workletNode -> destination
|
||||
*/
|
||||
private async buildProcessingGraph(rawStream: MediaStream): Promise<void> {
|
||||
// Reuse or create the AudioContext (must be 48 kHz for RNNoise)
|
||||
|
||||
Reference in New Issue
Block a user