This commit is contained in:
parent
9d7f658fc0
commit
39eb7c77ad
1 changed files with 32 additions and 2 deletions
|
|
@ -29,6 +29,7 @@ const state = {
|
||||||
viewMode: 'chat', // 'chat' or 'video'
|
viewMode: 'chat', // 'chat' or 'video'
|
||||||
iceServers: [{ urls: "stun:stun.l.google.com:19302" }],
|
iceServers: [{ urls: "stun:stun.l.google.com:19302" }],
|
||||||
peerGainNodes: new Map(), // userId -> GainNode
|
peerGainNodes: new Map(), // userId -> GainNode
|
||||||
|
peerAudioNodes: new Map(), // userId -> { sourceNode, compressorNode, gainNode }
|
||||||
visibleVolumeSliders: new Set(), // userIds whose sliders are visible
|
visibleVolumeSliders: new Set(), // userIds whose sliders are visible
|
||||||
},
|
},
|
||||||
voicePresencePollId: null,
|
voicePresencePollId: null,
|
||||||
|
|
@ -1039,7 +1040,24 @@ function shouldInitiateOffer(peerId) {
|
||||||
return state.me.id > peerId;
|
return state.me.id > peerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function disconnectPeerAudioNodes(peerId) {
|
||||||
|
const nodes = state.voice.peerAudioNodes.get(peerId);
|
||||||
|
if (!nodes) return;
|
||||||
|
|
||||||
|
for (const node of [nodes.sourceNode, nodes.compressorNode, nodes.gainNode]) {
|
||||||
|
try {
|
||||||
|
node?.disconnect();
|
||||||
|
} catch { }
|
||||||
|
}
|
||||||
|
|
||||||
|
state.voice.peerAudioNodes.delete(peerId);
|
||||||
|
state.voice.peerGainNodes.delete(peerId);
|
||||||
|
}
|
||||||
|
|
||||||
function stopAndClearAudioPipeline() {
|
function stopAndClearAudioPipeline() {
|
||||||
|
for (const peerId of state.voice.peerAudioNodes.keys()) {
|
||||||
|
disconnectPeerAudioNodes(peerId);
|
||||||
|
}
|
||||||
if (state.voice.deepFilterProcessor) {
|
if (state.voice.deepFilterProcessor) {
|
||||||
state.voice.deepFilterProcessor.destroy();
|
state.voice.deepFilterProcessor.destroy();
|
||||||
state.voice.deepFilterProcessor = null;
|
state.voice.deepFilterProcessor = null;
|
||||||
|
|
@ -1265,7 +1283,7 @@ async function createLocalVoiceStream() {
|
||||||
sampleRate: 48000,
|
sampleRate: 48000,
|
||||||
echoCancellation: true,
|
echoCancellation: true,
|
||||||
noiseSuppression: false,
|
noiseSuppression: false,
|
||||||
autoGainControl: false,
|
autoGainControl: true,
|
||||||
},
|
},
|
||||||
video: false,
|
video: false,
|
||||||
};
|
};
|
||||||
|
|
@ -1388,16 +1406,27 @@ function ensurePeerConnection(peerId) {
|
||||||
const ctx = state.voice.audioContext;
|
const ctx = state.voice.audioContext;
|
||||||
if (ctx.state === 'suspended') ctx.resume();
|
if (ctx.state === 'suspended') ctx.resume();
|
||||||
|
|
||||||
|
disconnectPeerAudioNodes(peerId);
|
||||||
|
|
||||||
const sourceNode = ctx.createMediaStreamSource(audio.srcObject);
|
const sourceNode = ctx.createMediaStreamSource(audio.srcObject);
|
||||||
|
const compressorNode = ctx.createDynamicsCompressor();
|
||||||
const gainNode = ctx.createGain();
|
const gainNode = ctx.createGain();
|
||||||
|
|
||||||
|
compressorNode.threshold.setValueAtTime(-24, ctx.currentTime);
|
||||||
|
compressorNode.knee.setValueAtTime(18, ctx.currentTime);
|
||||||
|
compressorNode.ratio.setValueAtTime(4, ctx.currentTime);
|
||||||
|
compressorNode.attack.setValueAtTime(0.003, ctx.currentTime);
|
||||||
|
compressorNode.release.setValueAtTime(0.25, ctx.currentTime);
|
||||||
|
|
||||||
const currentVolume = state.userVolumes.get(peerId) ?? 1.0;
|
const currentVolume = state.userVolumes.get(peerId) ?? 1.0;
|
||||||
gainNode.gain.setValueAtTime(currentVolume, ctx.currentTime);
|
gainNode.gain.setValueAtTime(currentVolume, ctx.currentTime);
|
||||||
|
|
||||||
sourceNode.connect(gainNode);
|
sourceNode.connect(compressorNode);
|
||||||
|
compressorNode.connect(gainNode);
|
||||||
gainNode.connect(ctx.destination);
|
gainNode.connect(ctx.destination);
|
||||||
|
|
||||||
state.voice.peerGainNodes.set(peerId, gainNode);
|
state.voice.peerGainNodes.set(peerId, gainNode);
|
||||||
|
state.voice.peerAudioNodes.set(peerId, { sourceNode, compressorNode, gainNode });
|
||||||
|
|
||||||
// Mute the original element as we play through Web Audio destination
|
// Mute the original element as we play through Web Audio destination
|
||||||
audio.volume = 0;
|
audio.volume = 0;
|
||||||
|
|
@ -1582,6 +1611,7 @@ async function joinVoice() {
|
||||||
pc.close();
|
pc.close();
|
||||||
state.voice.peerConnections.delete(msg.user_id);
|
state.voice.peerConnections.delete(msg.user_id);
|
||||||
}
|
}
|
||||||
|
disconnectPeerAudioNodes(msg.user_id);
|
||||||
document.getElementById(`audio-${msg.user_id}`)?.remove();
|
document.getElementById(`audio-${msg.user_id}`)?.remove();
|
||||||
} else if (msg.type === "signal") {
|
} else if (msg.type === "signal") {
|
||||||
await handleSignal(msg.from_user_id, msg.kind, msg.data);
|
await handleSignal(msg.from_user_id, msg.kind, msg.data);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue