AVFoundation Programming Guide-Playback,

Source: Internet
Author: User
Tags notification center

AVFoundation Programming Guide-Playback,

Playback

To control resource playback, use the AVPlayer object. During playback, you can use the AVPlayerItem instance to manage the rendering status of the entire resource and use the AVPlayerItemTrack object to manage the rendering status of a single track. To display a video, use the AVPlayerLayer object.

Playing Assets(Playback resources)

A player is a controller object used to manage asset playback, such as starting and stopping playback and searching for a specific time. You use an AVPlayer instance to play a single resource. You can use the AVQueuePlayer object to play multiple resources in sequence (AVQueuePlayer is a subclass of AVPlayer ). On OS X, you can use the AVPlayerView class of the AVKit framework to play content in the view.

The player provides you with information about the playback status. Therefore, you can synchronize the user interface with the player status if necessary. You usually direct the player output to a dedicated Core Animation layer (AVPlayerLayer or AVSynchronizedLayer instance ).

Although you finally want to play a resource, you do not directly provide the resource to the AVPlayer object.OppositeYou provide AVPlayerItem instances. A player item manages the presentation status of associated resources. A player item contains an instance of the player item track-AVPlayerItemTrack-corresponding to the track in the resource. The relationship between objects is 2-1.

This abstract concept means that you can use different players to play a given resource at the same time, but each player can be presented in different ways. Figure 2-2 shows the possibility that two different players use different settings to play the same resource. Use the item track. For example, you can disable a specific audio track during playback (for example, you may not want to play the sound component ).

You can use existing resources to initialize the player item, or you can initialize the player item directly from the URL, in this way, you can play resources at specific locations (AVPlayerItem will create and configure resources for resources ). However, like AVAsset, initializing a player item does not necessarily mean that it can be played immediately. You can observe the status (status attribute) of an item to determine whether to prepare and when to prepare for playback.

Handling Different Types of Asset (processing Different Types of resources)

The way you configure resources for playback may depend on the type of resources you want to play. Generally, there are two main types: file-based resources (such as local files, camera films, or media libraries) and stream-based resources (HTTP Live Streaming format )).
Load and play file-based resources. There are several steps to play a file-based resource: 1>. Use AVURLAsset to create a resource. 2>. use resources to create AVPlayerItem instances. 3>. Associate the item with the AVPlayer instance. 4>. Wait until the item state attribute indicates that it is ready (normally, when the state changes, you will use the key value observation to receive notifications ).
Summary: This method is illustrated by combining all of this: Using AVPlayerLayer to play a video file.
Create and prepare an HTTP live stream for playback. Use the URL to initialize the AVPlayerItem instance. (You cannot directly create an AVAsset instance to represent the media in the HTTP real-time stream .)

NSURL *url = [NSURL URLWithString:@"<#Live stream URL#>];// 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];
 

When you associate playerItem with the player, the player starts to prepare for playing. When player item is ready for playing, it creates AVAsset and AVAssetTrack instances, which you can use to check the content of real-time streams.
To obtain the duration of the streaming media item, you can observe the duration Attribute of the player item. When the item is ready for playback, this attribute is updated to the correct value of the stream.

Note:: To use the duration Attribute of player item, iOS 4.3 or later is required. The method compatible with all versions of iOS involves observing the status attribute of the player project. When the status changes to AVPlayerItemStatusReadyToPlay, the duration can be obtained using the following code:

[[[[[playerItem tracks] objectAtIndex:0] assetTrack] asset] duration];
If you only want to play real-time streams, you can use the following code to create a shortcut and create a player using a URL:
self.player = [AVPlayer playerWithURL:<#Live stream URL#>];[player addObserver:self forKeyPath:@"status" options:0 context:&PlayerStatusContext];
Like resources and items, initializing a player does not mean that it is ready to play. You should observe Status attribute, Which is changed to AVPlayerStatusReadyToPlay during preparation. You can also observe the currentItem attribute to access the player item created for the stream.

If you do not know which type of website you have, follow these steps: 1>. try to use URL to initialize AVURLAsset and load its key track. If the track is loaded successfully, create a player item for the resource. 2>. If 1 fails, create an AVPlayerItem from the URL directly, and observe the status attribute of the player to determine whether it can be played.

If any route is successful, you will eventually get a player item, and you can associate it with a player.

Playing an Item (play an item) To start playing, send the playback information to the player.
- (IBAction)play:sender {    [player play];}

In addition to simple playback, you can also manage all aspects of playback, such as the speed and position of the playback header. You can also listen to the Playback status of the player. For example, if you want to synchronize the status of the user interface with the status of the resource, see Monitoring Playback (Monitoring Playback ).

Changing the Playback Rate (Changing the Playback speed)

You can set the player speed attribute to change the playback speed.

aPlayer.rate = 0.5;aPlayer.rate = 2.0;
If the value is 1.0, it means "playing at the current item's natural speed ". Set the speed to 0.0, which is the same as paused playback. You can also use paused playback.

Items that support reverse playback can use the rate attribute of a negative number to set the reverse playback rate. You can use the playerItem attribute canPlayReverse (supports-1.0 rate values), canPlaySlowReverse (supports rates between 0.0 and-1.0), and canPlayFastReverse (supports rate values smaller than-1.0) to determine the supported reverse playback type.

Seeking-Repositioning the Playhead)

To move the playback header to a specific time, seekToTime is usually used as follows:

CMTime fiveSecondsIn = CMTimeMake(5, 1);[player seekToTime:fiveSecondsIn];
However, seekToTime: The method adjusts performance rather than accuracy. To precisely move the playback header, use seekToTime: toleranceBefore: toleranceAfter: as shown in the following code snippet:
CMTime fiveSecondsIn = CMTimeMake(5, 1);[player seekToTime:fiveSecondsIn toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];
Using zero-tolerance may require frame decoding of a large amount of data. For example, zero should be used only when writing complex media editing applications that require precise control. After playback, the player's header is set to the end of the item, and further playback calls do not work. To put the playback header back at the beginning of this item, you can register to receive AVPlayerItemDidPlayToEndTimeNotification notifications from this item. In the callback method of the notification, you use the kCMTimeZero parameter to call 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];}
Playing Multiple Items (Playing Multiple resources) You can use the AVQueuePlayer object to play multiple projects in sequence. The AVQueuePlayer class is a subclass of AVPlayer. You can use a player item array to initialize a Queue Player.
NSArray *items = <#An array of player items#>;AVQueuePlayer *queuePlayer = [[AVQueuePlayer alloc] initWithItems:items];
Then, you can use the play method to play the queue, just as you will use the AVPlayer object. The queue player plays each resource in sequence. If you want to jump to the next playing item, you will send a advanceToNextItem message to the queue player. You can use insertItem: afterItem:, removeItem: And removeAllItems to modify the queue. Generally, when you add a new project, you should check whether it can be inserted into the queue and use canInsertItem: afterItem :. You pass nil as the second parameter to test whether the new item can be added to the queue.
AVPlayerItem *anItem = <#Get a player item#>;if ([queuePlayer canInsertItem:anItem afterItem:nil]) {    [queuePlayer insertItem:anItem afterItem:nil];}
Monitoring Playback (Monitoring Playback)

You can monitor the display status of a player and multiple aspects of the player item being played. This is especially useful for situations that are not directly controlled or changed by you, for example:

1> if you use multiple tasks to switch to different applications, the player speed attribute will be reduced to 0.0. 2>. If you are playing remote media, the loadedTimeRanges and seekableTimeRanges attributes of player item will change with the availability of more data. These attributes will tell you which parts of the player item timeline are available. 3>. When the player item is created as an HTTP live streamThe currentItem attribute changes. 4>. The track attribute of the player item may change when playing the HTTP real-time stream. This may happen if the stream provides different encoding for the content; if the player switches to a different encoding, the track changes. 5>. When playback fails for some reason, the status attribute of the player or player item may change. You can use key-value observation to monitor changes to these attribute values.

Important: You should register the KVO change notification on the main thread and cancel the KVO change notification. This avoids the possibility of receiving partial notifications when another thread is making changes. AV Foundation calls observeValueForKeyPath: ofObject: change: context on the main thread, even if the change operation is performed on another thread.

Responding to a Change in Status (response to Status changes) When the player or player item status changes, it will send a notification of key value observation change. If an object cannot be played for some reason (for example, media service has been reset), the status changes to AVPlayerStatusFailed or AVPlayerItemStatusFailed depending on the situation. In this case, the value of the error attribute of the object will be changed to the error object that describes the reason why the object cannot be played.
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if (context == <#Player status context#>) { AVPlayer *thePlayer = (AVPlayer *)object; if ([thePlayer status] == AVPlayerStatusFailed) { NSError *error = [<#The AVPlayer object#> 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;}
Tracking Readiness for Visual Display (Visual Display Tracking is ready) You can observe that the readyForDisplay attribute of the AVPlayerLayer object receives a notification when the layer has user-visible content, especially when there is something for the user to view and then perform the conversion, only then can you insert the player layer into the layer tree.

You can use addPeriodicTimeObserverForInterval: queue: usingBlock: Or addBoundaryTimeObserverForTimes: queue: usingBlock :. for example, you can do this. For example, you can use information about the time used or the remaining time to update the user interface or execute other user interface synchronization tasks.

Tracking Time)

You can use addPeriodicTimeObserverForInterval: queue: usingBlock: Or addBoundaryTimeObserverForTimes: queue: usingBlock :. for example, you can update the user interface by using the information about the used time or remaining time, or execute other user interface synchronization. 1>. When addPeriodicTimeObserverForInterval: queue: usingBlock: is used, if the time is redirected and the playback starts or stops, the block you provide will be called at the specified time interval. 2>. When addBoundaryTimeObserverForTimes: queue: usingBlock: is used, you pass the CMTime structure array contained in the NSValue object. The block you provide is called whenever you traverse any time. Both methods return an opaque object as the observer. As long as you want the player to call the time to observe the block, you must keep a strong reference to the returned object. You must also balance each call of these methods with the corresponding removeTimeObserver: Call. Using these two methods, AV Foundation does not guarantee that your block will be called at intervals. If the execution of the previously called block is not completed, AV Foundation will not call the block. Therefore, you must ensure that your work in this region does not overload the system.

// Assume a property: @property (strong) id playerObserver; Float64 durationSeconds = CMTimeGetSeconds([<#An asset#> 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 = [<#A player#> addBoundaryTimeObserverForTimes:times queue:NULL usingBlock:^{ NSString *timeDescription = (NSString *) CFBridgingRelease(CMTimeCopyDescription(NULL, [self.player currentTime])); NSLog(@"Passed a boundary at %@", timeDescription);}];
Playing a Video File Using AVPlayerLayer (use AVPlayerLayer to play a Video File) 1>. configure the view to use AVPlayerLayer 2>. create an AVPlayer object 3>. create an AVPlayerItem object for a file-based resource and observe its status with a key value. 4>. use the Enable button to respond to the preparation of the Item for playing 5>. play the Item and restore the player's header to the beginning. The Player View)

To play the visual component of an asset, you need a view containing the AVPlayerLayer layer. The output of the AVPlayer object can be directed to this layer. You can create a simple UIView subclass to adapt to this situation:

#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 
A Simple View Controller

Suppose you have a simple view controller and declare it as follows:

@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;@end
The syncUI method synchronizes the button status with the player status:
- (void)syncUI { if ((self.player.currentItem != nil) && ([self.player.currentItem status] == AVPlayerItemStatusReadyToPlay)) { self.playButton.enabled = YES; } else { self.playButton.enabled = NO; }}
You can call syncUI in the viewDidLoad method of the View Controller to ensure that the view displays a consistent user interface for the first time.
- (void)viewDidLoad { [super viewDidLoad]; [self syncUI];}
Other attributes and methods are described.
Creating the Asset You can use AVURLAsset to create resources from a URL. (The following example assumes that your project contains an appropriate video resource .)
- (IBAction)loadAssetFromFile:sender { NSURL *fileURL = [[NSBundle mainBundle] URLForResource:<#@"VideoFileName"#> withExtension:<#@"extension"#>]; AVURLAsset *asset = [AVURLAsset URLAssetWithURL:fileURL options:nil]; NSString *tracksKey = @"tracks"; [asset loadValuesAsynchronouslyForKeys:@[tracksKey] completionHandler: ^{ // The completion block goes here. }];}
In the complete block, create an AVPlayerItem instance for the resource and set it to a player in the player view. Just like creating a resource, creating a player item does not mean that it is ready for use. To determine when the video can be played, you can observe the status attribute of the item. You should configure this observation before associating the player item instance with the player itself. When you associate the player item with the player, you trigger the preparation of the player item.
// 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:\n%@", [error localizedDescription]); } })

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.