Swift + iOS/iOS

[ios] CMTime & addBoundaryTimeObserver

군옥수수수 2018. 3. 6. 22:51

[ios] CMTime & addBoundaryTimeObserver


안녕하세요. 오늘은 AVKit를 이용하다가 새로 알게 된 것이 있어 이렇게 기록을 통해 남겨놓으려 합니다.


저는 AVKit을 이용해 특정 오디오를 재생시키는 기능을 구현하고 있었습니다. 구현하는 중 저는 오디오가 재생되기 시작하면 그에 맞춰서 특정 애니메이션을 주어 오디오가 재생되고 있다는 것을 사용자가 보다 확실히 느낄 수 있게끔 하고 싶었습니다.


처음에 구현한 코드는 다음과 같습니다. (간단하게 표현하도록 하겠습니다.)


하지만 원하는 동작은 이루어지지 않았습니다. 재생이 끝난 후가 아닌 뷰가 로드되자마자 해당 애니메이션이 실행되어 제가 볼 수 있는 시점에서는 이미 애니메이션이 종료된 상태였습니다.


그래서 구글링을 하던 도중 addBoundaryTimeObserver라는 메소드를 알게 되었고 해당 메소드를 사용한 코드를 이제 소개해드리도록 하겠습니다.


addBoundaryTimeObserver(forTimes:queue:using:)

이 메소드를 간단히 소개하자면 오디오나 비디오 등이 정상적으로 재생이 되는 동안 특정 시간대에 추가적인 액션을 취할 수 있게끔 해주는 메소드입니다. 애플 문서에는 다음과 같이 설명되있습니다.


Requests the invocation of a block when specified times are traversed during normal playback.

(영어로 된 설명을 한국어로 옮기니 이해하기가 더 어려운 것 같네요. 😂 )

위의 메소드를 사용하기 위해서는 먼저 forTime:로 넘어갈 NSValue에는 어떤 값이 담겨야 하는지를 알아보도록 하겠습니다.

CMTime

CMTime은 시간 값을 나타내는 구조체 타입입니다. CMTime은 유리수로 표현되며 CMTime을 표현하기 위해서는 분자와 분모에 해당하는 값을 필요로 합니다.


CMTime구조체는 CMTimeMake라는 함수로 생성할 수 있습니다. 위에서 생성된 CMTime 값들을 살펴보도록 하겠습니다.


  • time1value는 1이고 timescale은 4로 1/4초를 의미한다.
  • time2value는 2이고 timescale은 8로 2/8초를 의미한다.
  • time3value는 1이고 timescale은 10000으로 1/10000초를 의미한다.
  • time1time2는 같은 값이다. (CMTimeCompare(time1, time2) = 0)

CMTime은 비디오와 오디오 같은 미디어의 타임라인을 위해 고안된 타입이라고 애플의 문서에 나와있습니다. 그러므로 비디오와 오디오와 같은 미디어를 다루는 작업을 해야 한다면 CMTime을 자주 보게 될 것 같습니다.

Implemenation

이제 위에서 살펴본 두 가지를 이용해 제가 원하는 기능을 구현한 코드를 간단하게 살펴보도록 하겠습니다.


  1. 1/600초를 의미하는 CMTime을 생성합니다.
  2. CMTimeNSValue 타입 배열의 형태로 바꿉니다.
  3. addBoundaryTimeObserver 의 매개변수로 넣어줍니다. 이때 queue는 클로저 블록에 해당하는 코드를 어느 스레드 큐에서 실행시켜줄지를 지정하는 것입니다. 저는 현재 UI에 애니메이션을 주기 때문에 메인 스레드에서 해당 코드를 실행할 것입니다. 여기서 forTimes가 배열인 이유는 해당 미디어의 재생  시간동안 여러 시간대에서 원하는 액션을 취하게 해주기 위함입니다. 저는 오디오가 시작할 때 한 번만 실행할 것이기 때문에 하나의 시간 값만을 넣어주었습니다.

이제 해당 메소드는 오디오가 실행되고 1/600초가 지난 후 블록안에 작성해준 애니메이션 코드를 실행시킬 것입니다. 1/600초이기 때문에 오디오가 실행된 동시에 코드가 실행된다고 봐도 무방합니다.


마무리

오늘은 이렇게 CMTimeaddBoundaryTimeObserver메소드에 대해 간단하게 알아보고 저는 어떻게 적용을 하였는지를 기록하고 공유해보았습니다. AVKit를 다루게 되면 자주 보게 될 요소들인 것 같아 이렇게 글로 남겨보았습니다. 제가 처음 다뤄보는 모듈이기 때문에 틀린 점이 있다면 댓글로 알려주시기 바랍니다. 감사합니다. 😄


출처


  1. addBoundaryTimeObserver
  2. CMTime
  3. Trying to understand CMTime and CMTimeMake