AVPlayerViewController는 Apple 생태계에 내장된 비디오 플레이어 컨트롤러로, iOS 및 tvOS에서 미디어 콘텐츠를 재생하도록 설계되었습니다. 커스텀 UI를 작성할 필요 없이 전체 화면 인터페이스, 컨트롤, 자막 지원 및 AirPlay를 제공합니다. Apple Developer 문서, 2026에 따르면, AVPlayerViewController는 몇 줄의 코드로 통합되며 HLS, MP4 및 대부분의 미디어 형식을 지원합니다.
핵심 요점
AVPlayerViewController는 Apple 애플리케이션에서 비디오를 재생하기 위한 즉시 사용 가능한 인터페이스를 제공하는 AVKit 프레임워크의 구성 요소입니다. 처음부터 커스텀 플레이어를 만들 필요가 없으며, 재생/일시 정지, 스크러빙, 볼륨 조절 및 전체 화면 모드와 같은 표준 컨트롤을 제공합니다.
수동 UI 구축이 필요한 저수준 AVPlayerLayer와 달리, AVPlayerViewController는 플레이어 수명 주기를 완전히 관리합니다. 컨트롤러는 자동으로 화면 회전을 처리하고, 노치가 있는 iPhone의 Safe Area에 적응하며, iPad에서 멀티태스킹을 지원합니다.
Apple 문서(2026)에 따르면, AVPlayerViewController는 AVPlayer 및 AVQueuePlayer와 호환되며 단일 파일과 재생 목록을 모두 재생할 수 있습니다. 로컬 저장소의 URL, HLS 네트워크 스트림 및 암호화된 FairPlay 콘텐츠가 지원됩니다.
이 구성 요소는 iOS 8에서 AVKit과 함께 더 이상 사용되지 않는 MPMoviePlayerController를 대체하여 등장했습니다. iOS 11에서는 Picture in Picture 및 자막 표시 지원이 추가되었습니다. iOS 14에서는 컨트롤러가 AVPlayerViewControllerDelegate를 통해 사용자 지정 가능한 전송 바를 받았습니다. iOS 16부터는 플레이어를 다시 만들지 않고 미디어 파일을 동적으로 교체하는 지원이 도입되었습니다.
최신 AVPlayerViewController는 ProMotion 디스플레이에 최적화되어 있습니다. 비디오 프레임 속도가 자동으로 화면 새로 고침 빈도와 동기화됩니다. tvOS에서는 Siri Remote 포커스 인터페이스에 적응하고, macOS에서는 QuickTime Player 창 모드에 적응합니다.
컨트롤러의 핵심에는 AVPlayer와 AVPlayerItem의 페어링이 있습니다. AVPlayer는 타임라인, 속도 및 상태를 관리하는 재생 객체입니다. AVPlayerItem은 특정 미디어 파일을 감싸는 래퍼로, 메타데이터, 트랙 및 로딩 정보를 포함합니다.
초기화되면 AVPlayerViewController는 AVPlayer에 대한 참조를 받고 비디오 표시를 위한 AVPlayerLayer를 자동으로 생성합니다. 컨트롤러는 readyToPlay, 로딩 오류 및 재생 완료와 같은 상태 변경에 대한 AVPlayer KVO 알림을 구독합니다.
컨트롤(전송 바)은 탭하면 표시됩니다. iOS 15+에서는 AVPlayerViewControllerCustomizationDelegate를 통한 사용자 지정을 지원하여 표준 버튼을 숨기거나 교체할 수 있습니다.
컨트롤러를 만들고 AVPlayer를 할당한 후 viewDidLoad 메서드가 호출되어 비디오 스트림 준비를 시작합니다. AVPlayerItem이 AVPlayerItemStatusReadyToPlay 상태로 전환되면 플레이어가 프레임을 표시할 준비가 됩니다. play() 메서드가 호출되면 Video Toolbox를 통해 비디오 스트림 디코딩이 시작됩니다.
화면을 떠나면 컨트롤러가 자동으로 재생을 일시 중지하고 디코더 리소스를 해제합니다. iOS 13+에서 앱이 최소화될 때 재생을 유지하려면 백그라운드 모드와 오디오 세션을 구성해야 합니다. WWDC 2024에 따르면 iOS 미디어 센터와의 동기화를 위해 AVPlayerPlaybackCoordinator를 사용하는 것이 좋습니다.
이 구성 요소는 즉시 사용 가능한 풍부한 기능 세트를 제공하므로 대부분의 프로젝트에 매력적입니다. 아래는 추가 코드가 필요 없는 주요 기능입니다.
전송 바는 주요 컨트롤 버튼이 포함된 인터페이스의 하단 부분입니다. 기본적으로 사용자가 3초 동안 비활성 상태이면 바가 숨겨지고 탭하면 나타납니다. iOS 16+에서는 델리게이트를 사용하여 개별 요소의 가시성을 제어할 수 있습니다.
디버그 모드에서는 AVPlayerViewController.requiresLinearPlayback 속성을 사용하여 전송 바를 강제로 표시할 수 있으며, 이는 비디오 일시 중지도 방지합니다. 이는 광고 중단 및 교육 콘텐츠에 유용합니다.
컨트롤러의 기본 통합은 10줄 이상의 코드가 필요하지 않습니다. 먼저 미디어 파일 URL로 AVPlayer 인스턴스를 만든 다음 AVPlayerViewController에 전달하고 컨트롤러를 화면에 표시합니다.
import AVKit
let player = AVPlayer(url: URL(string: "https://example.com/video.mp4")!)
let playerVC = AVPlayerViewController()
playerVC.player = player
present(playerVC, animated: true) {
player.play()
}
present를 호출하면 컨트롤러가 전체 화면으로 표시됩니다. 비디오가 네트워크에서 로드를 시작하고 버퍼가 readyToPlay 임계값에 도달하면 play() 호출 후 자동으로 재생이 시작됩니다.
let asset = AVAsset(url: videoURL)
let item = AVPlayerItem(asset: asset)
let metadata = AVMutableMetadataItem()
metadata.key = AVMetadataKey.commonKeyTitle
metadata.value = "내 비디오"
item.addMetadata(metadata)
let player = AVPlayer(playerItem: item)
let playerVC = AVPlayerViewController()
playerVC.player = player
AVPlayerItem을 사용하면 메타데이터, 타임코드, 오디오 트랙 선택 및 자막을 제어할 수 있습니다. AVPlayerItem을 통해 status 속성의 KVO를 사용하여 로딩 진행률, 버퍼링 및 네트워크 오류를 모니터링할 수도 있습니다.
iOS 11부터 개발자는 AVPlayerViewControllerDelegate 프로토콜을 통해 전송 바를 사용자 지정할 수 있습니다. playerViewController(_:willBeginFullScreenPresentationWithAnimationCoordinator:) 메서드는 전체 화면 모드로 들어가기 전에 호출되며 UI를 준비할 수 있습니다.
개별 버튼을 숨기려면 AVPlayerViewController.showsPlaybackControls 속성을 사용합니다. false로 설정하면 전송 바가 완전히 사라지고 비디오 스트림만 남습니다. 사용자 지정 오버레이 요소에 유용합니다.
class CustomPlayerViewController: UIViewController {
private let playerVC = AVPlayerViewController()
override func viewDidLoad() {
super.viewDidLoad()
playerVC.delegate = self
playerVC.showsPlaybackControls = true
playerVC.entersFullScreenWhenPlaybackBegins = true
}
}
extension CustomPlayerViewController: AVPlayerViewControllerDelegate {
func playerViewController(
_ playerViewController: AVPlayerViewController,
willBeginFullScreenPresentationWithAnimationCoordinator coordinator: UIViewControllerTransitionCoordinator
) {
// 오버레이 버튼 추가
}
func playerViewController(
_ playerViewController: AVPlayerViewController,
didUpdate legibleMediaSelection: AVMediaSelectionGroup
) {
print("새 자막 언어 선택됨")
}
}
델리게이트는 자막 변경 이벤트, 전체 화면 모드 진입 및 종료, Picture in Picture 시작 및 종료를 가로챌 수 있습니다. WWDC 2024에서 Apple은 분석을 위해 델리게이트를 사용하고 각 전환을 100ms 이내에 기록할 것을 권장했습니다.
AVPlayerViewController는 미디어 파일에 포함되거나 HLS 매니페스트에 지정된 경우 사용 가능한 모든 자막 및 오디오 트랙을 자동으로 표시합니다. 사용자는 전송 바에서 자막 아이콘을 탭하면 나타나는 메뉴를 통해 전환할 수 있습니다.
HLS 스트림의 경우 M3U8 매니페스트에는 사용 가능한 언어 변형 목록이 포함됩니다. AVPlayer는 해당 WebVTT 자막 세그먼트를 로드하고 렌더링을 위해 AVPlayerLayer에 전달합니다. iOS 16+에서는 AVTextStyleRule을 통한 자막 스타일 지정 지원이 도입되었습니다.
func selectAudioTrack(languageCode: String) {
guard let group = player.currentItem?
.asset.mediaSelectionGroup(forMediaCharacteristic: AVMediaCharacteristic.audible)
else { return }
for option in group.options {
if option.extendedLanguageTag?.hasPrefix(languageCode) == true {
player.currentItem?.select(option, in: group)
}
}
}
selectAudioTrack 메서드는 audible 그룹의 오디오 옵션 중에서 extendedLanguageTag가 원하는 언어 코드와 일치하는 변형을 검색합니다. 이를 통해 다국어 콘텐츠가 있는 앱에서 “원본 오디오” 기능을 구현할 수 있습니다.
Picture in Picture(PiP) 모드를 사용하면 다른 앱 위에 떠 있는 창에서 비디오를 표시할 수 있습니다. iPad에서는 iOS 9부터, iPhone에서는 iOS 14부터 이 기능을 사용할 수 있습니다. AVPlayerViewController는 UIBackgroundModes에 구독할 때 전송 바에 PiP 버튼을 자동으로 추가합니다.
PiP를 활성화하려면 Info.plist에 audio 및 airplay 값이 있는 UIBackgroundModes 키를 추가합니다. 그러면 컨트롤러에 PiP 버튼이 나타나며, 탭하면 비디오가 192x108 포인트의 떠 있는 창으로 축소됩니다.
PiP 이벤트는 델리게이트를 통해 처리됩니다: playerViewController(_:willStartPictureInPictureFromFullScreen:) 및 playerViewController(_:didStopPictureInPicture:). Apple HIG에 따르면 콘텐츠 가독성을 유지하려면 PiP 창의 최소 크기가 120x68 포인트 이상이어야 합니다.
자주 묻는 질문
아니요, YouTube 비디오는 웹 뷰 WKWebView 또는 YouTube iOS Helper 라이브러리를 사용해야 합니다. YouTube는 자체 DRM 시스템을 사용하기 때문입니다. AVPlayerViewController는 URL을 통한 직접 미디어 스트림용으로 설계되었습니다.
showsPlaybackControls 속성을 false로 설정합니다. 그러면 화면이 비어 있고 비디오 스트림만 남습니다. 사용자 지정 버튼을 다시 추가하려면 컨트롤러 위에 addSubview를 통해 오버레이를 추가합니다.
네, 컨트롤러는 HLS Live를 완전히 지원합니다. 전송 바에는 진행 슬라이더 대신 라이브 표시기가 표시됩니다. 지연 시간은 HLS 구성에 따라 다르며, 저지연 설정에서 최소 6초입니다.
AVPlayerItem.status 속성에서 KVO를 구독합니다. 오류가 발생하면 상태가 .failed로 변경됩니다. AVPlayerItem의 error 속성을 통해 세부 정보를 가져와 사용자에게 문제를 설명하는 알림을 표시합니다. 대부분 네트워크 문제나 잘못된 URL입니다.
네, 사용자 지정 AVAssetResourceLoader와 함께 AVAsset을 사용하여 RAM에서 데이터를 공급합니다. AVAssetResourceLoaderDelegate를 구현하고 디스크에서 읽는 대신 버퍼에서 바이트를 반환합니다.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.