diff --git a/client/src/composables/libAudio.ts b/client/src/composables/libAudio.ts new file mode 100644 index 0000000..5d8048c --- /dev/null +++ b/client/src/composables/libAudio.ts @@ -0,0 +1,16 @@ +/** Получает путь к аудио по id */ +export function getSoundPathById(id: string): string { + const sound = SOUND_LIBRARY.find(s => s.id === id); + + if (!sound) { + throw new Error("Sound not found"); + } + + return sound.file; +} + +const base_path = "/sounds" + +const SOUND_LIBRARY = [ + { id: "alarm_beep", file: `${base_path}/alarm-beep.mp3`, name: "Alarm Beep" } +]; diff --git a/client/src/composables/useAudio.ts b/client/src/composables/useAudio.ts new file mode 100644 index 0000000..3af164f --- /dev/null +++ b/client/src/composables/useAudio.ts @@ -0,0 +1,49 @@ +let audioContext: AudioContext | null = null; +let currentSource: AudioBufferSourceNode | null = null; + +/** Получить AudioContext */ +function getAudioContext(): AudioContext { + if (!audioContext) { + audioContext = new AudioContext(); + } + + return audioContext; +} + +/** Воспроизводит звук */ +export async function playSound(url: string): Promise { + const context = getAudioContext(); + + if (context.state === 'suspended') { + await context.resume(); + } + + // Если уже играет звук — остановит + stopSound(); + + const response = await fetch(url); + const arrayBuffer = await response.arrayBuffer(); + const audioBuffer = await context.decodeAudioData(arrayBuffer); + const source = context.createBufferSource(); + + source.buffer = audioBuffer; + source.connect(context.destination); + currentSource = source; + source.start(0); + source.onended = () => { + source.disconnect(); + + if (currentSource === source) { + currentSource = null; + } + }; +} + +/** Останавливает звук */ +export function stopSound(): void { + if (currentSource) { + currentSource.stop(); + currentSource.disconnect(); + currentSource = null; + } +}