AVPlayerはAppleのメディアプレーヤーフレームワークで、AVFoundationの一部であり、iOS、macOS、tvOS、visionOSでオーディオとビデオの再生を提供します。AVPlayerはローカルのMP4ファイルからアダプティブHLSストリームまで、Apple Siliconチップでのハードウェアアクセラレーションによるデコードを備えた統一APIを通じて幅広いフォーマットをサポートしています。Apple WWDC(2024)によると、AVPlayerはApple TV、Music、Photosを含む、メディアを扱うiOSアプリケーションの90%で使用されています。
重要ポイント
AVPlayerはAVFoundationフレームワークの中核コンポーネントであり、すべてのAppleプラットフォームでのマルチメディア再生を担当します。iOS 4.0(2010)で非推奨のMPMoviePlayerControllerの後継として導入されたAVPlayerは、デコードパラメータの微調整、オーディオとビデオの同期、AirPlayやPicture in Pictureなどのシステムサービスとの統合を備えた低レベルの再生制御を提供します。
サードパーティのプレーヤーとは異なり、AVPlayerはApple Siliconチップでのハードウェアアクセラレーションの利点を活かします。ビデオデコードは専用のMシリーズメディアエンジン(Media Engine)を使用してVideoToolboxを通じて実行され、最小限の消費電力で8K HDR再生を実現します。HEVC(H.265)およびProResの場合、デコードはCPUに負荷をかけずに専用のチップブロックで行われます。
AVPlayerはAppleエコシステムと緊密に統合されています:デバイス間で再生を転送するHandoffサポート、Apple TVへのストリーミングのためのAirPlay 2、ダイナミックヘッドトラッキング対応の空間オーディオ、MPNowPlayingInfoCenterを介したシステム制御要素との同期。これらの統合により、AVPlayerはAppleプラットフォームでメディアを扱うすべてのアプリケーションのデファクトスタンダードとなっています。
AVFoundationフレームワークは、再生のための3層階層を提供します:AVAsset(メタデータとコンテンツ情報)、AVPlayerItem(特定のコンテンツインスタンスの状態と管理)、AVPlayer(再生制御)。このアーキテクチャにより、メタデータの読み込み、再生準備、再生プロセス自体が分離され、複数のビットレートオプションを持つHLSストリームにとって特に重要です。
AVAssetはメディアコンテンツモデル(ファイルまたはストリーム)を表します。AVAsset自体は再生可能ではありません。トラック(AVAssetTrack)、メタデータ(commonMetadata)、再生時間情報などの特性を含みます。AVAssetからAVPlayerItemが作成され、それをAVPlayerに渡して再生できます。
AVPlayerは、単純なファイル再生からDRMを伴う複雑なライブ配信まで、ほとんどの再生シナリオをカバーする一連の機能を提供します。使用例とともに主な機能を見ていきましょう。
| 機能 | 説明 | プラットフォーム |
|---|---|---|
| ローカルファイル | MP4、MOV、M4V、AVI、MKV(拡張機能経由) | iOS、macOS、tvOS |
| HLS | アダプティブABR対応HTTP Live Streaming | すべてのAppleプラットフォーム |
| FairPlay DRM | ストリーミングライセンス付き保護HLSコンテンツ | iOS、tvOS、macOS |
| Picture in Picture | 他のアプリの上に浮かぶビデオウィンドウ | iPad、iPhone(iOS 14+)、Mac |
| AirPlay 2 | Apple TVやスピーカーへのワイヤレスストリーミング | すべてのプラットフォーム |
| 空間オーディオ | Dolby Atmosとダイナミックヘッドトラッキング | iOS 15+、macOS 13+ |
| HDR | Dolby Vision、HDR10、HLG(ディスプレイ対応) | iOS 11+、macOS 10.13+ |
AVPlayerは追加ライブラリを必要とせずネイティブでHLSをサポートします。HLSストリーム再生時、AVPlayerはAppleプラットフォーム向けに最適化されたビルトインABRアルゴリズムを使用して、自動的にアダプティブビットレート切替えを管理します。このアルゴリズムはネットワーク帯域幅だけでなく、デバイスの熱状態も考慮します — 過熱時には、AVPlayerはCPU負荷を下げるためにビットレートを低下させることがあります。
FairPlay Streamingを使用したHLSストリームの場合、AVPlayerはAVContentKeySessionデリゲートを介してライセンスの取得と更新を自動的に処理します。デベロッパーはAVContentKeySessionDelegateプロトコルを実装する必要があり、復号キーの取得または更新が必要なときにプレーヤーから呼び出されます。WidevineがiOSでサポートされていないため、これがAppleプラットフォームでHLSコンテンツを保護する唯一の方法です。
PiPは、アプリ間を切り替える際にユーザーがフローティングウィンドウでビデオを引き続き視聴できるモードです。iPadおよびiPhone(iOS 14+)では、AVPlayerはAVPictureInPictureControllerと統合してこのモードを有効にします。macOS 15+でもPiPは利用可能ですが、システムメニューまたはプレーヤーウィンドウのボタンからアクティブ化します。
AVPlayerをiOSアプリに統合する方法は2つあります:高レベルのAVPlayerViewControllerを使用する方法(標準的なシナリオ向け)と、AVPlayer + AVPlayerLayerを直接使用する方法(完全なUIカスタマイズ向け)です。Swiftで両方のアプローチを見ていきましょう。
AVPlayerViewControllerは、再生/一時停止、シーク、音量、AirPlay、PiP、全画面モードなどの組み込みコントロールを提供する既製のUIコンポーネントです。最小限の統合には数行のコードのみが必要です:AVPlayerインスタンスを作成し、AVPlayerViewControllerに渡して、コントローラーを画面に表示します。
import AVKit
let url = URL(string: "https://example.com/video.mp4")!
let asset = AVAsset(url: url)
let playerItem = AVPlayerItem(asset: asset)
let player = AVPlayer(playerItem: playerItem)
let controller = AVPlayerViewController()
controller.player = player
controller.allowsPictureInPicturePlayback = true
present(controller, animated: true) {
player.play()
}
カスタムUIのアプリには、AVPlayerLayer(任意のUIView内でビデオをレンダリングするCore Animationレイヤー)を使用します。このアプローチにより、インターフェースを完全に制御できます:カスタムコントロール、アニメーションの追加、ビデオ上への追加レイヤーのオーバーレイが可能です。
class VideoPlayerView: UIView {
var player: AVPlayer? {
get { (layer as! AVPlayerLayer).player }
set { (layer as! AVPlayerLayer).player = newValue }
}
override class var layerClass: AnyClass {
AVPlayerLayer.self
}
}
// 使用法:
let playerView = VideoPlayerView(frame: view.bounds)
playerView.player = AVPlayer(url: url)
view.addSubview(playerView)
適切なプレーヤーのライフサイクル管理はアプリの安定性にとって重要です。AVPlayerは画面が表示されたときに作成され、閉じられたときに解放されるべきです。アプリがバックグラウンドに移行するときは、リソースを節約し、不必要なバックグラウンド再生によるApp Reviewのペナルティを避けるために、再生を一時停止することを推奨します。
AVPlayerLayerはCALayerを継承するCore Animationレイヤーで、画面上にビデオをレンダリングします。UIViewとは異なり、AVPlayerLayerはMetalまたはOpenGLを介してGPUと直接動作し、最小限のフレーム出力遅延を実現します。カスタム再生インターフェースを実装するには、AVPlayerLayerの理解が不可欠です。
videoGravityプロパティは、ビデオがレイヤー境界内にどのように収まるかを決定します。AVLayerVideoGravity.resizeAspect(黒帯でアスペクト比を維持)はAVPlayerViewControllerのデフォルトです。resizeAspectFill(トリミングで画面全体を埋める)は全画面モードで使用されます。resize(レイヤーサイズに合わせて歪める)はほとんど使用されず、主に分析アプリケーションで使用されます。
AVPlayerLayerはリアルタイムでビデオをレンダリングしますが、すべてのプレーヤー操作(開始、一時停止、シーク)はメインスレッドで実行する必要があります。監視対象の主要な値(timeControlStatus、rate、status、error)は、KVO(Key-Value Observing)またはiOS 16でSwift Concurrency対応のAVPlayerメソッドとして導入された最新のasync/await APIを介して追跡されます。
let player = AVPlayer(url: url)
let statusObservation = player.observe(
\.status,
options: [.new, .initial]
) { player, _ in
switch player.status {
case .readyToPlay:
player.play()
case .failed:
handleError(player.error)
default:
break
}
}
AVPlayerはVTT、CEA-608、ITT(iTunes Timed Text)形式の埋め込み字幕をサポートします。オーディオトラックと字幕の選択は、AVMediaSelectionGroupとAVMediaSelectionOptionを介して行われます。ユーザーの字幕設定(フォント、サイズ、色)はシステムのアクセシビリティ設定から読み取られ、コードで明示的に指定されない限り、自動的にAVPlayerLayerに適用されます。
本番アプリケーションでは、基本的なAVPlayer統合に加えて、HLSセグメントキャッシュ、FairPlay DRM統合、Now Playingシステム統合、カスタムビットレート選択アルゴリズムなどの追加設定が必要になることがよくあります。
AVAssetResourceLoaderはHLSセグメントの読み込みをインターセプトしてキャッシュを実装する唯一の方法です。AVAssetResourceLoaderDelegateはキーとセグメントの読み込みリクエストを受け取り、それらをローカルに保存し、後続のリクエストでキャッシュから返すことができます。これは不安定なネットワーク環境で動作するアプリケーションにとって特に有用です。
let asset = AVURLAsset(url: hlsURL)
asset.resourceLoader.setDelegate(
resourceLoaderDelegate,
queue: DispatchQueue(label: "com.app.resourceloader")
)
let playerItem = AVPlayerItem(asset: asset)
FairPlay Streaming(FPS)はHLSコンテンツを保護するためのAppleの標準です。FPSを統合するには、復号キーのリクエストを処理するAVContentKeySessionDelegateプロトコルを実装する必要があります。プロセスには、プレーヤーからSPC(Server Playback Context)を取得し、ライセンスサーバーに送信し、CKC(Content Key Context)を受信してAVContentKeySessionに返すことが含まれます。
class DRMDelegate: NSObject, AVContentKeySessionDelegate {
func contentKeySession(
_ session: AVContentKeySession,
didProvide keyRequest: AVContentKeyRequest
) {
// 1. keyRequestからSPCを取得
// 2. SPCをライセンスサーバーに送信
// 3. CKCを取得してkeyRequest.processContentKeyResponseに渡す
}
}
ロック画面、コントロールセンター、Apple Watchに現在の再生情報を表示するには、MediaPlayer.frameworkのMPNowPlayingInfoCenterを使用します。AVPlayerは自動的にNow Playingを更新しません — デベロッパーは再生状態が変化したときに手動でメタデータ(タイトル、アーティスト、アートワーク、進行状況)を設定する必要があります。進行状況の更新には、定期的なタイマーまたはobserve(\.timeControlStatus)が使用されます。
Remote Command Centerは、ロック画面、AirPods、CarPlayから再生を制御できるもう1つのシステムサービスです。MPRemoteCommandCenterは、play、pause、nextTrack、previousTrack、changePlaybackPosition、skipForward/skipBackwardコマンドのハンドラーを登録します。AVPlayerはこれらのコマンドを自動的に処理しません — デベロッパーはそれらをplayer.play()、player.pause()、player.seek()の呼び出しに接続する必要があります。
よくある質問
AVPlayerはストリーミング、HLS、DRM、システムコントロールとの同期をサポートするユニバーサルなオーディオおよびビデオプレーヤーです。AVAudioPlayerはストリーミングやハードウェアビデオアクセラレーションをサポートしない、ローカルオーディオファイル再生のための簡易オーディオプレーヤーです。ビデオとHLSにはAVPlayerを、シンプルなオーディオにはAVAudioPlayerを使用してください。
いいえ、AVPlayerはYouTubeコンテンツの直接読み込みをサポートしていません。YouTubeはDASHと独自形式に基づく独自のプレーヤーを使用しているためです。iOSアプリにYouTubeを統合するには、WKWebViewまたは公式のyoutube-ios-player-helperライブラリを介してYouTube IFrame Player APIを使用してください。
バックグラウンドオーディオの場合、XcodeプロジェクトのBackground ModesにAudio、AirPlay and Picture in Pictureを追加します。AVAudioSessionを.playbackカテゴリで設定します:try AVAudioSession.sharedInstance().setCategory(.playback)。AVPlayerはバックグラウンドで再生を続け、ロック画面とコントロールセンターはMPNowPlayingInfoCenterを介してコントロールを表示します。
これらのサービスはDRM保護と独自のプレーヤーソリューションを使用しています。AVPlayerは直接のメディアファイルURLまたはHLSプレイリストを介してのみコンテンツを再生できます。YouTubeや類似プラットフォームのビデオは、AVPlayerと互換性のないiframeやJavaScriptプレーヤーでラップされています。表示には公式SDKまたはWebViewを使用してください。
低遅延HLSの場合、AVPlayerItemをpreferredForwardBufferDuration = 2.0(秒)で設定し、ライブエッジから遅れたときに自動的に一時停止を管理します:player.currentItem?.configuredTimeOffsetFromLiveとplayer.currentItem?.canPlayReverseを使用します。Appleはサーバーとクライアントの両方で適切に設定された場合、2〜4秒の遅延でLL-HLSを推奨しています。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。