AVPlayer 알아보기

글쓴이 연유 날짜

iOS 상에서 웹 브라우저라면 HTML에 따라 비디오 플레이어를 표시할 수 있습니다. 만약, 앱에서 비디오를 표시하려면 비디오를 표시하기 위한 라이브러리를 이용해야합니다. 여러분의 앱 요구사항에 따라 간단하게 운영체제의 디자인을 따라가는 AVKit을 이용할 수도 있을 것이고, AVFoundation을 이용하여 커스터마이징된 플레이어를 구현할 수도 있습니다.

AVKit과 AVFoundation 중 어떤 것을 이용해서 구현해야 할까?

iOS에서 앱에서 비디오 재생을 구현하기 위해서 이용할 수 있는 라이브러리로 AVKitAVFoundation이 있습니다. 서로 무관한 것은 아니지만, 일단 이 두 가지를 알아봅시다.

AVKit

AVKit은 AVFoundation과 UIKit으로 구현된 Player View Controller입니다. 특별하게 커스텀 구현을 해야할 일이 없을 경우 AVPlayerViewController 또는 VideoPlayer(iOS 14 이상, SwiftUI)를 이용해 이미 만들어진 플레이어를 이용할 수 있습니다.

차례로 AVPlayerViewController의 inline 타입과 fullscreen type1사용된 샘플 코드로 Apple Developer Documentation의 샘플 프로젝트를 참고했습니다., 그리고 SwiftUI 상에서의 VideoPlayer를 나열했습니다. SwiftUI를 위한 VideoPlayer의 경우 아직 자체적으로 FullScreen과 Inline player를 전환하는 기능이 없어보입니다.

AVKit을 이용하게 되면, AVPlayer를 통해 리소스를 정의하고 이미 만들어진 View Controller를 앱에 넣는 방식으로 앱 내 VideoPlayer를 구현할 수 있습니다. 이미 기본적인 컨트롤을 위해서 상태 바나 기타 버튼 등이 구현된 상태입니다. 기 구현된 요소들을 커스터마이징하는 방법은 따로 제공하고 있지 않지만, 특별한 요구사항이 없는 경우 iOS 인터페이스를 충실히 따르는 AVPlayerViewController를 활용하면 간편하게 앱에서 영상을 재생할 수 있습니다.

만약, 상태 바나 기타 버튼, 그리고 기본적인 작동을 커스터마이징하려면 AVKit이 아닌 AVFoundation을 이용해야합니다.

AVFoundation

직접 플레이어의 UI를 구현하지 않고, AVKit을 쓴다고 하더라도 내부는 동일하게 AVFoundation으로 구현되어 있습니다. 또한 AVPlayer와 AVPlayerItem등의 사용법을 알아야지 AVPlayerViewController를 이용해 동영상을 재생시킬 수 있습니다. 만약에 애플에서 기본적으로 제공하는 UI가 아닌, 커스텀 UI를 만들 필요가 있을 경우 AVKit을 사용하지 않고, View를 새로 만들고, 그 안에 AVPlayerLayer를 삽입할 필요가 있습니다.

AVPlayer

AVPlayer

미디어 재생을 관리하기 위해 AVPlayer를 사용합니다. AVPlayer는 사용자가 직접 조작할 수 있는 인터페이스를 제공하는 것이 아니기 때문에 AVKit의 이미 구현된 뷰 또는, AVPlayerLayer를 이용해서 컨텐츠를 표시해야합니다.

AVPlayer는 플레이할 URL 또는 미리 만들어진 PlayerItem을 받아 생성할 수 있습니다. AVPlayer를 이용하면 현재 item이 무엇인지 알 수 있고, item을 쉽게 조작할 수 있습니다. 또한, 재생하고 있는 아이템을 교체할 수도 있습니다. 동영상 재생 시 쓰일 수 있는 대부분의 기능을 AVPlayer를 통해 쉽게 조작할 수 있습니다.

AVPlayerItem

AVPlayerItem은 AVAsset에 대한 모델입니다. AVAsset은 플레이할 미디어에 대한 정보인데, AVPlayerItem은 AVAsset에 대한 참조를 가지고, 그에 대한 정보(미디어에 고유한 정보나, 상태에 대한 정보)를 저장합니다. 이러한 값들을 가져오는 데는 시간이 걸리기 때문에 AVPlayerItem의 값들이 동기적으로 로딩되지는 않습니다. 따라서 AVPlayerItem은 AVAsynchronousKeyValueLoading을 채택하고 있습니다.

영상을 재생하는 동안 값들이 변할 수 있기 때문에 KeyValueObserving을 하여, 변화하는 값에 대응할 수 있습니다. (https://developer.apple.com/documentation/objectivec/nsobject/nskeyvalueobserving)

AVPlayerLayer

AVPlayer의 영상이 나타나는 CALayer 객체입니다. 일반적으로, UIView의 layerClass를 오버라이딩하여 사용합니다. 커스텀 플레이어를 만드는 경우, 이 레이어를 이용해 영상을 표시하고, 나머지 요소들은 직접 구현할 수도 있습니다.

AVMediaSelection

Media에는 영상, 소리, 그 외에도 자막이나 보조 요소등이 있을 수 있습니다. AVMediaSelection은 제공되는 요소들을 어떻게 선택할 지에 대한 객체입니다. 예를 들어서, 전 세계에 방송되는 행사에서 사람마다 언어가 다르기 때문에 자막을 따로 선택하는 것과 같은 기능을 AVMediaSelection에서 제공합니다.

AVAssetDownloadURLSession

AVURLAsset으로 표현되는 데이터를 다운로드 받을 수 있는 URLSession 객체입니다. URLSession을 통해 직접 리소스를 다운로드 받을 수도 있겠지만, AVAssetDownloadURLSession을 이용하면 AVURLAsset이 표현하는 리소스를 직접 URL로 매핑할 필요없이 다운로드 받을 수 있습니다. (HLS와 같이 플레이 리스트 형식으로 리소스가 로드되는 경우를 생각하면, URL을 통해 직접 다운로드하는 것 보다는 AVURLAsset으로 표현되는 리소스를 다운로드 받는 게 더 쉬운 것을 아실 수 있을 것입니다.)

AVURLAsset을 이용하면 메모리 상에만 리소스를 다운로드 받지만, AVAssetDownloadURLSession을 이용하면 영구 저장소에 저장을 하게 됩니다. AVAssetDownloadDelegate를 구현하여 다운로드 받는 상황과 어느 위치에 다운로드 받는 지를 알 수 있습니다. 미디어의 위치를 UserDefault 또는 다른 데이터 베이스에 저장하여 Offline playback으로도 이용할 수 있습니다.

다운로드 받은 미디어는 시스템이 관리할 수 있습니다. 설정 > 스토리지 > 개개의 앱 내역에서 다운로드 받은 미디어가 표시됩니다. 아이폰의 용량이 충분하지 않다면 시스템은 이러한 Offline playback을 자동적으로 제거합니다.2최대 용량을 설정하거나 하는 일은 지원하지 않고, 용량이 충분하지 않을 때 지워집니다. 만약, 최대 용량에 따라 리플레이스멘트 알고리즘을 구현한다면, FileManager를 통해 수동으로 미디어를 미리 지울 수도 있을 것 입니다. 조금 더 세밀한 설정을 위해 AVAssetDownloadStorageManager로 다운로드 받은 미디어의 저장 정책을 설정할 수 있습니다.

AVAsset

AVAsset

AVAsset은 AVAssetTrack을 포함하는 컨테이너입니다. AVAssetTrack은 비디오, 오디오, 자막 등이 될 수 있다.3정확한 AVAssetTrack의 타입들은 https://developer.apple.com/documentation/avfoundation/avmediatype을 참고하세요. 비유를 들어서 설명하자면, AVAsset은 한 편의 드라마 파일에 대응하고, AVAssetTrack은 그 드라마 파일에서 소리만, 비디오만, 자막만 추출한 것이라고 생각하면 좋을 것 같습니다.

AVAsset은 데이터를 비동기적으로 로딩할 수 있으며, AVAsynchronousKeyValueLoading 프로토콜을 채택하고 있습니다. 데이터가 생성과 동시에 로딩되는 것은 아니기 때문에4예를 들어 인터넷에서 파일을 받거나, 로컬에서 엄청나게 큰 파일을 여는 것을 생각해보세요. 만약 동기적으로 작성이 되어있으면, 여러분의 앱은 파일을 로드하는 동안 유저와 상호작용하지 못 하고, 마치 고장난 것 처럼 멈춰있을 것 입니다., 값에 직접 접근하면 로딩하고 있는 데이터를 동기적으로 기다려야 합니다. AVAsset은 클로저를 통해 값이 로딩 되었을 때, 작업을 비동기적으로 실행할 수 있도록 loadValuesAsynchronously(forKeys:completionHandler:)등을 제공합니다.

AVAsset이 지원하는 파일 타입 등을 확인하려면 Media Assets and Metadata 하단의 Supporting Type을 참조하세요.

AVMetadataItem

AVMetadataItem은 AVAsset에는 포함되지 않는 정보를 나타냅니다. 예를 들어서 한 편의 Blulay 영화를 구매했다고 합시다. 이 때, 블루레이 영화의 데이터가 보존된 디스크는 AVAsset에 해당하고, 껍데기에 포함된 사진이나 여러 정보는 AVMetadataItem에 포함될 수 있습니다.5정확하게 따지자면, 사실 디스크의 미디어 파일에도 헤더나 부가 파일에 감독, 주연, 발행연도 등이 포함되어 있을 수도 있어서 다를 수 있지만, 여기서는 아무런 다른 정보가 없이 영상 파일만 덩그러니 있다고 합시다. AVMetadataItem은 다양한 종류의 Metadata를 지원합니다.

<초본, 개선 예정>

카테고리: 미분류