AVFoundationプログラミングガイド-再生



Avfoundation Programming Guide Playback



再生

リソースの再生を制御するには、AVPlayerオブジェクト。再生中に、あなたは使用することができますAVPlayerItemインスタンスリソース全体のプレゼンテーションステータスを管理しますそして使用するAVPlayerItemTrackオブジェクトが来る単一のトラックのプレゼンテーションステータスを管理します欲しいですビデオを見る、使ってくださいAVPlayerLayerオブジェクト。



1.アセットの再生 ((リソースを再生する)。

プレーヤーは、再生の開始と停止、特定の時間の検索など、アセットの再生を管理するために使用されるコントローラーオブジェクトです。あなたが使うAVPlayerのインスタンス単一のリソースを再生するあなたはそれを使うことができますAVQueuePlayerオブジェクト順番に複数のリソースを再生する((AVQueuePlayerはAVPlayerのサブクラスです)。OS Xでは、AVKitフレームワークのAVPlayerViewクラスを使用して、ビュー内のコンテンツを再生することを選択できます。

プレーヤーはあなたに提供します再生ステータス情報、必要に応じて、ユーザーインターフェイスをプレーヤーの状態と同期します通常、プレーヤーの出力を専用に送信しますCore Animation(Core Animation)床(AVPlayerLayerまたはAVSynchronizedLayerインスタンス)。レイヤーの詳細については、を参照してください。 CoreAnimationプログラミングガイド 。。




最終的にはリソースをプレイしたいのですが、直接利用できませんリソースAVPlayerオブジェクトを与える 対照的に 、あなたが提供したAVPlayerItemのインスタンスプレーヤーアイテムは、関連するリソースの表示ステータスを管理します。プレイヤーアイテムリソース内のトラックに対応するプレーヤーアイテムトラック(AVPlayerItemTrackのインスタンス)が含まれます。さまざまなオブジェクト間の関係を図2-1に示します。




この抽象的な概念は、異なるプレーヤーを使用して特定のリソースを同時に再生できることを意味しますが、各プレーヤーは異なる方法でリソースを提示できます。図2-2は、1つの可能性を示しています。2人の異なるプレーヤー使用するさまざまな設定演奏する同じリソースたとえば、アイテムトラックを使用すると、再生中に特定のオーディオトラックを無効にできます(たとえば、サウンドコンポーネントを再生したくない場合があります)。


既存のリソースを使用してプレーヤーアイテムを初期化することも、URLから直接プレーヤーアイテムを初期化することもできます。特定の場所でリソースを再生する((AVPlayerItemは、リソースのリソースを作成および構成します)。ただし、AVAssetのように、プレーヤーアイテムを初期化するだけでは、必ずしもすぐに再生できるとは限りません。アイテムを(キー値監視を使用して)監視できます状態((状態属性)かどうかを判断するにはプレイする準備ができましたそして、いつプレイする準備ができていますか。

2.さまざまな種類の資産の処理(さまざまな種類のリソースの処理)。

再生用にリソースを構成する方法は、再生するリソースのタイプによって異なる場合があります。一般的に言えば、2つの主なタイプがあります。ファイルベースのリソース(ランダムにアクセスできます(例:ローカルファイルカメラロールまたはメディアライブラリ)とストリームベースのリソース((HTTPライブストリーミング形式))。
ファイルベースのリソースをロードして再生するファイルベースのリソースを再生するには、いくつかの手順があります。1>。AVURLAssetを使用してリソースを作成します。 2>。リソースを使用して、AVPlayerItemのインスタンスを作成します。 3>。アイテムをAVPlayerのインスタンスに関連付けます。4>。アイテムのステータス属性が準備ができていることを示すまで待ち​​ます(通常、ステータスが変更されると、Key-Value監視を使用して通知を受信します)。
概要:すべてをまとめると、このアプローチがわかります:AVPlayerLayerを使用してビデオファイルを再生します。

再生用のHTTPライブストリーミングを作成して準備します。使用するAVPlayerItemを初期化するためのURLインスタンス。(君はHTTPライブストリームでメディアを表すAVAssetインスタンスを直接作成することはできません。)

NSURL *url = [NSURL URLWithString:@'] // You may find a test stream at . self.playerItem = [AVPlayerItem playerItemWithURL:url] [playerItem addObserver:self forKeyPath:@'status' options:0 context:&ItemStatusContext] self.player = [AVPlayer playerWithPlayerItem:playerItem]

playerItemをプレーヤーに関連付けると、プレーヤーはプレイする準備が整います。プレイする準備ができると、プレイヤーアイテムが作成されますAVAssetAVAssetTrackインスタンス、あなたそれらを使用して、ライブストリームのコンテンツを確認できます
ストリーミングメディアアイテムの継続時間を取得するには、プレーヤーアイテムの継続時間属性を確認できます。 アイテムを再生する準備ができると、この属性はストリームの正しい値に更新されます。

注意 :使用するプレイヤーアイテムの持続時間プロパティにはiOS4.3以降が必要です。iOSのすべてのバージョンと互換性のある方法では、プレーヤーアイテムのステータス属性を監視する必要があります。ステータスがAVPlayerItemStatusReadyToPlayに変わると、次のコード行で期間を取得できます。

[[[[[playerItem tracks] objectAtIndex:0] assetTrack] asset] duration]ライブストリームを再生したいだけの場合は、次のコードを使用してショートカットを作成し、URLを使用してプレーヤーを直接作成できます。

self.player = [AVPlayer playerWithURL:] [player addObserver:self forKeyPath:@'status' options:0 context:&PlayerStatusContext] リソースやアイテムと同様に、プレーヤーを初期化しても、プレイする準備ができているとは限りません。プレーヤーの status ステータス属性を確認する必要があります。この属性は、再生の準備ができるとAVPlayerStatusReadyToPlayに変更されます。currentItemプロパティを監視して、ストリーム用に作成されたプレーヤーアイテムにアクセスすることもできます。

お持ちのURLの種類がわからない場合は、以下の手順に従ってください。

1>。AVURLAssetをURLで初期化してから、そのキートラックをロードしてみてください。トラックが正常に読み込まれると、リソース用のプレーヤーアイテムが作成されます。

2>。1が失敗した場合は、URLから直接AVPlayerItemを作成してください。プレーヤーのステータス属性を観察して、プレーヤーがプレイできるかどうかを判断します。

いずれかのルートが成功すると、最終的にプレイヤーアイテムを取得し、それをプレイヤーに関連付けることができます。

3.アイテムの再生(アイテムを再生する)。

再生を開始するには、再生メッセージをプレーヤーに送信します
- (IBAction)play:sender { [player play] }単純な再生に加えて、再生ヘッドなど、再生のすべての側面を管理することもできます割合ポジションあなたもすることができますモニタープレーヤー再生ステータスたとえば、ユーザーインターフェイスの状態をリソースの状態と同期させる場合は、を参照してください。再生の監視((再生を監視する)。

4.再生速度の変更(再生速度を変更する)。

プレーヤーのレート属性を設定して、再生レートを変更します。

aPlayer.rate = 0.5 aPlayer.rate = 2.01.0の値は、「現在のアイテムの自然な速度で再生する」ことを意味します。レートを0.0に設定することは、再生を一時停止することと同じです。一時停止を使用することもできます。

逆再生をサポートするアイテムは負の利率を使用する設定するプロパティ逆再生レートあなたが使用することができますplayerItem属性canPlayReverse(-1.0レート値をサポート)、canPlaySlowReverse(0.0〜-1.0のサポート率)およびcanPlayFastReverse(-1.0未満のサポート率の値)からサポートされている逆再生のタイプを決定します

五。シーク—再生ヘッドの再配置(再生ヘッドを見つけて再配置します)。

再生ヘッドを特定の時間に移動するには、通常、seekToTime:次のように:

CMTime fiveSecondsIn = CMTimeMake(5, 1) [player seekToTime:fiveSecondsIn] ただし、seekToTime:メソッドは精度ではなく、パフォーマンスを調整するの。必要な場合再生ヘッドを正確に動かす、次のコードスニペットに示すように、seekToTime:toleranceBefore:toleranceAfter:を使用してください。

CMTime fiveSecondsIn = CMTimeMake(5, 1) [player seekToTime:fiveSecondsIn toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero]ゼロトレランスを使用すると、フレームが大量のデータをデコードする必要がある場合があります。たとえば、ゼロは、正確な制御を必要とする複雑なメディア編集アプリケーションを作成する場合にのみ使用する必要があります。再生後、プレーヤーの頭はアイテムの最後に設定され、それ以上の再生呼び出しは機能しません。再生ヘッドをアイテムの先頭に戻すには、アイテムから受け取るように登録できますAVPlayerItemDidPlayToEndTimeNotification通知。通知のコールバックメソッドでは、パラメータを使用しますkCMTimeZero転送seekToTime:。

// Register with the notification center after creating the player item. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerItemDidReachEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:<#The player item#>] - (void)playerItemDidReachEnd:(NSNotification *)notification { [player seekToTime:kCMTimeZero] }

6.複数のアイテムを再生する(複数のアイテムを再生する)

あなたはそれを使うことができますAVQueuePlayerオブジェクトは複数のアイテムを順番に再生します。AVQueuePlayerクラスは、AVPlayerのサブクラスです。プレーヤーアイテム配列を使用して、キュープレーヤー
NSArray *items = AVQueuePlayer *queuePlayer = [[AVQueuePlayer alloc] initWithItems:items]その後、あなたは使用することができます演奏するAVPlayerオブジェクトを使用するのと同じように、キューを再生するメソッド。キュープレーヤーは各リソースを順番に再生します。次に再生するアイテムにスキップする場合は、キュープレーヤーにアイテムを送信しますAdvanceToNextItemニュース。insertItem:afterItem:、removeItem :、およびremoveAllItemsメソッドを使用できますキューを変更する通常、新しいアイテムを追加するときは、canInsertItem:afterItem:を使用して、キューに挿入できるかどうかを確認する必要があります。 2番目のパラメーターとしてnilを渡して、新しいアイテムをキューに追加できるかどうかをテストします。
AVPlayerItem *anItem = <#Get a player item#> if ([queuePlayer canInsertItem:anItem afterItem:nil]) { [queuePlayer insertItem:anItem afterItem:nil] }

セブン。再生の監視(再生を監視する)。

プレイヤーの表示状態や、プレイ中のプレイヤーアイテムのさまざまな側面を監視できます。これは、直接制御されていない状態を変更する場合に特に便利です。次に例を示します。

1>ユーザーがマルチタスクを使用して別のアプリケーションに切り替えると、プレーヤーのレート属性は0.0に下がります。 …

2>。リモートメディアを再生している場合、より多くのデータが利用可能になると、プレーヤーアイテムのloadedTimeRangesプロパティとseekableTimeRangesプロパティが変更されます。これらの属性はあなたに教えてくれますプレイヤーアイテムタイムラインのどの部分が利用可能か。

3>。いつプレイヤーアイテムHTTPライブストリームとして作成され、プレーヤーの currentItem 属性が変更されました。

4>。HTTPリアルタイムストリームが再生されると、プレーヤーアイテムのトラック属性が変更される場合があります。これは、ストリームがコンテンツに異なるエンコーディングを提供する場合に発生する可能性がありますプレーヤーが別のエンコーディングに切り替えると、トラックが変更されます。 …

5>。なんらかの理由で再生に失敗した場合、プレーヤーまたはプレイヤーアイテムのステータス属性は変更される可能性があります。キーオブザベーションを使用して、これらのプロパティ値の変更を監視できます。

重要なヒント :メインスレッドでKVO変更通知に登録し、KVO変更通知の登録を解除する必要があります。これにより、別のスレッドが変更を行っているときに部分的な通知を受信する可能性が回避されます。AV Foundationは、変更操作が別のスレッドで実行されている場合でも、メインスレッドでobserveValueForKeyPath:ofObject:change:context:を呼び出します。

8.ステータスの変化への対応(状態変化への対処)。

プレイヤーまたはプレイヤーアイテムのステータスが変更されると、キー値観測の変更の通知が送信されます。何らかの理由でオブジェクトを再生できない場合(メディアサービスがリセットされた場合など)、状況に応じて、ステータスがAVPlayerStatusFailedまたはAVPlayerItemStatusFailedに変わります。この場合、オブジェクトのエラー属性の値は、オブジェクトを再生できない理由を説明するエラーオブジェクトに変更されます。

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if (context == ) { AVPlayer *thePlayer = (AVPlayer *)object if ([thePlayer status] == AVPlayerStatusFailed) { NSError *error = [ error] // Respond to error: for example, display an alert sheet. return } // Deal with other status change if appropriate. } // Deal with other change notifications if appropriate. [super observeValueForKeyPath:keyPath ofObject:object change:change context:context] return }

9.ビジュアルディスプレイの準備状況の追跡((ビジュアルディスプレイ追跡の準備ができました)。

レイヤーにユーザーに表示されるコンテンツがあると、AVPlayerLayerオブジェクトのreadyForDisplayプロパティに通知されることがわかります。、特に、ユーザーが表示して変換を実行するための何かがある場合にのみ、プレーヤーレイヤーをレイヤーツリーに挿入できます。

AVPlayerオブジェクトの再生ヘッド位置の変更を追跡するには、addPeriodicTimeObserverForInterval:queue:usingBlock:またはaddBoundaryTimeObserverForTimes:queue:usingBlock:を使用できます。 たとえば、これを実行して、経過時間または残り時間に関する情報でユーザーインターフェイスを更新したり、他のユーザーインターフェイスの同期を実行したりできます。

10.追跡時間(追跡時間)。

AVPlayerオブジェクトの再生ヘッド位置の変更を追跡するには、addPeriodicTimeObserverForInterval:queue:usingBlock:またはaddBoundaryTimeObserverForTimes:queue:usingBlock:を使用できます。たとえば、あなたはすることができます経過時間または残り時間に関する情報でユーザーインターフェイスを更新します、または他のユーザーインターフェイスの同期を実行する

1>。addPeriodicTimeObserverForIntervalを使用します:queue:usingBlock:when、時間がジャンプして再生が開始または停止した場合、指定した時間間隔で指定したブロックが呼び出されます。

2>。addBoundaryTimeObserverForTimes:queue:usingBlock:を使用する場合、NSValueオブジェクトに含まれるCMTime構造体配列を渡します。あなたがいつでもトラバースするときはいつでも、あなたが提供するブロックが呼び出されます。 、

これらのメソッドは両方とも、オブザーバーとして不透明なオブジェクトを返します。プレーヤーに時間観測ブロックを呼び出させたい限り、返されたオブジェクトへの強力な参照を維持する必要があります。また、これらのメソッドの各呼び出しと、対応するremoveTimeObserver:呼び出しのバランスをとる必要があります。

これらの2つの方法を使用すると、AVFoundationはブロックを時々呼び出すことを保証しません。以前に呼び出されたブロックの実行が完了していない場合、AVFoundationはブロックを呼び出しません。したがって、この領域で実行する作業がシステムに負担をかけないようにする必要があります。

// Assume a property: @property (strong) id playerObserver Float64 durationSeconds = CMTimeGetSeconds([ duration]) CMTime firstThird = CMTimeMakeWithSeconds(durationSeconds/3.0, 1) CMTime secondThird = CMTimeMakeWithSeconds(durationSeconds*2.0/3.0, 1) NSArray *times = @[[NSValue valueWithCMTime:firstThird], [NSValue valueWithCMTime:secondThird]] self.playerObserver = [ addBoundaryTimeObserverForTimes:times queue:NULL usingBlock:^{ NSString *timeDescription = (NSString *) CFBridgingRelease(CMTimeCopyDescription(NULL, [self.player currentTime])) NSLog(@'Passed a boundary at %@', timeDescription) }]

11. AVPlayerLayerを使用してビデオファイルを再生する(AVPlayerLayerを使用してビデオファイルを再生する)。

1>。 AVPlayerLayerレイヤーを使用するようにビューを構成します

2>。 AVPlayerオブジェクトを作成します

3>。ファイルベースのリソース用のAVPlayerItemオブジェクトを作成し、Key-Value監視を使用してそのステータスを監視します

4>。ボタンを有効にしてこれに応答します項目プレイする準備ができました

5>。これを再生項目、そしてプレイヤーの頭を最初に戻します。

12.プレーヤービュー(プレイヤービュー)。

アセットのビジュアルコンポーネントを再生するには、AVPlayerオブジェクトの出力を送信できるAVPlayerLayerレイヤーを含むビューが必要です。この状況に対応するために、単純なUIViewサブクラスを作成できます。

#import #import @interface PlayerView : UIView @property (nonatomic) AVPlayer *player @end @implementation PlayerView + (Class)layerClass { return [AVPlayerLayer class] } - (AVPlayer*)player { return [(AVPlayerLayer *)[self layer] player] } - (void)setPlayer:(AVPlayer *)player { [(AVPlayerLayer *)[self layer] setPlayer:player] } @end

13.シンプルなビューコントローラー

次のように宣言された単純なViewControllerがあるとします。

@class PlayerView @interface PlayerViewController : UIViewController @property (nonatomic) AVPlayer *player @property (nonatomic) AVPlayerItem *playerItem @property (nonatomic, weak) IBOutlet PlayerView *playerView @property (nonatomic, weak) IBOutlet UIButton *playButton - (IBAction)loadAssetFromFile:sender - (IBAction)play:sender - (void)syncUI @endsyncUIメソッドは、ボタンの状態をプレーヤーの状態と同期します。- (void)syncUI { if ((self.player.currentItem != nil) && ([self.player.currentItem status] == AVPlayerItemStatusReadyToPlay)) { self.playButton.enabled = YES } else { self.playButton.enabled = NO } } ビューコントローラのviewDidLoadメソッドでsyncUIを呼び出して、ビューが最初に表示されたときに一貫したユーザーインターフェイスを確保できます。- (void)viewDidLoad { [super viewDidLoad] [self syncUI] }このセクションの残りの部分では、他のプロパティとメソッドを紹介します。

14.アセットの作成

AVURLAssetを使用して、URLからリソースを作成できます。(次の例では、プロジェクトに適切なビデオリソースが含まれていることを前提としています。)- (IBAction)loadAssetFromFile:sender { NSURL *fileURL = [[NSBundle mainBundle] URLForResource: withExtension:] AVURLAsset *asset = [AVURLAsset URLAssetWithURL:fileURL options:nil] NSString *tracksKey = @'tracks' [asset loadValuesAsynchronouslyForKeys:@[tracksKey] completionHandler: ^{ // The completion block goes here. }] }完了ブロックで、リソースのAVPlayerItemインスタンスを作成し、それをプレーヤービューのプレーヤーとして設定します。リソースの作成と同様に、プレーヤーアイテムを作成するだけでは、すぐに使用できるわけではありません。いつ再生できるかを判断するために、アイテムのステータス属性を確認できます。プレーヤーアイテムインスタンスをプレーヤー自体に関連付ける前に、この監視を構成する必要があります。あなたが置くときプレイヤーアイテムプレーヤーに接続すると、トリガーしますプレイヤーアイテム準備。
// Define this constant for the key-value observation context. static const NSString *ItemStatusContext // Completion handler block. dispatch_async(dispatch_get_main_queue(), ^{ NSError *error AVKeyValueStatus status = [asset statusOfValueForKey:tracksKey error:&error] if (status == AVKeyValueStatusLoaded) { self.playerItem = [AVPlayerItem playerItemWithAsset:asset] // ensure that this is done before the playerItem is associated with the player [self.playerItem addObserver:self forKeyPath:@'status' options:NSKeyValueObservingOptionInitial context:&ItemStatusContext] [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerItemDidReachEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.playerItem] self.player = [AVPlayer playerWithPlayerItem:self.playerItem] [self.playerView setPlayer:self.player] } else { // You should deal with the error appropriately. NSLog(@'The asset's tracks were not loaded: %@', [error localizedDescription]) } })