[ios] CMTime & addBoundaryTimeObserver
[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
값들을 살펴보도록 하겠습니다.
time1
은value
는 1이고timescale
은 4로 1/4초를 의미한다.time2
는value
는 2이고timescale
은 8로 2/8초를 의미한다.time3
는value
는 1이고timescale
은 10000으로 1/10000초를 의미한다.- 즉
time1
과time2
는 같은 값이다. (CMTimeCompare(time1, time2) = 0
)
CMTime
은 비디오와 오디오 같은 미디어의 타임라인을 위해 고안된 타입이라고 애플의 문서에 나와있습니다. 그러므로 비디오와 오디오와 같은 미디어를 다루는 작업을 해야 한다면 CMTime
을 자주 보게 될 것 같습니다.
Implemenation
이제 위에서 살펴본 두 가지를 이용해 제가 원하는 기능을 구현한 코드를 간단하게 살펴보도록 하겠습니다.
- 1/600초를 의미하는
CMTime
을 생성합니다. CMTime
을NSValue
타입 배열의 형태로 바꿉니다.addBoundaryTimeObserver
의 매개변수로 넣어줍니다. 이때queue
는 클로저 블록에 해당하는 코드를 어느 스레드 큐에서 실행시켜줄지를 지정하는 것입니다. 저는 현재 UI에 애니메이션을 주기 때문에 메인 스레드에서 해당 코드를 실행할 것입니다. 여기서forTimes
가 배열인 이유는 해당 미디어의 재생 시간동안 여러 시간대에서 원하는 액션을 취하게 해주기 위함입니다. 저는 오디오가 시작할 때 한 번만 실행할 것이기 때문에 하나의 시간 값만을 넣어주었습니다.
이제 해당 메소드는 오디오가 실행되고 1/600초가 지난 후 블록안에 작성해준 애니메이션 코드를 실행시킬 것입니다. 1/600초이기 때문에 오디오가 실행된 동시에 코드가 실행된다고 봐도 무방합니다.
마무리
오늘은 이렇게 CMTime
과 addBoundaryTimeObserver
메소드에 대해 간단하게 알아보고 저는 어떻게 적용을 하였는지를 기록하고 공유해보았습니다. AVKit
를 다루게 되면 자주 보게 될 요소들인 것 같아 이렇게 글로 남겨보았습니다. 제가 처음 다뤄보는 모듈이기 때문에 틀린 점이 있다면 댓글로 알려주시기 바랍니다. 감사합니다. 😄
출처