자바스크립트와 HTML로 이루어진 페이지에서 audio태그를 사용하여 음원을 재생할 때 설정할 수 있는 구간 반복 기능을 구현한 예제입니다. 언어 학습 등에 사용하면 좋을 것 같습니다.

자바스크립트 오디오 객체에서 특정 이벤트를 실행하는 방법은 다음과 같습니다.

audioElement.addEventListener(type, listener[, useCapture]);
  • type: 이벤트 종류(timeupdate, play, loaddedmetadata 등)
  • listener: 해당 이벤트 발생 시 실행할 함수
  • useCapture: 이벤트 전파 관련 설정 (옵셔널이며 기본값 false, 관련 글 보기)

 

JSFiddle 에서 코드 보기 및 실행

자바스크립트 Audio 참고글

2020년 6월 11일 업데이트: 오디오 구간반복 부분은 timeupdate 이벤트를 사용하는 것보다 setInterval을 사용하는 것이 더 자연스럽습니다. timeupdate는 끊기는 부분이 많아 부자연스러운 구간 반복이 되는 경우가 많습니다.

// 재생 중일때, 현재 위치가 끝 위치보다 크면 시작 위치로 되돌아가도록 함
setInterval(e => {
  if(setting.isSectionRepeatOn && audio.currentTime >= setting.endTime){
  	audio.currentTime = setting.startTime
    audio.play()
  }
}, 100)

 

<audio id=audio controls preload="metadata" loop>
  <source id=sndSrc src="http://cdndown.chosun.com/chosun/entertainment/native/Japanese-20191217.mp3" type="audio/mpeg">
  Your browser does not support the audio element.
</audio>
<button id="btn-set-repeat">
구간반복 OFF
</button>
<button id="btn-set-start">
  시작
</button>
<button id="btn-set-end">
  끝
</button>
<pre id="debug"></pre>
.blue{
  color: blue;
}
// audio 객체 로드
const audio = document.getElementById("audio")

// 설정 변수
const setting = {
  isSectionRepeatOn: false,
  startTime: 0,
  endTime: 0
}

// DOM 로드
const btnSetRepeat = document.getElementById("btn-set-repeat")
const btnSetStart = document.getElementById("btn-set-start")
const btnSetEnd = document.getElementById("btn-set-end")
const debug = document.getElementById("debug")

// 오디오 메타 데이터가 로드되었을 때
audio.addEventListener("loadedmetadata", e => {
  setting.endTime = e.target.duration
}, false)

// 버튼 클릭 이벤트(시작, 끝)
btnSetStart.onclick = e => {
  if(setting.endTime <= audio.currentTime){
  	debug.innerHTML = "시작 시간은 끝 시간보다 크거나 같으면 안됩니다."
  } else {
    setting.startTime = audio.currentTime
    debug.innerHTML = `시작: ${setting.startTime} / 끝: ${setting.endTime}`
    // 구간반복 ON 상태에서 시작 버튼 클릭하면 구간반복이 OFF되도록 함 (UX 측면)
    if(setting.isSectionRepeatOn){
    	btnSetRepeat.click()
    }
  }
}
btnSetEnd.onclick = e => {
  if(setting.StartTime >= audio.currentTime){
  	debug.innerHTML = "끝 시간은 시작 시간보다 작거나 같으면 안됩니다."
  } else {
    setting.endTime = audio.currentTime
    debug.innerHTML = `시작: ${setting.startTime} / 끝: ${setting.endTime}`
    // 구간반복 OFF 상태에서 끝 버튼 클릭하면 구간반복이 ON되도록 함 (UX 측면)
    if(!setting.isSectionRepeatOn){
    	btnSetRepeat.click()
    }
  }
}

// 버튼 설정 이벤트(구간반복 ON/OFF)
btnSetRepeat.onclick = e => {
  setting.isSectionRepeatOn = !setting.isSectionRepeatOn
  if(setting.isSectionRepeatOn){
  	btnSetRepeat.innerHTML = "구간반복 ON"
    btnSetRepeat.className = "blue"
    audio.currentTime = setting.startTime
    audio.play()
  } else {
  	btnSetRepeat.innerHTML = "구간반복 OFF"
    btnSetRepeat.className = ""
  }
}

// 재생 중일때, 현재 위치가 끝 위치보다 크면 시작 위치로 되돌아가도록 함
audio.addEventListener("timeupdate", e => {
  if(setting.isSectionRepeatOn && audio.currentTime >= setting.endTime){
  	audio.currentTime = setting.startTime
    audio.play()
  }
}, false)

// 구간반복 ON일때, 현재 위치가 시작 위치보다 작으면 시작 위치로 강제 이동하도록 함
audio.addEventListener("play", e => {
  if(setting.isSectionRepeatOn && audio.currentTime <= setting.startTime){
  	audio.currentTime = setting.startTime
  }
}, false)

 

문의 | 코멘트 또는 yoonbumtae@gmail.com


카테고리: WEB: Frontend


0개의 댓글

답글 남기기

Avatar placeholder

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다