Skip to content

Commit

Permalink
fix: remove duplicate outputs
Browse files Browse the repository at this point in the history
  • Loading branch information
Saelmala committed Dec 9, 2024
1 parent db21327 commit 7804794
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 84 deletions.
12 changes: 6 additions & 6 deletions src/components/production-line/production-line.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -146,10 +146,6 @@ export const ProductionLine: FC = () => {
inputId: joinProductionOptions?.audioinput ?? null,
});

const { setVolume } = useControlVolume({
stream: inputAudioStream !== "no-device" ? inputAudioStream : null,
});

const muteInput = useCallback(
(mute: boolean) => {
if (inputAudioStream && inputAudioStream !== "no-device") {
Expand Down Expand Up @@ -192,16 +188,20 @@ export const ProductionLine: FC = () => {
sessionId,
});

const { setVolume } = useControlVolume({
audioElements,
});

useEffect(() => {
if (connectionState === "connected") {
playEnterSound();
}
}, [connectionState, playEnterSound]);

const muteOutput = useCallback(() => {
audioElements.forEach((singleElement: HTMLAudioElement) => {
audioElements.forEach(({ gainNode }) => {
// eslint-disable-next-line no-param-reassign
singleElement.muted = !isOutputMuted;
gainNode.gain.value = isOutputMuted ? 1 : 0;
});
setIsOutputMuted(!isOutputMuted);
}, [audioElements, isOutputMuted]);
Expand Down
50 changes: 11 additions & 39 deletions src/components/production-line/use-control-volume.tsx
Original file line number Diff line number Diff line change
@@ -1,54 +1,26 @@
import { useEffect, useRef, useState } from "react";
type TAudioElement = {
audioCtx: AudioContext;
gainNode: GainNode;
source: MediaStreamAudioSourceNode;
};

type TUseControlVolumeOptions = {
stream: MediaStream | null;
audioElements: TAudioElement[];
};

type TUseControlVolume = (options: TUseControlVolumeOptions) => {
setVolume: (value: number) => void;
audioContext: AudioContext | null;
};

export const useControlVolume: TUseControlVolume = ({ stream }) => {
const [audioContext, setAudioContext] = useState<AudioContext | null>(null);
const gainNodeRef = useRef<GainNode | null>(null);

useEffect(() => {
if (!stream) return;

console.log("Initializing Audio Context");

const audioCtx = new AudioContext();
setAudioContext(audioCtx);

const source = audioCtx.createMediaStreamSource(stream);

const gainNode = audioCtx.createGain();
gainNode.gain.value = 0.5;

source.connect(gainNode);
// Outputs the audio to the speakers
gainNode.connect(audioCtx.destination);

gainNodeRef.current = gainNode;

// eslint-disable-next-line consistent-return
return () => {
source.disconnect();
gainNode.disconnect();
audioCtx.close();
gainNodeRef.current = null;
};
}, [stream]);

export const useControlVolume: TUseControlVolume = ({ audioElements }) => {
const setVolume = (value: number) => {
if (gainNodeRef.current) {
audioElements.forEach(({ gainNode }) => {
const clampedValue = Math.max(0, Math.min(1, value));
gainNodeRef.current.gain.value = clampedValue;
gainNode.gain.setValueAtTime(clampedValue, gainNode.context.currentTime);

console.log("Setting Gain Node Volume:", clampedValue);
}
});
};

return { setVolume, audioContext };
return { setVolume };
};
111 changes: 72 additions & 39 deletions src/components/production-line/use-rtc-connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,15 @@ type TEstablishConnection = {
joinProductionOptions: TJoinProductionOptions;
sessionId: string;
dispatch: Dispatch<TGlobalStateAction>;
setAudioElements: Dispatch<SetStateAction<HTMLAudioElement[]>>;
setAudioElements: Dispatch<
SetStateAction<
{
audioCtx: AudioContext;
gainNode: GainNode;
source: MediaStreamAudioSourceNode;
}[]
>
>;
setNoStreamError: (input: boolean) => void;
};

Expand All @@ -49,7 +57,7 @@ const attachInputAudioToPeerConnection = ({
const establishConnection = ({
rtcPeerConnection,
sdpOffer,
joinProductionOptions,
// joinProductionOptions,
sessionId,
dispatch,
setAudioElements,
Expand All @@ -60,31 +68,45 @@ const establishConnection = ({
const selectedStream = streams[0];

if (selectedStream && selectedStream.getAudioTracks().length !== 0) {
const audioElement = new Audio();

audioElement.controls = false;
audioElement.autoplay = true;
audioElement.onerror = () => {
dispatch({
type: "ERROR",
payload: new Error(
`Audio Error: ${audioElement.error?.code} - ${audioElement.error?.message}`
),
});
};

audioElement.srcObject = selectedStream;

setAudioElements((prevArray) => [audioElement, ...prevArray]);
if (joinProductionOptions.audiooutput) {
audioElement.setSinkId(joinProductionOptions.audiooutput).catch((e) => {
dispatch({
type: "ERROR",
payload:
e instanceof Error ? e : new Error("Error assigning audio sink."),
});
});
}
const audioCtx = new AudioContext();
const gainNode = audioCtx.createGain();
const source = audioCtx.createMediaStreamSource(selectedStream);

source.connect(gainNode);
gainNode.connect(audioCtx.destination);

gainNode.gain.value = 0.5;

setAudioElements((prevArray) => [
{ audioCtx, gainNode, source },
...prevArray,
]);

// const audioElement = new Audio();

// audioElement.controls = false;
// audioElement.autoplay = true;
// audioElement.onerror = () => {
// dispatch({
// type: "ERROR",
// payload: new Error(
// `Audio Error: ${audioElement.error?.code} - ${audioElement.error?.message}`
// ),
// });
// };

// audioElement.srcObject = selectedStream;

// setAudioElements((prevArray) => [audioElement, ...prevArray]);
// if (joinProductionOptions.audiooutput) {
// audioElement.setSinkId(joinProductionOptions.audiooutput).catch((e) => {
// dispatch({
// type: "ERROR",
// payload:
// e instanceof Error ? e : new Error("Error assigning audio sink."),
// });
// });
// }
} else if (selectedStream && selectedStream.getAudioTracks().length === 0) {
setNoStreamError(true);
dispatch({
Expand Down Expand Up @@ -232,15 +254,24 @@ export const useRtcConnection = ({
const [, dispatch] = useGlobalState();
const [connectionState, setConnectionState] =
useState<RTCPeerConnectionState | null>(null);
const [audioElements, setAudioElements] = useState<HTMLAudioElement[]>([]);
const [audioElements, setAudioElements] = useState<
{
audioCtx: AudioContext;
gainNode: GainNode;
source: MediaStreamAudioSourceNode;
}[]
>([]);
const [noStreamError, setNoStreamError] = useState(false);
const audioElementsRef = useRef<HTMLAudioElement[]>(audioElements);
const audioElementsRef = useRef<
{
audioCtx: AudioContext;
gainNode: GainNode;
source: MediaStreamAudioSourceNode;
}[]
>(audioElements);
const navigate = useNavigate();
const { setVolume, audioContext } = useControlVolume({
stream:
inputAudioStream && typeof inputAudioStream !== "string"
? inputAudioStream
: null,
const { setVolume } = useControlVolume({
audioElements,
});

// Use a ref to make sure we only clean up
Expand All @@ -251,10 +282,12 @@ export const useRtcConnection = ({
}, [audioElements]);

const cleanUpAudio = useCallback(() => {
audioElementsRef.current.forEach((el) => {
el.pause();
// eslint-disable-next-line no-param-reassign
el.srcObject = null;
audioElementsRef.current.forEach(({ audioCtx, source, gainNode }) => {
// el.pause();
// el.srcObject = null;
source.disconnect();
gainNode.disconnect();
audioCtx.close();
});
}, [audioElementsRef]);

Expand Down Expand Up @@ -405,5 +438,5 @@ export const useRtcConnection = ({
};
}, [rtcPeerConnection]);

return { connectionState, audioElements, setVolume, audioContext };
return { connectionState, audioElements, setVolume };
};

0 comments on commit 7804794

Please sign in to comment.