Force renegotiation when attaching to null audio sender
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// Maintainer-controlled web client version.
|
||||
// Format: YYYY.MM.DD Rn (example: 2026.02.20 R2)
|
||||
window.CHGRID_WEB_VERSION = "2026.02.25 R265";
|
||||
window.CHGRID_WEB_VERSION = "2026.02.25 R266";
|
||||
// Optional display timezone for timestamps. Falls back to America/Detroit if unset/invalid.
|
||||
window.CHGRID_TIME_ZONE = "America/Detroit";
|
||||
|
||||
@@ -4,6 +4,7 @@ import type { RemoteUser } from '../network/protocol';
|
||||
export type PeerRuntime = SpatialPeerRuntime & {
|
||||
id: string;
|
||||
pc: RTCPeerConnection;
|
||||
initiator: boolean;
|
||||
remoteStream?: MediaStream;
|
||||
};
|
||||
|
||||
@@ -38,6 +39,7 @@ export class PeerManager {
|
||||
|
||||
const peer: PeerRuntime = {
|
||||
id: targetId,
|
||||
initiator: isInitiator,
|
||||
nickname: userData.nickname ?? 'user...',
|
||||
x: userData.x ?? 20,
|
||||
y: userData.y ?? 20,
|
||||
@@ -117,16 +119,47 @@ export class PeerManager {
|
||||
if (!newTrack) {
|
||||
return;
|
||||
}
|
||||
const peersToRenegotiate: PeerRuntime[] = [];
|
||||
for (const peer of this.peers.values()) {
|
||||
let shouldRenegotiate = false;
|
||||
const sender =
|
||||
peer.pc.getSenders().find((candidate) => candidate.track?.kind === 'audio') ??
|
||||
peer.pc
|
||||
.getTransceivers()
|
||||
.find((transceiver) => transceiver.receiver.track?.kind === 'audio' || transceiver.sender.track?.kind === 'audio')
|
||||
?.sender;
|
||||
if (!sender) continue;
|
||||
if (!sender) {
|
||||
peer.pc.addTrack(newTrack, stream);
|
||||
shouldRenegotiate = true;
|
||||
} else {
|
||||
if (!sender.track) {
|
||||
shouldRenegotiate = true;
|
||||
}
|
||||
await sender.replaceTrack(newTrack);
|
||||
}
|
||||
const audioTransceiver = peer.pc
|
||||
.getTransceivers()
|
||||
.find((transceiver) => transceiver.receiver.track?.kind === 'audio' || transceiver.sender.track?.kind === 'audio');
|
||||
if (audioTransceiver && (audioTransceiver.direction === 'recvonly' || audioTransceiver.direction === 'inactive')) {
|
||||
audioTransceiver.direction = 'sendrecv';
|
||||
shouldRenegotiate = true;
|
||||
}
|
||||
if (shouldRenegotiate && peer.initiator) {
|
||||
peersToRenegotiate.push(peer);
|
||||
}
|
||||
}
|
||||
for (const peer of peersToRenegotiate) {
|
||||
if (peer.pc.connectionState === 'closed') continue;
|
||||
if (peer.pc.signalingState !== 'stable') continue;
|
||||
try {
|
||||
let offer = await peer.pc.createOffer();
|
||||
offer = this.tuneOpus(offer);
|
||||
await peer.pc.setLocalDescription(offer);
|
||||
this.sendSignal(peer.id, { sdp: peer.pc.localDescription ?? undefined });
|
||||
} catch {
|
||||
// Best-effort renegotiation; transport-level failures recover on subsequent signaling.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
removePeer(id: string): void {
|
||||
|
||||
Reference in New Issue
Block a user