티스토리 뷰

발생일: 2011.10.12

문제:
버튼을 클릭하면 오디오가 재생되고, 오디오 재생 상태에 따라 버튼의 모양을 변경하려고 한다.

<audio> 엘리먼트의 onplay / onended 이벤트를 컨트롤 해서,
재생될 때 아이콘의 모양을 변경하면 간단히 해결될 것 같았다.

대상이 되는 audio 엘리먼트에 간단하게 아래와 같이 이벤트를 할당했다.

  audio.addEventListener("play", function () {
    // 재생 모양으로 아이콘 변경
  }, false);

  audio.addEventListener("ended", function () {
    // 대기 모양으로 아이콘 변경
  }, false);



음.. 헌데,..
최초로 버튼을 클릭했을 땐 play 이벤트가 잘 호출되는데,
두 번째 클릭(또는 두 번째 재생)부터는 play 이벤트가 호출되지 않는다.

여러 번 시도에 관계 없이 ended 이벤트는 의도한 대로 작동한다.

뭐가 문제일까?


해결책:
원인은, 오디오가 재생되었으나 명시적으로 '멈춤(paused)' 상태가 되지 않았기 때문이다.

w3c 스펙을 확인해보니, 미디어 엘리먼트(video, audio, ...)의 play 이벤트가 아래와 같이 정의되어 있다.

  play Event

  Fired when... : 
    The element is no longer paused.
    Fired after the play() method has returned,
    or when the autoplay attribute has caused playback to begin.

  Preconditions :
    paused is newly false.

  http://dev.w3.org/html5/spec-author-view/media-elements.html#mediaevents


play() 메서드가 호출되어 paused 상태가 아닐 때에 발생하며,
전제 조건으로 paused 가 새로 false 가 되었을 때이다.


여기서 유심히 보아야 할 것이 미디어 엘리먼트의 paused 속성인데,
현재 재생 상태에 따라 true 또는 false 의 값을 갖는다.
딱 위 문장만 읽었을 땐 굉장히 헷갈렸는데, paused 속성에 대해 이해하니 좀 덜하다. -_-;

paused 속성은 미디어 엘리먼트의 속성으로 접근해 읽어올 수 있지만,
직접 설정은 불가능하다. (audio.paused = true; 는 적용되지 않는다)


paused 속성을 변경하는 두 가지 메서드가 있는데, play() 와 paused()이다.

play() 메서드를 호출하면 미디어 소스가 재생되고,
엘리먼트의 paused 속성을 false로 설정한다. (즉, 더 이상 paused 상태가 아닌 것이다)

하지만 재생이 종료된 후에도, paused 속성을 true로 변경하진 않는다. 



play()와 반대 개념의 pause() 메서드를 호출하면,
재생을 멈추고 paused 속성을 true로 변경한다.

(media play 스펙 참고: http://dev.w3.org/html5/spec-author-view/media-elements.html#dom-media-play)



위 문제에선,
play() 메서드가 호출된 이후에 paused 상태가 변경되지 않았기 때문에(paused = false),
play 이벤트의 'paused is newly false.' 전제 조건에 부합하지 않아서 이벤트가 발생하지 않았던 것이었다.


고로, 재생 후 paused 값을 true로 설정하기 위해,
ended 이벤트에서 명시적으로 paused() 호출해 주는 방법으로 해결했다.

  audio.addEventListener("ended", function () {
    audio.pause();
    // 대기 모양으로 아이콘 변경
  }, false);


 

반응형
댓글
공지사항