AVPlayerについて調べた - iOS
AVPlayer周りのドキュメントを読んだので、
AVAsset
、AVPlayerItem
、AVPlayer
について書いてあること自分に分かりやすいように書き起こしました。
動画をViewに反映する方法については詳しく書いていませんので、ご了承ください。
読んだもの
AVFoundation
- audiovisual assets
- control device cameras
- process audio
- system audio interactions
Media Assets, Playback, and Editing
- media assetsにアクセス
- mediaの再生(再生をカスタマイズ)
- mediaの編集や結合
- import and export raw media streams
Asset Modelについて
Media Playback Programming Guide
AVAsset
- 単一のメディアリソースを表す抽象的で不変の型(abstract, immutable type)
- ローカルファイルだけでなく、プログレッシブダウンロードされたもの、HLSを使用してストリーミングされたものも表せる
- formatを気にせずに扱えるようにする
- locationを気にせず扱えるようにする(URLを用いてイニシャライズ)
- AVAssetはAVAssetTrackのコンテナオブジェクト
AVAssetTrack扱っている種類
- video
- audio
- subtitles
- caption
- timed metadata
Overview
let url: URL = // Local or Remote Asset URL let asset = AVAsset(url: url)
実際にはAVURLAssetと言う具象サブクラスが生成される。
Wi-Fi下のみでのリソースのダウンロード
等のオプションを付けたい時はAVURLAsset.init(url:option:)を使用する。
他にもAVComposition等でイニシャライズすることも可能。
リソースによっては、初期化が完了しても即時に再生できないものもある。再生を要求することはいつでも出来るが、そのためには呼び出し元のスレッドを止める必要があるかもしれない。
そのブロッキングを避けるために、AVAsynchronousKeyValueLoadingを使って完了通知を受けるように登録することができる。
AVAssetを再生するには、AVPlayerItemを生成してAVPlayerを使って再生する。
AVAssetオブジェクトをAVMutableCompositionオブジェクトに挿入することで、1つ以上のAssetからaudiovisual構造を組み立てることができる。
Topics
⚠️必要そうなものだけをピックアップしました。
生成方法
init(url: URL)
ローディングデータ
func cancelLoading()
全てのロードを中断する。
Assetについて
var duration: CMTime
assetの再生時間(CMTimeについて)
AVPlayerItem
Overview
ざっくり言うとAVAssetにロードされたかどうかのStatus情報が付属されたもの。
これを渡してAVPlayer
に再生してもらう。
init(url: URL) init(asset: AVAsset)
上記のイニシャライザに加えて、事前にロードを開始する
init(asset: AVAsset, automaticallyLoadedAssetKeys: [String]?)
がある。
Topics
生成方法
init(url: URL) init(asset: AVAsset) init(asset: AVAsset, automaticallyLoadedAssetKeys: [String]?)
その他
var status: AVPlayerItem.Status
.readyToPlay
, .unknown
, .failed
がある。
var loadedTimeRanges: [NSValue]
ロード済みの部分のタイムレンジ
var seekableTimeRanges: [NSValue]
シーク可能な部分のタイムレンジ
func seek(to: CMTime, completionHandler: ((Bool) -> Void)
シーク
func currentTime() -> CMTime
再生されている現在の時間
var presentationSize: CGSize
videoの場合にplayer
に提示される表示サイズの比率
AVPlayer
Overview
media assetの再生、タイミング調整を管理するコントローラオブジェクト。
1度に1media assetしか再生できないため、Player
を再利用するならreplaceCurrentItem(with:)
メソッドを使う。(AVQueuePlayerというものもあるが、便利ではないので使わない...)
AVPlayer
は連続的に状態が変化する動的オブジェクトである。Playerの状態を監視するには二つの方法がある。
一般的な方法
Key-value observing(KVO)を用いて、再生中のアイテムや再生速度などを監視できる。
その際にはobserveValue(forKeyPath:of:change:context:)
メソッドを用いる。
時間の変化による監視方法
ある一定時間が経過した時に特定の処理を実行するようにできる。
addPeriodicTimeObserver(forInterval:queue:using:)
特定の時間間隔ごとに処理を実行する。
addBoundaryTimeObserver(forTimes:queue:using:)
特定の時間が経過した時に処理を実行する。
Viewへの反映方法
AVPlayerは非視覚的オブジェクトであり、スクリーンに動画を反映することはできない。
スクリーンに反映する方法は主に二つある。
AVKitを用いた方法
AVKit
にあるAVPlayerViewControllerを用いて表示を行う。(AVPlayerViewはmacOSのみ)
AVPlayerLayerを用いた方法
AVPlayerLayerを用いて表示を行う。
AVPlayerViewControllerのようにコントローラのViewは無いので、自前で設定する必要がある。
Topics
生成方法
init(url: URL) init(playerItem: AVPlayerItem?)
再生管理
func play() func pause()
言わずもがな。
var rate: Float
再生速度。(rate = 0
⇔pause()
)
var actionAtItemEnd: AVPlayer.ActionAtItemEnd
再生が終わった時にどうするか。.advance
, .pause
, .none
がある。
func replaceCurrentItem(with: AVPlayerItem?)
再生するAVPlayerItem
を変更する。
var preventsDisplaySleepDuringVideoPlayback: Bool
動画再生中に画面スリープするかどうか。
時間
func seek(to: CMTime) func seek(to: CMTime, completionHandler: ((Bool) -> Void)
シーク
func currentTime() -> CMTime
再生されている現在の時間
func addPeriodicTimeObserver(forInterval: CMTime, queue: DispatchQueue?, using: (CMTime) -> Void) -> Any func addBoundaryTimeObserver(forTimes: [NSValue], queue: DispatchQueue?, using: () -> Void) -> Any
監視する系
func removeTimeObserver(Any)
監視を外す