Nuxt3 프로젝트를 진행하며 사용자 알림용 소리나 효과음을 넣을 일이 종종 생깁니다. new Audio('/alarm.mp3')처럼 간단히 구현할 수 있지만, 한 가지 문제가 있습니다:
✅ 버튼을 여러 번 누르면 이전 오디오가 겹쳐서 동시에 재생되는 현상!
이 글에서는 이 문제의 원인과 해결 방법, 그리고 오디오 관련 속성인 preload, load()의 개념까지 정리해보겠습니다.
📌 문제: 오디오가 겹쳐 재생된다?
다음과 같은 코드가 있다고 가정해봅시다:
const audio = new Audio('/alarm.mp3')
audio.play()
이 코드를 버튼 클릭 시마다 실행하면, 매번 새로운 Audio 인스턴스가 생성되어 각각 따로 재생됩니다. 그래서 버튼을 여러 번 누르면 소리가 겹쳐 들리게 됩니다.
✅ 해결 방법: 오디오 인스턴스를 재활용하자
<script setup lang="ts">
import { ref, onUnmounted } from 'vue'
const alarm = '/alarm.mp3'
const audioRef = ref<HTMLAudioElement | null>(null)
const playAlarm = () => {
// 기존 오디오가 있다면 정지하고 처음으로 돌림
if (audioRef.value) {
audioRef.value.pause()
audioRef.value.currentTime = 0
}
// 새 오디오 인스턴스 생성 및 재생
const newAudio = new Audio(alarm)
newAudio.play()
audioRef.value = newAudio
}
// 컴포넌트 사라질 때 정리
onUnmounted(() => {
if (audioRef.value) {
audioRef.value.pause()
audioRef.value = null
}
})
</script>
<template>
<button @click="playAlarm">🔔 알람 재생</button>
</template>
이렇게 하면 오디오는 매번 새로 생성되지만, 기존에 재생되던 소리를 먼저 멈추고 초기화하기 때문에 중첩되는 일이 없습니다.
🎛️ 추가 개념: preload 와 load()는 뭘까?
HTML5 <audio>나 new Audio()로 오디오를 다룰 때 사용할 수 있는 속성과 메서드입니다.
🔹 audio.preload = 'auto'
- 브라우저에게 오디오를 미리 로딩하라고 힌트를 줍니다.
- 'auto': 오디오 전체를 미리 받아올 수도 있음
- 'metadata': 길이 같은 메타 정보만 미리 로딩
- 'none': 아예 미리 로딩하지 않음 (필요할 때만 다운로드)
🔹 audio.load()
- 오디오 파일을 명시적으로 다시 로드하게 합니다.
- 소스를 바꿨거나, 강제로 다시 불러오고 싶을 때 사용합니다.
예시:
const audio = new Audio('/sound.mp3')
audio.preload = 'auto'
audio.load() // 브라우저가 지금 오디오를 다운로드하도록 시도함
단, preload와 load는 브라우저의 정책이나 사용자 상호작용 여부에 따라 무시될 수 있습니다. 특히 모바일에서는 더 엄격하니 테스트가 중요합니다.
✨ 마무리
Nuxt3에서 오디오를 다룰 때:
- 중복 재생을 방지하려면 기존 오디오를 멈추고 새로 재생해야 합니다.
- preload, load() 속성은 오디오의 미리 로딩 여부와 시점을 제어할 수 있습니다.
'삼분공부 > Vue' 카테고리의 다른 글
[Nuxt.js] Nuxt 3에서 nitro.devProxy와 운영 환경 API 연동 (1) | 2025.04.14 |
---|---|
[Nuxt] meta 태그의 name과 property 차이점 (0) | 2025.04.02 |
[Nuxt.js] page 별로 layout 다르게 적용하는 방법 (0) | 2025.03.11 |
[Nuxt.js] <NuxtLink> 사용하는 이유 ! (0) | 2025.02.06 |
[Nuxt] nuxt.js 에서 텍스트 에디터 추가하기 - @tiptap (0) | 2024.12.30 |