Outgoing voice was gated on the observer's roster copy of the remote user's voice state, which is signaling gossip. The signal server broadcasts `user_left` for any socket it declares dead, so a suspended laptop or a flaky hop wiped that copy and the observer detached its microphone from a peer that never left the channel - a silent member with no way back through the UI. `decideVoicePathRouting` now closes a path only on positive evidence: we left voice, the peer itself reported another channel or none, or the connection is gone. Missing gossip holds an established path instead. Opening still needs confirmation, so a guess never starts sending; the same rule gates playback, camera video, and the microphone a new connection puts in its first offer. Peers are also asked for their voice state when a connection or data channel comes up, so a rebuilt path re-confirms itself. Alongside it, the microphone can be switched mid-call: capture moves to a device service and rules, the live track is swapped with `replaceTrack` so the session is never renegotiated, and the speaking indicator follows the new stream.
15 lines
846 B
TypeScript
15 lines
846 B
TypeScript
export * from './application/facades/voice-session.facade';
|
|
export * from './application/services/voice-audio-device.service';
|
|
export * from './application/services/voice-client-takeover.service';
|
|
export * from './application/services/voice-workspace.service';
|
|
export * from './domain/logic/audio-device-selection.rules';
|
|
export * from './domain/logic/client-voice-session.rules';
|
|
export * from './domain/logic/stream-indicator.rules';
|
|
export * from './domain/logic/voice-path-routing.rules';
|
|
export * from './domain/models/voice-session.model';
|
|
export * from './infrastructure/util/voice-settings-storage.util';
|
|
|
|
// Feature components
|
|
export { VoiceControlsComponent } from './feature/voice-controls/voice-controls.component';
|
|
export { FloatingVoiceControlsComponent } from './feature/floating-voice-controls/floating-voice-controls.component';
|