Use html audio element to call setsink id for reactions and call sounds.

This commit is contained in:
Timo
2025-06-05 11:53:01 +02:00
parent 34724b7a8c
commit aabdc2e894

View File

@@ -76,15 +76,18 @@ export function useAudioContext<S extends string>(
const [audioContext, setAudioContext] = useState<AudioContext>(); const [audioContext, setAudioContext] = useState<AudioContext>();
const [audioBuffers, setAudioBuffers] = useState<Record<S, AudioBuffer>>(); const [audioBuffers, setAudioBuffers] = useState<Record<S, AudioBuffer>>();
const [htmlAudioElement] = useState((): HTMLAudioElement => new Audio());
useEffect(() => { useEffect(() => {
const sounds = props.sounds; const sounds = props.sounds;
if (!sounds) { if (!sounds || !htmlAudioElement) {
return; return;
} }
const ctx = new AudioContext({ const ctx = new AudioContext({
// We want low latency for these effects. // We want low latency for these effects.
latencyHint: props.latencyHint, latencyHint: props.latencyHint,
}); });
htmlAudioElement.srcObject = ctx.createMediaStreamDestination().stream;
// We want to clone the content of our preloaded // We want to clone the content of our preloaded
// sound buffers into this context. The context may // sound buffers into this context. The context may
@@ -107,22 +110,16 @@ export function useAudioContext<S extends string>(
}); });
setAudioContext(undefined); setAudioContext(undefined);
}; };
}, [props.sounds, props.latencyHint]); }, [props.sounds, props.latencyHint, htmlAudioElement]);
// Update the sink ID whenever we change devices. // Update the sink ID whenever we change devices.
useEffect(() => { useEffect(() => {
if ( if (!controlledAudioDevices && audioOutput.selectedId) {
audioContext && htmlAudioElement.setSinkId(audioOutput.selectedId).catch((ex) => {
"setSinkId" in audioContext &&
!controlledAudioDevices
) {
// https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/setSinkId
// @ts-expect-error - setSinkId doesn't exist yet in types, maybe because it's not supported everywhere.
audioContext.setSinkId(audioOutput.selectedId).catch((ex) => {
logger.warn("Unable to change sink for audio context", ex); logger.warn("Unable to change sink for audio context", ex);
}); });
} }
}, [audioContext, audioOutput.selectedId, controlledAudioDevices]); }, [audioOutput.selectedId, controlledAudioDevices, htmlAudioElement]);
const { pan: earpiecePan, volume: earpieceVolume } = useEarpieceAudioConfig(); const { pan: earpiecePan, volume: earpieceVolume } = useEarpieceAudioConfig();
// Don't return a function until we're ready. // Don't return a function until we're ready.