几种播放视频文件的方式(三) —— 基于AVFoundation框架视频播放(一)

版本记录

版本号 时间
V1.0 2017.12.30

前言

iOS系统中有很多方式可以播放视频文件,这里我们就详细的说明下播放视频文件的原理和实例。希望能帮助到大家,大家能喜欢。感兴趣的可以参考上面几篇。
1. 几种播放视频文件的方式(一) —— 总结播放视频的几种方式(一)
2. 几种播放视频文件的方式(二) —— 基于MediaPlayer框架的视频播放(一)

AVFoundation框架

框架API

在使用之前要引入框架

#import 

我们先看一下AVFoundation框架的API

/*
    File:  AVFoundation.h

    Framework:  AVFoundation
 
    Copyright 2010-2015 Apple Inc. All rights reserved.

    To report bugs, go to:  http://developer.apple.com/bugreporter/

*/

#import 
#if TARGET_OS_WATCH
#if ! __has_include()
#define AVF_IS_WATCHOS_SDK 1
#endif
#endif

#import 

#if ! AVF_IS_WATCHOS_SDK
#import 
#import 
#import 
#import 
#import 
#import 
#import 
#import 
#import 
#import 
#import 
#import 
#import 
#import 
#import 
#import 
#import 

#if TARGET_OS_IPHONE
#import 
#import 
#endif

#if (TARGET_OS_IPHONE || defined(__MAC_10_7))
#import 
#import 
#import 
#import 
#import 
#import 
#import 
#endif

#import 
#import 
#import 
#import 
#import 
#endif

#import 

#if ! AVF_IS_WATCHOS_SDK
#import 
#import 
#import 
#import 
#import  
#import 
#import 
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
#import 
#import 
#endif
#import 
#import 
#import 
#import 
#import 
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
#import 
#endif
#import 
#import 
#import 
#import 
#import 
#import 
#import 
#import 
#import 
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
#import 
#import 
#endif
#import 
#import 
#import 
#import 
#import 
#import 
#import 
#import 
#endif
#if TARGET_OS_TV
#import 
#endif

框架中几个有关的类

  • AVPlayer 用于播放音视频
  • AVPlayerItem 音频的对象
  • AVPlayerLayer 播放显示视频的图层界面

这里,AVPlayer是视频播放器;AVPlayerItem是视频要播放的元素;AVPlayerLayer是视频显示的图层。

AVPlayer

AVPlayer是AVFoundation中很重要的播放音视频的类,下面看一下API。

/*
    File:  AVPlayer.h

    Framework:  AVFoundation
 
    Copyright 2010-2017 Apple Inc. All rights reserved.

*/

/*!
    @class          AVPlayer
 
    @abstract
      AVPlayer offers a playback interface for single-item playback that's sufficient for
      the implementation of playback controllers and playback user interfaces.
 
    @discussion
      AVPlayer works equally well with local and remote media files, providing clients with appropriate
      information about readiness to play or about the need to await additional data before continuing.

      Visual content of items played by an instance of AVPlayer can be displayed in a CoreAnimation layer
      of class AVPlayerLayer.

      To allow clients to add and remove their objects as key-value observers safely, AVPlayer serializes notifications of
      changes that occur dynamically during playback on a dispatch queue. By default, this queue is the main queue. See dispatch_get_main_queue().
      
      To ensure safe access to AVPlayer's nonatomic properties while dynamic changes in playback state may be reported, clients must
      serialize their access with the receiver's notification queue. In the common case, such serialization is naturally achieved
      by invoking AVPlayer's various methods on the main thread or queue.
*/

#import 
#import 
#import 
#import 
#import 
#import 
#import 

@class AVPlayerItem;
@class AVPlayerInternal;

NS_ASSUME_NONNULL_BEGIN

/*!
 @enum AVPlayerStatus
 @abstract
    These constants are returned by the AVPlayer status property to indicate whether it can successfully play items.
 
 @constant   AVPlayerStatusUnknown
    Indicates that the status of the player is not yet known because it has not tried to load new media resources for
    playback.
 @constant   AVPlayerStatusReadyToPlay
    Indicates that the player is ready to play AVPlayerItem instances.
 @constant   AVPlayerStatusFailed
    Indicates that the player can no longer play AVPlayerItem instances because of an error. The error is described by
    the value of the player's error property.
 */
typedef NS_ENUM(NSInteger, AVPlayerStatus) {
    AVPlayerStatusUnknown,
    AVPlayerStatusReadyToPlay,
    AVPlayerStatusFailed
};

NS_CLASS_AVAILABLE(10_7, 4_0)
@interface AVPlayer : NSObject 
{
@private
    AVPlayerInternal     *_player;
}

/*!
    @method         playerWithURL:
    @abstract       Returns an instance of AVPlayer that plays a single audiovisual resource referenced by URL.
    @param          URL
    @result         An instance of AVPlayer
    @discussion     Implicitly creates an AVPlayerItem. Clients can obtain the AVPlayerItem as it becomes the player's currentItem.
*/
+ (instancetype)playerWithURL:(NSURL *)URL;

/*!
    @method         playerWithPlayerItem:
    @abstract       Create an AVPlayer that plays a single audiovisual item.
    @param          item
    @result         An instance of AVPlayer
    @discussion     Useful in order to play items for which an AVAsset has previously been created. See -[AVPlayerItem initWithAsset:].
*/
+ (instancetype)playerWithPlayerItem:(nullable AVPlayerItem *)item;

/*!
    @method         initWithURL:
    @abstract       Initializes an AVPlayer that plays a single audiovisual resource referenced by URL.
    @param          URL
    @result         An instance of AVPlayer
    @discussion     Implicitly creates an AVPlayerItem. Clients can obtain the AVPlayerItem as it becomes the player's currentItem.
*/
- (instancetype)initWithURL:(NSURL *)URL;

/*!
    @method         initWithPlayerItem:
    @abstract       Create an AVPlayer that plays a single audiovisual item.
    @param          item
    @result         An instance of AVPlayer
    @discussion     Useful in order to play items for which an AVAsset has previously been created. See -[AVPlayerItem initWithAsset:].
*/
- (instancetype)initWithPlayerItem:(nullable AVPlayerItem *)item;

/*!
 @property status
 @abstract
    The ability of the receiver to be used for playback.
 
 @discussion
    The value of this property is an AVPlayerStatus that indicates whether the receiver can be used for playback. When
    the value of this property is AVPlayerStatusFailed, the receiver can no longer be used for playback and a new
    instance needs to be created in its place. When this happens, clients can check the value of the error property to
    determine the nature of the failure. This property is key value observable.
 */
@property (nonatomic, readonly) AVPlayerStatus status;

/*!
 @property error
 @abstract
    If the receiver's status is AVPlayerStatusFailed, this describes the error that caused the failure.
 
 @discussion
    The value of this property is an NSError that describes what caused the receiver to no longer be able to play items.
    If the receiver's status is not AVPlayerStatusFailed, the value of this property is nil.
 */
@property (nonatomic, readonly, nullable) NSError *error;

@end


@interface AVPlayer (AVPlayerPlaybackControl)

/*!
 @property      rate
 @abstract      Indicates the desired rate of playback; 0.0 means "paused", 1.0 indicates a desire to play at the natural rate of the current item.
 @discussion
 Setting the value of rate to 0.0 pauses playback, causing the value of timeControlStatus to change to AVPlayerTimeControlStatusPaused.
 Setting the rate to a non-zero value causes the value of timeControlStatus to become either AVPlayerTimeControlStatusWaitingToPlayAtSpecifiedRate or AVPlayerTimeControlStatusPlaying, depending on whether sufficient media data has been buffered for playback to occur and whether the player's default behavior of waiting in order to minimize stalling is permitted. See discussion of AVPlayerTimeControlStatus for more details.
 
 AVPlayer can reset the desired rate to 0.0 when a change in overall state requires playback to be halted, such as when an interruption occurs on iOS, as announced by AVAudioSession, or when the playback buffer becomes empty and playback stalls while automaticallyWaitsToMinimizeStalling is NO.

 The effective rate of playback may differ from the desired rate even while timeControlStatus is AVPlayerTimeControlStatusPlaying, if the processing algorithm in use for managing audio pitch requires quantization of playback rate. For information about quantization of rates for audio processing, see AVAudioProcessingSettings.h. You can always obtain the effective rate of playback from the currentItem's timebase; see the timebase property of AVPlayerItem.
 */
@property (nonatomic) float rate;

/*!
 @method        play
 @abstract      Signals the desire to begin playback at the current item's natural rate.
 @discussion    Equivalent to setting the value of rate to 1.0.
 */
- (void)play;

/*!
 @method        pause
 @abstract      Pauses playback.
 @discussion    Equivalent to setting the value of rate to 0.0.
 */
- (void)pause;

/*!
 @enum AVPlayerTimeControlStatus
 @abstract
    These constants are the allowable values of AVPlayer's timeControlStatus property. This discussion pertains when automaticallyWaitsToMinimizeStalling is YES, the default setting, and exceptions are discussed in connection with automaticallyWaitsToMinimizeStalling.
 
 @constant   AVPlayerTimeControlStatusPaused
    This state is entered upon receipt of a -pause message, an invocation of -setRate: with a value of 0.0, when a change in overall state requires playback to be halted, such as when an interruption occurs on iOS, as announced by AVAudioSession.
    In this state, playback is paused indefinitely and will not resume until 1) a subsequent -play message is received or 2) a -setRate: or -playImmediatelyAtRate: message with a non-zero value for rate is received and sufficient media data has been buffered for playback to proceed.
 @constant   AVPlayerTimeControlStatusWaitingToPlayAtSpecifiedRate
    This state is entered when 1) the playback buffer becomes empty and playback stalls in AVPlayerTimeControlStatusPlaying, 2) when rate is set from zero to non-zero in AVPlayerTimeControlStatusPaused and insufficient media data has been buffered for playback to occur, or 3) when the player has no item to play, i.e. when the receiver's currentItem is nil.
    In this state, the value of the rate property is not currently effective but instead indicates the rate at which playback will start or resume. Refer to the value of reasonForWaitingToPlay for details about why the receiver is waiting and the conditions that allow waitStatus to change to AVPlayerWaitStatusPlaying.
    While waiting for buffering, you can attempt to start playback of any available media data via -playImmediatelyAtRate:.
 @constant   AVPlayerTimeControlStatusPlaying
    In this state, playback is currently progressing and rate changes will take effect immediately. Should playback stall because of insufficient media data, timeControlStatus will change to AVPlayerTimeControlStatusWaitingToPlayAtSpecifiedRate.
 */
typedef NS_ENUM(NSInteger, AVPlayerTimeControlStatus) {
    AVPlayerTimeControlStatusPaused,
    AVPlayerTimeControlStatusWaitingToPlayAtSpecifiedRate,
    AVPlayerTimeControlStatusPlaying
} NS_ENUM_AVAILABLE(10_12, 10_0);


/*!
 @property      timeControlStatus
 @abstract      Indicates whether playback is currently paused indefinitely, suspended while waiting for appropriate conditions, or in progress.
 @discussion    For possible values and discussion, see AVPlayerTimeControlStatus.
 
When automaticallyWaitsToMinimizeStalling is YES, absent intervention in the form of invocations of -setRate: or -pause or, on iOS, an interruption that requires user intervention before playback can resume, the value of the property timeControlStatus automatically changes between AVPlayerTimeControlStatusPlaying and AVPlayerTimeControlStatusWaitingToPlayAtSpecifiedRate depending on whether sufficient media data is available to continue playback. This property is key value observable.
*/
@property (nonatomic, readonly) AVPlayerTimeControlStatus timeControlStatus NS_AVAILABLE(10_12, 10_0);

/*!
 @typedef AVPlayerWaitingReason
 @abstract
    The type of reason that a player is waiting for playback.
*/
typedef NSString * AVPlayerWaitingReason NS_STRING_ENUM;

/*!
 @constant AVPlayerWaitingToMinimizeStallsReason
 @abstract Indicates that the player is waiting for appropriate playback buffer conditions before starting playback
 @discussion
    The player is waiting for playback because automaticallyWaitToMinimizeStalling is YES and playback at the specified rate would likely cause the playback buffer to become empty before playback completes. Playback will resume when 1) playback at the specified rate will likely complete without a stall or 2) the playback buffer becomes full, meaning no forther buffering of media data is possible.
    When the value of automaticallyWaitsToMinimizeStalling is NO, timeControlStatus cannot become AVPlayerTimeControlStatusWaitingToPlayAtSpecifiedRate for this reason.
 */
AVF_EXPORT AVPlayerWaitingReason const AVPlayerWaitingToMinimizeStallsReason NS_AVAILABLE(10_12, 10_0);

/*!
 @constant AVPlayerWaitingWhileEvaluatingBufferingRateReason
 @abstract Indicates that the player is monitoring the playback buffer fill rate to determine if playback is likely to complete without interruptions.
 @discussion
    The player is waiting for playback because automaticallyWaitToMinimizeStalling is YES and it has not yet determined if starting playback at the specified rate would likely cause the buffer to become empty. When the brief initial monitoring period is over, either playback will begin or the value of reasonForWaitingToPlayAtSpecifiedRate will switch to AVPlayerWaitingToMinimizeStallsReason.
    Recommended practice is not to show UI indicating the waiting state to the user while the value of reasonForWaitingToPlayAtSpecifiedRate is AVPlayerWaitingWhileEvaluatingBufferingRateReason.
 */
AVF_EXPORT AVPlayerWaitingReason const AVPlayerWaitingWhileEvaluatingBufferingRateReason NS_AVAILABLE(10_12, 10_0);

/*!
 @constant AVPlayerWaitingWithNoItemToPlayReason
 @abstract Indicates that the AVPlayer is waiting because its currentItem is nil
 @discussion
    The player is waiting for playback because automaticallyWaitToMinimizeStalling is YES and the value of currentItem is nil. When an item becomes available, either because of a call to -replaceCurrentItemWithPlayerItem: or  -insertItem: afterItem:, playback will begin or the value of reasonForWaitingToPlay will change.
 */
AVF_EXPORT AVPlayerWaitingReason const AVPlayerWaitingWithNoItemToPlayReason NS_AVAILABLE(10_12, 10_0);


/*!
 @property      reasonForWaitingToPlay
 @abstract      Indicates the reason for waiting when the value of timeControlStatus is AVPlayerTimeControlStatusWaitingToPlayAtSpecifiedRate
 @discussion
    When the value of timeControlStatus is AVPlayerTimeControlStatusWaitingToPlayAtSpecifiedRate, this property describes why the player is currently waiting. It is nil otherwise.
    You can use the value of reasonForWaitingToPlay to show UI indicating the player's waiting state conditionally.
    This property is key value observable.
    Possible values are AVPlayerWaitingWithNoItemToPlayReason, AVPlayerWaitingWhileEvaluatingBufferingRateReason, and AVPlayerWaitingToMinimizeStallsReason.
*/

@property (nonatomic, readonly, nullable) AVPlayerWaitingReason reasonForWaitingToPlay NS_AVAILABLE(10_12, 10_0);


/*!
 @method        playImmediatelyAtRate:
 @abstract      Immediately plays the available media data at the specified rate.
 @discussion
 When the player's currentItem has a value of NO for playbackBufferEmpty, this method causes the value of rate to change to the specified rate, the value of timeControlStatus to change to AVPlayerTimeControlStatusPlaying, and the receiver to play the available media immediately, whether or not prior buffering of media data is sufficient to ensure smooth playback.
 If insufficient media data is buffered for playback to start (e.g. if the current item has a value of YES for playbackBufferEmpty), the receiver will act as if the buffer became empty during playback, except that no AVPlayerItemPlaybackStalledNotification will be posted.
 */
- (void)playImmediatelyAtRate:(float)rate NS_AVAILABLE(10_12, 10_0);

@end


@interface AVPlayer (AVPlayerItemControl)

/* indicates the current item of the player */
@property (nonatomic, readonly, nullable) AVPlayerItem *currentItem;

/*!
    @method         replaceCurrentItemWithPlayerItem:
    @abstract       Replaces the player's current item with the specified player item.
    @param          item
      The AVPlayerItem that will become the player's current item.
    @discussion
      In all releases of iOS 4, invoking replaceCurrentItemWithPlayerItem: with an AVPlayerItem that's already the receiver's currentItem results in an exception being raised. Starting with iOS 5, it's a no-op.
*/
- (void)replaceCurrentItemWithPlayerItem:(nullable AVPlayerItem *)item;

/*!
 @enum AVPlayerActionAtItemEnd
 @abstract
    These constants are the allowable values of AVPlayer's actionAtItemEnd property.
 
 @constant   AVPlayerActionAtItemEndAdvance
    Indicates that when an AVPlayerItem reaches its end time the player will automatically advance to the next item in its queue.
    This value is supported only for players of class AVQueuePlayer. An AVPlayer that's not an AVQueuePlayer will raise an NSInvalidArgumentException if an attempt is made to set its actionAtItemEnd to AVPlayerActionAtItemEndAdvance.
 @constant   AVPlayerActionAtItemEndPause
    Indicates that when an AVPlayerItem reaches its end time the player will automatically pause (which is to say, the player's
    rate will automatically be set to 0).
 @constant   AVPlayerActionAtItemEndNone
    Indicates that when an AVPlayerItem reaches its end time the player will take no action (which is to say, the player's rate
    will not change, its currentItem will not change, and its currentTime will continue to be incremented or decremented as time
    elapses, according to its rate). After this, if the player's actionAtItemEnd is set to a value other than AVPlayerActionAtItemEndNone,
    the player will immediately take the action appropriate to that value.
*/
typedef NS_ENUM(NSInteger, AVPlayerActionAtItemEnd)
{
    AVPlayerActionAtItemEndAdvance  = 0,
    AVPlayerActionAtItemEndPause    = 1,
    AVPlayerActionAtItemEndNone     = 2,
};

/* indicates the action that the player should perform when playback of an item reaches its end time */
@property (nonatomic) AVPlayerActionAtItemEnd actionAtItemEnd;

@end


@interface AVPlayer (AVPlayerTimeControl)
/*!
 @method            currentTime
 @abstract          Returns the current time of the current item.
 @result            A CMTime
 @discussion        Returns the current time of the current item. Not key-value observable; use -addPeriodicTimeObserverForInterval:queue:usingBlock: instead.
 */
- (CMTime)currentTime;

/*!
 @method            seekToDate:
 @abstract          Moves the playback cursor.
 @param             date
 @discussion        Use this method to seek to a specified time for the current player item.
                    The time seeked to may differ from the specified time for efficiency. For sample accurate seeking see seekToTime:toleranceBefore:toleranceAfter:.
 */
- (void)seekToDate:(NSDate *)date;

/*!
 @method            seekToDate:completionHandler:
 @abstract          Moves the playback cursor and invokes the specified block when the seek operation has either been completed or been interrupted.
 @param             date
 @param             completionHandler
 @discussion        Use this method to seek to a specified time for the current player item and to be notified when the seek operation is complete.
                    The completion handler for any prior seek request that is still in process will be invoked immediately with the finished parameter 
                    set to NO. If the new request completes without being interrupted by another seek request or by any other operation the specified 
                    completion handler will be invoked with the finished parameter set to YES. 
 */
- (void)seekToDate:(NSDate *)date completionHandler:(void (^)(BOOL finished))completionHandler NS_AVAILABLE(10_7, 5_0);

/*!
 @method            seekToTime:
 @abstract          Moves the playback cursor.
 @param             time
 @discussion        Use this method to seek to a specified time for the current player item.
                    The time seeked to may differ from the specified time for efficiency. For sample accurate seeking see seekToTime:toleranceBefore:toleranceAfter:.
 */
- (void)seekToTime:(CMTime)time;

/*!
 @method            seekToTime:toleranceBefore:toleranceAfter:
 @abstract          Moves the playback cursor within a specified time bound.
 @param             time
 @param             toleranceBefore
 @param             toleranceAfter
 @discussion        Use this method to seek to a specified time for the current player item.
                    The time seeked to will be within the range [time-toleranceBefore, time+toleranceAfter] and may differ from the specified time for efficiency.
                    Pass kCMTimeZero for both toleranceBefore and toleranceAfter to request sample accurate seeking which may incur additional decoding delay. 
                    Messaging this method with beforeTolerance:kCMTimePositiveInfinity and afterTolerance:kCMTimePositiveInfinity is the same as messaging seekToTime: directly.
 */
- (void)seekToTime:(CMTime)time toleranceBefore:(CMTime)toleranceBefore toleranceAfter:(CMTime)toleranceAfter;

/*!
 @method            seekToTime:completionHandler:
 @abstract          Moves the playback cursor and invokes the specified block when the seek operation has either been completed or been interrupted.
 @param             time
 @param             completionHandler
 @discussion        Use this method to seek to a specified time for the current player item and to be notified when the seek operation is complete.
                    The completion handler for any prior seek request that is still in process will be invoked immediately with the finished parameter 
                    set to NO. If the new request completes without being interrupted by another seek request or by any other operation the specified 
                    completion handler will be invoked with the finished parameter set to YES. 
 */
- (void)seekToTime:(CMTime)time completionHandler:(void (^)(BOOL finished))completionHandler NS_AVAILABLE(10_7, 5_0);

/*!
 @method            seekToTime:toleranceBefore:toleranceAfter:completionHandler:
 @abstract          Moves the playback cursor within a specified time bound and invokes the specified block when the seek operation has either been completed or been interrupted.
 @param             time
 @param             toleranceBefore
 @param             toleranceAfter
 @discussion        Use this method to seek to a specified time for the current player item and to be notified when the seek operation is complete.
                    The time seeked to will be within the range [time-toleranceBefore, time+toleranceAfter] and may differ from the specified time for efficiency.
                    Pass kCMTimeZero for both toleranceBefore and toleranceAfter to request sample accurate seeking which may incur additional decoding delay. 
                    Messaging this method with beforeTolerance:kCMTimePositiveInfinity and afterTolerance:kCMTimePositiveInfinity is the same as messaging seekToTime: directly.
                    The completion handler for any prior seek request that is still in process will be invoked immediately with the finished parameter set to NO. If the new 
                    request completes without being interrupted by another seek request or by any other operation the specified completion handler will be invoked with the 
                    finished parameter set to YES.
 */
- (void)seekToTime:(CMTime)time toleranceBefore:(CMTime)toleranceBefore toleranceAfter:(CMTime)toleranceAfter completionHandler:(void (^)(BOOL finished))completionHandler NS_AVAILABLE(10_7, 5_0);

@end


@interface AVPlayer (AVPlayerAdvancedRateControl)


/*!
 @property      automaticallyWaitsToMinimizeStalling
 @abstract      Indicates that the player is allowed to delay playback at the specified rate in order to minimize stalling
 @discussion
 
 When this property is YES, whenever 1) the rate is set from zero to non-zero or 2) the playback buffer becomes empty and playback stalls, the player will attempt to determine if, at the specified rate, its currentItem will play to the end without interruptions. Should it determine that such interruptions would occur and these interruptions can be avoided by delaying the start or resumption of playback, the value of timeControlStatus will become AVPlayerTimeControlStatusWaitingToPlayAtSpecifiedRate and playback will start automatically when the likelihood of stalling has been minimized.
 
 You may want to set this property to NO when you need precise control over playback start times, e.g., when synchronizing multiple instances of AVPlayer, and you should set it to NO if you use an AVAssetResourceLoader delegate to load media data (more on this below). If the value of this property is NO, reasonForWaitingToPlay cannot assume a value of AVPlayerWaitingToMinimizeStallsReason.
 This implies that setting rate to a non-zero value in AVPlayerTimeControlStatusPaused will cause playback to start immediately as long as the playback buffer is not empty. When the playback buffer becomes empty during AVPlayerTimeControlStatusPlaying and playback stalls, playback state will switch to AVPlayerTimeControlStatusPaused and the rate will become 0.0.
 
 Changing the value of this property to NO while the value of timeControlStatus is AVPlayerTimeControlStatusWaitingToPlayAtSpecifiedRate with a reasonForWaitingToPlay of AVPlayerWaitingToMinimizeStallsReason will cause the player to attempt playback at the specified rate immediately.
 
 For clients linked against iOS 10.0 and running on that version or later or linked against OS X 10.12 and running on that version or later, the default value of this property is YES.
 In versions of iOS prior to iOS 10.0 and versions of OS X prior to 10.12, this property is unavailable, and the behavior of the AVPlayer corresponds to the type of content being played. For streaming content, including HTTP Live Streaming, the AVPlayer acts as if automaticallyWaitsToMinimizeStalling is YES. For file-based content, including file-based content accessed via progressive http download, the AVPlayer acts as if automaticallyWaitsToMinimizeStalling is NO.

 If you employ an AVAssetResourceLoader delegate that loads media data for playback, you should set the value of your AVPlayer’s automaticallyWaitsToMinimizeStalling property to NO. Allowing the value of automaticallyWaitsToMinimizeStalling to remain YES when an AVAssetResourceLoader delegate is used for the loading of media data can result in poor start-up times for playback and poor recovery from stalls, because the behaviors provided by AVPlayer when automaticallyWaitsToMinimizeStalling has a value of YES depend on predictions of the future availability of media data that that do not function as expected when data is loaded via a client-controlled means, using the AVAssetResourceLoader delegate interface.

 You can allow the value of automaticallyWaitsToMinimizeStalling to remain YES if you use an AVAssetResourceLoader delegate to manage content keys for FairPlay Streaming, to provide dynamically-generated master playlists for HTTP Live Streaming, or to respond to authentication challenges, but not to load media data for playback.
*/

@property (nonatomic) BOOL automaticallyWaitsToMinimizeStalling NS_AVAILABLE(10_12, 10_0);



/*!
    @method         setRate:time:atHostTime:
    @abstract       Simultaneously sets the playback rate and the relationship between the current item's current time and host time.
    @discussion     You can use this function to synchronize playback with an external activity.
    
                    The current item's timebase is adjusted so that its time will be (or was) itemTime when host time is (or was) hostClockTime.
                    In other words: if hostClockTime is in the past, the timebase's time will be interpolated as though the timebase has been running at the requested rate since that time.  If hostClockTime is in the future, the timebase will immediately start running at the requested rate from an earlier time so that it will reach the requested itemTime at the requested hostClockTime.  (Note that the item's time will not jump backwards, but instead will sit at itemTime until the timebase reaches that time.)

                    Note that setRate:time:atHostTime: is not currently supported for HTTP Live Streaming or when automaticallyWaitsToMinimizeStalling is YES. For clients linked against iOS 10.0 and later or OS X 12.0 and later, invoking setRate:time:atHostTime: when automaticallyWaitsToMinimizeStalling is YES will raise an NSInvalidArgument exception.
    @param itemTime The time to start playback from, specified precisely (i.e., with zero tolerance).
                    Pass kCMTimeInvalid to use the current item's current time.
    @param hostClockTime
                    The host time at which to start playback.
                    If hostClockTime is specified, the player will not ensure that media data is loaded before the timebase starts moving.
                    If hostClockTime is kCMTimeInvalid, the rate and time will be set together, but without external synchronization;
                    a host time in the near future will be used, allowing some time for media data loading.
*/
- (void)setRate:(float)rate time:(CMTime)itemTime atHostTime:(CMTime)hostClockTime NS_AVAILABLE(10_8, 6_0);

/*!
    @method         prerollAtRate:completionHandler:
    @abstract       Begins loading media data to prime the render pipelines for playback from the current time with the given rate.
    @discussion     Once the completion handler is called with YES, the player's rate can be set with minimal latency.
                    The completion handler will be called with NO if the preroll is interrupted by a time change or incompatible rate change, or if preroll is not possible for some other reason.
                    Call this method only when the rate is currently zero and only after the AVPlayer's status has become AVPlayerStatusReadyToPlay.

                    Note that advanced rate control is not currently supported for HTTP Live Streaming.
    @param rate     The intended rate for subsequent playback.
    @param completionHandler
                    The block that will be called when the preroll is either completed or is interrupted.
*/
- (void)prerollAtRate:(float)rate completionHandler:(nullable void (^)(BOOL finished))completionHandler NS_AVAILABLE(10_8, 6_0);

/*!
    @method         cancelPendingPrerolls
    @abstract       Cancel any pending preroll requests and invoke the corresponding completion handlers if present.
    @discussion     Use this method to cancel and release the completion handlers for pending prerolls. The finished parameter of the completion handlers will be set to NO.
*/
- (void)cancelPendingPrerolls NS_AVAILABLE(10_8, 6_0);

/* NULL by default.  if not NULL, overrides the automatic choice of master clock for item timebases. This is most useful for synchronizing video-only movies with audio played via other means. IMPORTANT: If you specify a master clock other than the appropriate audio device clock, audio may drift out of sync. */
@property (nonatomic, retain, nullable) __attribute__((NSObject)) CMClockRef masterClock NS_AVAILABLE(10_8, 6_0);

@end


@interface AVPlayer (AVPlayerTimeObservation)

/*!
    @method         addPeriodicTimeObserverForInterval:queue:usingBlock:
    @abstract       Requests invocation of a block during playback to report changing time.
    @param          interval
      The interval of invocation of the block during normal playback, according to progress of the current time of the player.
    @param          queue
      The serial queue onto which block should be enqueued.  If you pass NULL, the main queue (obtained using dispatch_get_main_queue()) will be used.  Passing a
      concurrent queue to this method will result in undefined behavior.
    @param          block
      The block to be invoked periodically.
    @result
      An object conforming to the NSObject protocol.  You must retain this returned value as long as you want the time observer to be invoked by the player.
      Pass this object to -removeTimeObserver: to cancel time observation.
    @discussion     The block is invoked periodically at the interval specified, interpreted according to the timeline of the current item.
                    The block is also invoked whenever time jumps and whenever playback starts or stops.
                    If the interval corresponds to a very short interval in real time, the player may invoke the block less frequently
                    than requested. Even so, the player will invoke the block sufficiently often for the client to update indications
                    of the current time appropriately in its end-user interface.
                    Each call to -addPeriodicTimeObserverForInterval:queue:usingBlock: should be paired with a corresponding call to -removeTimeObserver:.
                    Releasing the observer object without a call to -removeTimeObserver: will result in undefined behavior.
*/
- (id)addPeriodicTimeObserverForInterval:(CMTime)interval queue:(nullable dispatch_queue_t)queue usingBlock:(void (^)(CMTime time))block;

/*!
    @method         addBoundaryTimeObserverForTimes:queue:usingBlock:
    @abstract       Requests invocation of a block when specified times are traversed during normal playback.
    @param          times
      The times for which the observer requests notification, supplied as an array of NSValues carrying CMTimes.
    @param          queue
      The serial queue onto which block should be enqueued.  If you pass NULL, the main queue (obtained using dispatch_get_main_queue()) will be used.  Passing a
      concurrent queue to this method will result in undefined behavior.
    @param          block
      The block to be invoked when any of the specified times is crossed during normal playback.
    @result
      An object conforming to the NSObject protocol.  You must retain this returned value as long as you want the time observer to be invoked by the player.
      Pass this object to -removeTimeObserver: to cancel time observation.
    @discussion     Each call to -addPeriodicTimeObserverForInterval:queue:usingBlock: should be paired with a corresponding call to -removeTimeObserver:.
                    Releasing the observer object without a call to -removeTimeObserver: will result in undefined behavior.
*/
- (id)addBoundaryTimeObserverForTimes:(NSArray *)times queue:(nullable dispatch_queue_t)queue usingBlock:(void (^)(void))block;

/*!
    @method         removeTimeObserver:
    @abstract       Cancels a previously registered time observer.
    @param          observer
      An object returned by a previous call to -addPeriodicTimeObserverForInterval:queue:usingBlock: or -addBoundaryTimeObserverForTimes:queue:usingBlock:.
    @discussion     Upon return, the caller is guaranteed that no new time observer blocks will begin executing.  Depending on the calling thread and the queue
                    used to add the time observer, an in-flight block may continue to execute after this method returns.  You can guarantee synchronous time 
                    observer removal by enqueuing the call to -removeTimeObserver: on that queue.  Alternatively, call dispatch_sync(queue, ^{}) after
                    -removeTimeObserver: to wait for any in-flight blocks to finish executing.
                    -removeTimeObserver: should be used to explicitly cancel each time observer added using -addPeriodicTimeObserverForInterval:queue:usingBlock:
                    and -addBoundaryTimeObserverForTimes:queue:usingBlock:.
*/
- (void)removeTimeObserver:(id)observer;

@end


@interface AVPlayer (AVPlayerMediaControl)

/* Indicates the current audio volume of the player; 0.0 means "silence all audio", 1.0 means "play at the full volume of the current item".

   iOS note: Do not use this property to implement a volume slider for media playback. For that purpose, use MPVolumeView, which is customizable in appearance and provides standard media playback behaviors that users expect.
   This property is most useful on iOS to control the volume of the AVPlayer relative to other audio output, not for volume control by end users. */
@property (nonatomic) float volume NS_AVAILABLE(10_7, 7_0);

/* indicates whether or not audio output of the player is muted. Only affects audio muting for the player instance and not for the device. */
@property (nonatomic, getter=isMuted) BOOL muted NS_AVAILABLE(10_7, 7_0);

@end


@class AVPlayerMediaSelectionCriteria;

@interface AVPlayer (AVPlayerAutomaticMediaSelection)

/* Indicates whether the receiver should apply the current selection criteria automatically to AVPlayerItems.
 For clients linked against the iOS 7 SDK or later or against the OS X 10.9 SDK or later, the default is YES. For all others, the default is NO.

 By default, AVPlayer applies selection criteria based on system preferences. To override the default criteria for any media selection group, use -[AVPlayer setMediaSelectionCriteria:forMediaCharacteristic:].
*/
@property (nonatomic) BOOL appliesMediaSelectionCriteriaAutomatically NS_AVAILABLE(10_9, 7_0);

/*!
 @method     setMediaSelectionCriteria:forMediaCharacteristic:
 @abstract   Applies automatic selection criteria for media that has the specified media characteristic.
 @param      criteria
   An instance of AVPlayerMediaSelectionCriteria.
 @param      mediaCharacteristic
   The media characteristic for which the selection criteria are to be applied. Supported values include AVMediaCharacteristicAudible, AVMediaCharacteristicLegible, and AVMediaCharacteristicVisual.
 @discussion
    Criteria will be applied to an AVPlayerItem when:
        a) It is made ready to play
        b) Specific media selections are made by -[AVPlayerItem selectMediaOption:inMediaSelectionGroup:] in a different group. The automatic choice in one group may be influenced by a specific selection in another group.
        c) Underlying system preferences change, e.g. system language, accessibility captions.

   Specific selections made by -[AVPlayerItem selectMediaOption:inMediaSelectionGroup:] within any group will override automatic selection in that group until -[AVPlayerItem selectMediaOptionAutomaticallyInMediaSelectionGroup:] is received.
*/
- (void)setMediaSelectionCriteria:(nullable AVPlayerMediaSelectionCriteria *)criteria forMediaCharacteristic:(AVMediaCharacteristic)mediaCharacteristic NS_AVAILABLE(10_9, 7_0);

/*!
 @method     mediaSelectionCriteriaForMediaCharacteristic:
 @abstract   Returns the automatic selection criteria for media that has the specified media characteristic.
 @param      mediaCharacteristic
  The media characteristic for which the selection criteria is to be returned. Supported values include AVMediaCharacteristicAudible, AVMediaCharacteristicLegible, and AVMediaCharacteristicVisual.
*/
- (nullable AVPlayerMediaSelectionCriteria *)mediaSelectionCriteriaForMediaCharacteristic:(AVMediaCharacteristic)mediaCharacteristic NS_AVAILABLE(10_9, 7_0);

@end


@interface AVPlayer (AVPlayerAudioDeviceSupport)

/*!
 @property audioOutputDeviceUniqueID
 @abstract
    Specifies the unique ID of the Core Audio output device used to play audio.
 @discussion
    By default, the value of this property is nil, indicating that the default audio output device is used. Otherwise the value of this property is an NSString containing the unique ID of the Core Audio output device to be used for audio output.

    Core Audio's kAudioDevicePropertyDeviceUID is a suitable source of audio output device unique IDs.
*/
@property (nonatomic, copy, nullable) NSString *audioOutputDeviceUniqueID NS_AVAILABLE_MAC(10_9);

@end

/*
 @category      
    AVPlayer (AVPlayerExternalPlaybackSupport)
 
 @abstract
    Methods for supporting "external playback" of video 
 
 @discussion
    "External playback" is a mode where video data is sent to an external device for full screen playback at its original fidelity.
    AirPlay Video playback is considered as an "external playback" mode.
 
    In "external screen" mode (also known as mirroring and second display), video data is rendered on the host 
    device (e.g. Mac and iPhone), rendered video is recompressed and transferred to the external device, and the
    external device decompresses and displays the video.
 
    AVPlayerExternalPlaybackSupport properties affect AirPlay Video playback and are the replacement for the 
    deprecated AVPlayerAirPlaySupport properties.
 
    Additional note for iOS: AVPlayerExternalPlaybackSupport properties apply to the Lightning-based
    video adapters but do not apply to 30-pin-connector-based video output cables and adapters.
 */

@interface AVPlayer (AVPlayerExternalPlaybackSupport)

/* Indicates whether the player allows switching to "external playback" mode. The default value is YES. */
@property (nonatomic) BOOL allowsExternalPlayback NS_AVAILABLE(10_11, 6_0);

/* Indicates whether the player is currently playing video in "external playback" mode. */
@property (nonatomic, readonly, getter=isExternalPlaybackActive) BOOL externalPlaybackActive NS_AVAILABLE(10_11, 6_0);

/* Indicates whether the player should automatically switch to "external playback" mode while the "external 
    screen" mode is active in order to play video content and switching back to "external screen" mode as soon 
    as playback is done. Brief transition may be visible on the external display when automatically switching 
    between the two modes. The default value is NO. Has no effect if allowsExternalPlayback is NO. */
@property (nonatomic) BOOL usesExternalPlaybackWhileExternalScreenIsActive NS_AVAILABLE_IOS(6_0);

/* Video gravity strictly for "external playback" mode, one of AVLayerVideoGravity* defined in AVAnimation.h */
@property (nonatomic, copy) AVLayerVideoGravity externalPlaybackVideoGravity NS_AVAILABLE_IOS(6_0);

@end

#if TARGET_OS_IPHONE

@interface AVPlayer (AVPlayerAirPlaySupport)

/* Indicates whether the player allows AirPlay Video playback. The default value is YES. 
    This property is deprecated. Use AVPlayer's -allowsExternalPlayback instead. */
@property (nonatomic) BOOL allowsAirPlayVideo NS_DEPRECATED_IOS(5_0, 6_0);

/* Indicates whether the player is currently playing video via AirPlay. 
    This property is deprecated. Use AVPlayer's -externalPlaybackActive instead.*/
@property (nonatomic, readonly, getter=isAirPlayVideoActive) BOOL airPlayVideoActive NS_DEPRECATED_IOS(5_0, 6_0);

/* Indicates whether the player should automatically switch to AirPlay Video while AirPlay Screen is active in order to play video content, switching back to AirPlay Screen as soon as playback is done. 
    The default value is NO. Has no effect if allowsAirPlayVideo is NO.
    This property is deprecated. Use AVPlayer's -usesExternalPlaybackWhileExternalScreenIsActive instead. */
@property (nonatomic) BOOL usesAirPlayVideoWhileAirPlayScreenIsActive NS_DEPRECATED_IOS(5_0, 6_0);

@end

#endif // TARGET_OS_IPHONE

/*
    @category       AVPlayer (AVPlayerProtectedContent)
    @abstract       Methods supporting protected content.
*/

@interface AVPlayer (AVPlayerProtectedContent)

/*!
    @property outputObscuredDueToInsufficientExternalProtection
    @abstract
        Whether or not decoded output is being obscured due to insufficient external protection.
 
    @discussion
        The value of this property indicates whether the player is purposefully obscuring the visual output
        of the current item because the requirement for an external protection mechanism is not met by the
        current device configuration. It is highly recommended that clients whose content requires external
        protection observe this property and set the playback rate to zero and display an appropriate user
        interface when the value changes to YES. This property is key value observable.

        Note that the value of this property is dependent on the external protection requirements of the
        current item. These requirements are inherent to the content itself and cannot be externally specified.
        If the current item does not require external protection, the value of this property will be NO.
 */
@property (nonatomic, readonly) BOOL outputObscuredDueToInsufficientExternalProtection NS_AVAILABLE(10_12, 6_0);

@end

/*!
 @typedef AVPlayerHDRMode
 @abstract  A bitfield type that specifies an HDR mode.
 
 @constant  AVPlayerHDRModeHLG
 @abstract  Indicates that HLG (Hybrid Log-Gamma) HDR mode is available.
 @constant  AVPlayerHDRModeHDR10
 @abstract  Indicates that HDR10 HDR mode is available.
 @constant  AVPlayerHDRModeDolbyVision
 @abstract  Indicates that Dolby Vision HDR mode is available.
 */
typedef NS_OPTIONS(NSInteger, AVPlayerHDRMode) {
    AVPlayerHDRModeHLG              = 0x1,
    AVPlayerHDRModeHDR10                = 0x2,
    AVPlayerHDRModeDolbyVision      = 0x4,
} API_AVAILABLE(ios(11.2), tvos(11.2)) API_UNAVAILABLE(macos, watchos);

@interface AVPlayer (AVPlayerPlaybackCapabilities)

/*!
     @property      availableHDRModes
     @abstract      An array of AVPlayerHDRMode values that indicates the HDR modes the device can play to an appropriate display.   A value of 0 indicates that no HDR modes are supported.
 
     @discussion
         This property indicates all of the HDR modes that the device can play.  Each value indicates that an appropriate HDR display is available for the specified HDR mode.  Additionally, the device must be capable of playing the specified HDR type.  This property does not indicate whether video contains HDR content, whether HDR video is currently playing, or whether video is playing on an HDR display.
*/
@property (class, nonatomic, readonly) AVPlayerHDRMode availableHDRModes API_AVAILABLE(ios(11.2), tvos(11.2)) API_UNAVAILABLE(macos, watchos);

/*!
     @constant      AVPlayerAvailableHDRModesDidChangeNotification
     @abstract      A notification that fires whenever availableHDRModes changes.
 
     @discussion
         This notification fires when a value is added or removed from the list of availableHDRModes.  This can be caused by display connection/disconnection or resource changes.
*/
API_AVAILABLE(ios(11.2), tvos(11.2)) API_UNAVAILABLE(macos, watchos)
AVF_EXPORT NSNotificationName const AVPlayerAvailableHDRModesDidChangeNotification;

@end

@interface AVPlayer (AVPlayerDeprecated)

/*!
    @property closedCaptionDisplayEnabled
    @abstract
        Indicates whether display of closed captions is enabled.

    @discussion
        This property is deprecated.

        When the value of appliesMediaSelectionCriteriaAutomatically is YES, the receiver will enable closed captions automatically either according to user preferences or, if you provide them, according to AVPlayerMediaSelectionCriteria for the media characteristic AVMediaCharacteristicLegible.

        If you want to determine whether closed captions may be available for a given AVPlayerItem, you can examine the AVMediaSelectionOptions in the AVMediaSelectionGroup for the characteristic AVMediaCharacteristicLegible, as vended by -[AVAsset mediaSelectionGroupForMediaCharacteristic:]. See AVMediaCharacteristicTranscribesSpokenDialogForAccessibility and AVMediaCharacteristicDescribesMusicAndSoundForAccessibility as documented in AVMediaFormat.h for information about how to identify legible media selection options that offer the features of closed captions for accessibility purposes.

        You can select or deselect a specific AVMediaSelectionOption via -[AVPlayerItem selectMediaOption:inMediaSelectionGroup:].

        For further information about Media Accessibility preferences, see MediaAccessibility framework documentation.
 */
@property (nonatomic, getter=isClosedCaptionDisplayEnabled) BOOL closedCaptionDisplayEnabled NS_DEPRECATED(10_7, 10_13, 4_0, 11_0, "Allow AVPlayer to enable closed captions automatically according to user preferences by ensuring that the value of appliesMediaSelectionCriteriaAutomatically is YES.");

@end

/*!
    @class          AVQueuePlayer
 
    @abstract
      AVQueuePlayer is a subclass of AVPlayer that offers an interface for multiple-item playback.
 
    @discussion
      AVQueuePlayer extends AVPlayer with methods for managing a queue of items to be played in sequence.
      It plays these items as gaplessly as possible in the current runtime environment, depending on 
      the timely availability of media data for the enqueued items.
      
      For best performance clients should typically enqueue only as many AVPlayerItems as are necessary
      to ensure smooth playback. Note that once an item is enqueued it becomes eligible to be loaded and
      made ready for playback, with whatever I/O and processing overhead that entails.

*/

@class AVQueuePlayerInternal;

NS_CLASS_AVAILABLE(10_7, 4_1)
@interface AVQueuePlayer : AVPlayer 
{
@private
    AVQueuePlayerInternal   *_queuePlayer;
}

/*!
    @method     queuePlayerWithItems:
    @abstract   Creates an instance of AVQueuePlayer and enqueues the AVPlayerItems from the specified array.
    @param      items
      An NSArray of AVPlayerItems with which to populate the player's queue initially.
    @result
      An instance of AVQueuePlayer.
*/
+ (instancetype)queuePlayerWithItems:(NSArray *)items;

/*!
    @method     initWithItems:
    @abstract   Initializes an instance of AVQueuePlayer by enqueueing the AVPlayerItems from the specified array.
    @param      items
      An NSArray of AVPlayerItems with which to populate the player's queue initially.
    @result
      An instance of AVQueuePlayer.
*/
- (AVQueuePlayer *)initWithItems:(NSArray *)items;

/*!
    @method     items
    @abstract   Provides an array of the currently enqueued items.
    @result     An NSArray containing the enqueued AVPlayerItems.
*/
- (NSArray *)items;

/*!
    @method     advanceToNextItem
    @abstract   Ends playback of the current item and initiates playback of the next item in the player's queue.
    @discussion Removes the current item from the play queue.
*/
- (void)advanceToNextItem;

/*!
    @method     canInsertItem:afterItem:
    @abstract   Tests whether an AVPlayerItem can be inserted into the player's queue.
    @param      item
      The AVPlayerItem to be tested.
    @param      afterItem
      The item that the item to be tested is to follow in the queue. Pass nil to test whether the item can be appended to the queue.
    @result
      An indication of whether the item can be inserted into the queue after the specified item.
    @discussion
      Note that adding the same AVPlayerItem to an AVQueuePlayer at more than one position in the queue is not supported.
*/
- (BOOL)canInsertItem:(AVPlayerItem *)item afterItem:(nullable AVPlayerItem *)afterItem;

/*!
    @method     insertItem:afterItem:
    @abstract   Places an AVPlayerItem after the specified item in the queue.
    @param      item
      The item to be inserted.
    @param      afterItem
      The item that the newly inserted item should follow in the queue. Pass nil to append the item to the queue.
*/
- (void)insertItem:(AVPlayerItem *)item afterItem:(nullable AVPlayerItem *)afterItem;

/*!
    @method     removeItem:
    @abstract   Removes an AVPlayerItem from the queue.
    @param      item
      The item to be removed.
    @discussion
      If the item to be removed is currently playing, has the same effect as -advanceToNextItem.
*/
- (void)removeItem:(AVPlayerItem *)item;

/*!
    @method     removeAllItems
    @abstract   Removes all items from the queue.
    @discussion Stops playback by the target.
*/
- (void)removeAllItems;

@end

NS_ASSUME_NONNULL_END

AVPlayerItem

还是直接看API

/*
    File:  AVPlayerItem.h

    Framework:  AVFoundation
 
    Copyright 2010-2017 Apple Inc. All rights reserved.

*/

/*!
    @class          AVPlayerItem

    @abstract
      An AVPlayerItem carries a reference to an AVAsset as well as presentation settings for that asset.

    @discussion
      Note that inspection of media assets is provided by AVAsset.
      This class is intended to represent presentation state for an asset that's played by an AVPlayer and to permit observation of that state.

      To allow clients to add and remove their objects as key-value observers safely, AVPlayerItem serializes notifications of
      changes that occur dynamically during playback on the same dispatch queue on which notifications of playback state changes
      are serialized by its associated AVPlayer. By default, this queue is the main queue. See dispatch_get_main_queue().
      
      To ensure safe access to AVPlayerItem's nonatomic properties while dynamic changes in playback state may be reported, clients must
      serialize their access with the associated AVPlayer's notification queue. In the common case, such serialization is naturally
      achieved by invoking AVPlayerItem's various methods on the main thread or queue.
*/

#import 
#import 
#import 
#import 
#import 
#import 
#import 
#import 

NS_ASSUME_NONNULL_BEGIN

/* Note that NSNotifications posted by AVPlayerItem may be posted on a different thread from the one on which the observer was registered. */

// notifications                                                                                description
AVF_EXPORT NSString *const AVPlayerItemTimeJumpedNotification            NS_AVAILABLE(10_7, 5_0);   // the item's current time has changed discontinuously
AVF_EXPORT NSString *const AVPlayerItemDidPlayToEndTimeNotification      NS_AVAILABLE(10_7, 4_0);   // item has played to its end time
AVF_EXPORT NSString *const AVPlayerItemFailedToPlayToEndTimeNotification NS_AVAILABLE(10_7, 4_3);   // item has failed to play to its end time
AVF_EXPORT NSString *const AVPlayerItemPlaybackStalledNotification       NS_AVAILABLE(10_9, 6_0);    // media did not arrive in time to continue playback
AVF_EXPORT NSString *const AVPlayerItemNewAccessLogEntryNotification     NS_AVAILABLE(10_9, 6_0);   // a new access log entry has been added
AVF_EXPORT NSString *const AVPlayerItemNewErrorLogEntryNotification      NS_AVAILABLE(10_9, 6_0);   // a new error log entry has been added

// notification userInfo key                                                                    type
AVF_EXPORT NSString *const AVPlayerItemFailedToPlayToEndTimeErrorKey     NS_AVAILABLE(10_7, 4_3);   // NSError

/*!
 @enum AVPlayerItemStatus
 @abstract
    These constants are returned by the AVPlayerItem status property to indicate whether it can successfully be played.
 
 @constant   AVPlayerItemStatusUnknown
    Indicates that the status of the player item is not yet known because it has not tried to load new media resources
    for playback.
 @constant   AVPlayerItemStatusReadyToPlay
    Indicates that the player item is ready to be played.
 @constant   AVPlayerItemStatusFailed
    Indicates that the player item can no longer be played because of an error. The error is described by the value of
    the player item's error property.
 */
typedef NS_ENUM(NSInteger, AVPlayerItemStatus) {
    AVPlayerItemStatusUnknown,
    AVPlayerItemStatusReadyToPlay,
    AVPlayerItemStatusFailed
};

@class AVPlayer;
@class AVAsset;
@class AVAssetTrack;
@class AVAudioMix;
@class AVVideoComposition;
@class AVMediaSelection;
@class AVMediaSelectionGroup;
@class AVMediaSelectionOption;
@class AVPlayerItemInternal;
@protocol AVVideoCompositing;

NS_CLASS_AVAILABLE(10_7, 4_0)
@interface AVPlayerItem : NSObject 
{
@private
    AVPlayerItemInternal* _playerItem;
}
AV_INIT_UNAVAILABLE

/*!
 @method        playerItemWithURL:
 @abstract      Returns an instance of AVPlayerItem for playing a resource at the specified location.
 @param         URL
 @result        An instance of AVPlayerItem.
 @discussion    Equivalent to +playerItemWithAsset:, passing [AVAsset assetWithURL:URL] as the value of asset.
 */
+ (instancetype)playerItemWithURL:(NSURL *)URL;

/*!
 @method        playerItemWithAsset:
 @abstract      Returns an instance of AVPlayerItem for playing an AVAsset.
 @param         asset
 @result        An instance of AVPlayerItem.
 @discussion    Equivalent to +playerItemWithAsset:automaticallyLoadedAssetKeys:, passing @[ @"duration" ] as the value of automaticallyLoadedAssetKeys.
  */
+ (instancetype)playerItemWithAsset:(AVAsset *)asset;

/*!
 @method        playerItemWithAsset:automaticallyLoadedAssetKeys:
 @abstract      Returns an instance of AVPlayerItem for playing an AVAsset.
 @param         asset
 @param         automaticallyLoadedAssetKeys
                An NSArray of NSStrings, each representing a property key defined by AVAsset. See AVAsset.h for property keys, e.g. duration.
 @result        An instance of AVPlayerItem.
 @discussion    The value of each key in automaticallyLoadedAssetKeys will be automatically be loaded by the underlying AVAsset before the receiver achieves the status AVPlayerItemStatusReadyToPlay; i.e. when the item is ready to play, the value of -[[AVPlayerItem asset] statusOfValueForKey:error:] will be one of the terminal status values greater than AVKeyValueStatusLoading.
 */
+ (instancetype)playerItemWithAsset:(AVAsset *)asset automaticallyLoadedAssetKeys:(nullable NSArray *)automaticallyLoadedAssetKeys NS_AVAILABLE(10_9, 7_0);

/*!
 @method        initWithURL:
 @abstract      Initializes an AVPlayerItem with an NSURL.
 @param         URL
 @result        An instance of AVPlayerItem
 @discussion    Equivalent to -initWithAsset:, passing [AVAsset assetWithURL:URL] as the value of asset.
 */
- (instancetype)initWithURL:(NSURL *)URL;

/*!
 @method        initWithAsset:
 @abstract      Initializes an AVPlayerItem with an AVAsset.
 @param         asset
 @result        An instance of AVPlayerItem
 @discussion    Equivalent to -initWithAsset:automaticallyLoadedAssetKeys:, passing @[ @"duration" ] as the value of automaticallyLoadedAssetKeys.
 */
- (instancetype)initWithAsset:(AVAsset *)asset;

/*!
 @method        initWithAsset:automaticallyLoadedAssetKeys:
 @abstract      Initializes an AVPlayerItem with an AVAsset.
 @param         asset
                An instance of AVAsset.
 @param         automaticallyLoadedAssetKeys
                An NSArray of NSStrings, each representing a property key defined by AVAsset. See AVAsset.h for property keys, e.g. duration.
 @result        An instance of AVPlayerItem
 @discussion    The value of each key in automaticallyLoadedAssetKeys will be automatically be loaded by the underlying AVAsset before the receiver achieves the status AVPlayerItemStatusReadyToPlay; i.e. when the item is ready to play, the value of -[[AVPlayerItem asset] statusOfValueForKey:error:] will be one of the terminal status values greater than AVKeyValueStatusLoading.
 */
- (instancetype)initWithAsset:(AVAsset *)asset automaticallyLoadedAssetKeys:(nullable NSArray *)automaticallyLoadedAssetKeys NS_DESIGNATED_INITIALIZER NS_AVAILABLE(10_9, 7_0);

/*!
 @property status
 @abstract
    The ability of the receiver to be used for playback.
 
 @discussion
    The value of this property is an AVPlayerItemStatus that indicates whether the receiver can be used for playback.
    When the value of this property is AVPlayerItemStatusFailed, the receiver can no longer be used for playback and
    a new instance needs to be created in its place. When this happens, clients can check the value of the error
    property to determine the nature of the failure. This property is key value observable.
 */
@property (nonatomic, readonly) AVPlayerItemStatus status;

/*!
 @property error
 @abstract
    If the receiver's status is AVPlayerItemStatusFailed, this describes the error that caused the failure.
 
 @discussion
    The value of this property is an NSError that describes what caused the receiver to no longer be able to be played.
    If the receiver's status is not AVPlayerItemStatusFailed, the value of this property is nil.
 */
@property (nonatomic, readonly, nullable) NSError *error;

@end


@class AVPlayerItemTrack;
@class AVMetadataItem;

@interface AVPlayerItem (AVPlayerItemInspection)

/*!
 @property asset
 @abstract Accessor for underlying AVAsset.
 */
@property (nonatomic, readonly) AVAsset *asset;

/*!
 @property tracks
 @abstract Provides array of AVPlayerItem tracks. Observable (can change dynamically during playback).
    
 @discussion
    The value of this property will accord with the properties of the underlying media resource when the receiver becomes ready to play.
    Before the underlying media resource has been sufficiently loaded, its value is an empty NSArray. Use key-value observation to obtain
    a valid array of tracks as soon as it becomes available.
 */
@property (nonatomic, readonly) NSArray *tracks;

/*!
 @property duration
 @abstract Indicates the duration of the item, not considering either its forwardPlaybackEndTime or reversePlaybackEndTime.
 
 @discussion
    This property is observable. The duration of an item can change dynamically during playback.
    
    Unless you omit @"duration" from the array of asset keys you pass to +playerItemWithAsset:automaticallyLoadedAssetKeys: or
    -initWithAsset:automaticallyLoadedAssetKeys:, the value of this property will accord with the properties of the underlying
    AVAsset and the current state of playback once the receiver becomes ready to play.

    Before the underlying duration has been loaded, the value of this property is kCMTimeIndefinite. Use key-value observation to
    obtain a valid duration as soon as it becomes available. (Note that the value of duration may remain kCMTimeIndefinite,
    e.g. for live streams.)
 */
@property (nonatomic, readonly) CMTime duration NS_AVAILABLE(10_7, 4_3);

/*!
 @property presentationSize
 @abstract The size of the receiver as presented by the player.
 
 @discussion 
    Indicates the size at which the visual portion of the item is presented by the player; can be scaled from this 
    size to fit within the bounds of an AVPlayerLayer via its videoGravity property. Can be scaled arbitarily for presentation
    via the frame property of an AVPlayerLayer.
    
    The value of this property will accord with the properties of the underlying media resource when the receiver becomes ready to play.
    Before the underlying media resource is sufficiently loaded, its value is CGSizeZero. Use key-value observation to obtain a valid
    presentationSize as soon as it becomes available. (Note that the value of presentationSize may remain CGSizeZero, e.g. for audio-only items.)
 */
@property (nonatomic, readonly) CGSize presentationSize;

/*!
 @property timedMetadata
 @abstract Provides an NSArray of AVMetadataItems representing the timed metadata encountered most recently within the media as it plays. May be nil.
 @discussion
   Notifications of changes are available via key-value observation.
   As an optimization for playback, AVPlayerItem may omit the processing of timed metadata when no observer of this property is registered. Therefore, when no such observer is registered, the value of the timedMetadata property may remain nil regardless of the contents of the underlying media.
 */
@property (nonatomic, readonly, nullable) NSArray *timedMetadata;

/*!
 @property automaticallyLoadedAssetKeys
 @abstract An array of property keys defined on AVAsset. The value of each key in the array is automatically loaded while the receiver is being made ready to play.
 @discussion
   The value of each key in automaticallyLoadedAssetKeys will be automatically be loaded by the underlying AVAsset before the receiver achieves the status AVPlayerItemStatusReadyToPlay; i.e. when the item is ready to play, the value of -[[AVPlayerItem asset] statusOfValueForKey:error:] will be AVKeyValueStatusLoaded. If loading of any of the values fails, the status of the AVPlayerItem will change instead to AVPlayerItemStatusFailed..
 */
@property (nonatomic, readonly) NSArray *automaticallyLoadedAssetKeys NS_AVAILABLE(10_9, 7_0);

@end


@interface AVPlayerItem (AVPlayerItemRateAndSteppingSupport)

/* For releases of OS X prior to 10.9 and releases of iOS prior to 7.0, indicates whether the item can be played at rates greater than 1.0.
   Starting with OS X 10.9 and iOS 7.0, all AVPlayerItems with status AVPlayerItemReadyToPlay can be played at rates between 1.0 and 2.0, inclusive, even if canPlayFastForward is NO; for those releases canPlayFastForward indicates whether the item can be played at rates greater than 2.0.
*/
@property (nonatomic, readonly) BOOL canPlayFastForward NS_AVAILABLE(10_8, 5_0);

/* indicates whether the item can be played at rates between 0.0 and 1.0 */
@property (nonatomic, readonly) BOOL canPlaySlowForward NS_AVAILABLE(10_8, 6_0);

/* indicates whether the item can be played at rate -1.0 */
@property (nonatomic, readonly) BOOL canPlayReverse NS_AVAILABLE(10_8, 6_0);

/* indicates whether the item can be played at rates less between 0.0 and -1.0 */
@property (nonatomic, readonly) BOOL canPlaySlowReverse NS_AVAILABLE(10_8, 6_0);

/* indicates whether the item can be played at rates less than -1.0 */
@property (nonatomic, readonly) BOOL canPlayFastReverse NS_AVAILABLE(10_8, 5_0);

/* Indicates whether the item supports stepping forward; see -stepByCount:. Once the item has become ready to play, the value of canStepForward does not change even when boundary conditions are reached, such as when the item's currentTime is its end time. */
@property (nonatomic, readonly) BOOL canStepForward NS_AVAILABLE(10_8, 6_0);

/* indicates whether the item supports stepping backward; see -stepByCount:. Once the item has become ready to play, the value of canStepBackward does not change even when boundary conditions are reached, such as when the item's currentTime is equal to kCMTimeZero. */
@property (nonatomic, readonly) BOOL canStepBackward NS_AVAILABLE(10_8, 6_0);

@end


@interface AVPlayerItem (AVPlayerItemTimeControl)

/*!
 @method            currentTime
 @abstract          Returns the current time of the item.
 @result            A CMTime
 @discussion        Returns the current time of the item.
 */
- (CMTime)currentTime;

/*!
 @property forwardPlaybackEndTime
 @abstract
    The end time for forward playback.
 
 @discussion
    Specifies the time at which playback should end when the playback rate is positive (see AVPlayer's rate property).
    The default value is kCMTimeInvalid, which indicates that no end time for forward playback is specified.
    In this case, the effective end time for forward playback is the receiver's duration.
    
    When the end time is reached, the receiver will post AVPlayerItemDidPlayToEndTimeNotification and the AVPlayer will take
    the action indicated by the value of its actionAtItemEnd property (see AVPlayerActionAtItemEnd in AVPlayer.h). 

    The value of this property has no effect on playback when the rate is negative.
 */
@property (nonatomic) CMTime forwardPlaybackEndTime;

/*!
 @property reversePlaybackEndTime
 @abstract
    The end time for reverse playback.
 
 @discussion
    Specifies the time at which playback should end when the playback rate is negative (see AVPlayer's rate property).
    The default value is kCMTimeInvalid, which indicates that no end time for reverse playback is specified.
    In this case, the effective end time for reverse playback is kCMTimeZero.

    When the end time is reached, the receiver will post AVPlayerItemDidPlayToEndTimeNotification and the AVPlayer will take
    the action indicated by the value of its actionAtItemEnd property (see AVPlayerActionAtItemEnd in AVPlayer.h). 

    The value of this property has no effect on playback when the rate is positive.
 */
@property (nonatomic) CMTime reversePlaybackEndTime;

/*!
 @property seekableTimeRanges
 @abstract This property provides a collection of time ranges that the player item can seek to. The ranges provided might be discontinous.
 @discussion Returns an NSArray of NSValues containing CMTimeRanges.
 */
@property (nonatomic, readonly) NSArray *seekableTimeRanges;

/*!
 @method            seekToTime:completionHandler:
 @abstract          Moves the playback cursor and invokes the specified block when the seek operation has either been completed or been interrupted.
 @param             time
 @param             completionHandler
 @discussion        Use this method to seek to a specified time for the item and to be notified when the seek operation is complete.
                    The completion handler for any prior seek request that is still in process will be invoked immediately with the finished parameter 
                    set to NO. If the new request completes without being interrupted by another seek request or by any other operation the specified 
                    completion handler will be invoked with the finished parameter set to YES. 
                    If the seek time is outside of seekable time ranges as indicated by seekableTimeRanges property, the seek request will be cancelled and the completion handler will be invoked with the finished parameter set to NO.
 */
- (void)seekToTime:(CMTime)time completionHandler:(void (^_Nullable)(BOOL finished))completionHandler NS_AVAILABLE(10_7, 5_0);

/*!
 @method            seekToTime:toleranceBefore:toleranceAfter:completionHandler:
 @abstract          Moves the playback cursor within a specified time bound and invokes the specified block when the seek operation has either been completed or been interrupted.
 @param             time
 @param             toleranceBefore
 @param             toleranceAfter
 @param             completionHandler
 @discussion        Use this method to seek to a specified time for the item and to be notified when the seek operation is complete.
                    The time seeked to will be within the range [time-toleranceBefore, time+toleranceAfter] and may differ from the specified time for efficiency.
                    Pass kCMTimeZero for both toleranceBefore and toleranceAfter to request sample accurate seeking which may incur additional decoding delay. 
                    Messaging this method with beforeTolerance:kCMTimePositiveInfinity and afterTolerance:kCMTimePositiveInfinity is the same as messaging seekToTime: directly.
                    The completion handler for any prior seek request that is still in process will be invoked immediately with the finished parameter set to NO. If the new 
                    request completes without being interrupted by another seek request or by any other operation the specified completion handler will be invoked with the 
                    finished parameter set to YES.
                    If the seek time is outside of seekable time ranges as indicated by seekableTimeRanges property, the seek request will be cancelled and the completion handler will be invoked with the finished parameter set to NO.
 */
- (void)seekToTime:(CMTime)time toleranceBefore:(CMTime)toleranceBefore toleranceAfter:(CMTime)toleranceAfter completionHandler:(void (^_Nullable)(BOOL finished))completionHandler NS_AVAILABLE(10_7, 5_0);

/*!
 @method            cancelPendingSeeks
 @abstract          Cancel any pending seek requests and invoke the corresponding completion handlers if present.
 @discussion        Use this method to cancel and release the completion handlers of pending seeks. The finished parameter of the completion handlers will
                    be set to NO.
 */
- (void)cancelPendingSeeks NS_AVAILABLE(10_7, 5_0);

/*!
    @method currentDate
    @abstract   If currentTime is mapped to a particular (real-time) date, return that date.
    @result     Returns the date of current playback, or nil if playback is not mapped to any date.
*/
- (nullable NSDate *)currentDate;

/*!
 @method        seekToDate:completionHandler:
 @abstract      move playhead to a point corresponding to a particular date, and invokes the specified block when the seek operation has either been completed or been interrupted.
 @discussion
   For playback content that is associated with a range of dates, move the
   playhead to point within that range and invokes the completion handler when the seek operation is complete. 
   Will fail if the supplied date is outside the range or if the content is not associated with a range of dates.  
   The completion handler for any prior seek request that is still in process will be invoked immediately with the finished parameter 
   set to NO. If the new request completes without being interrupted by another seek request or by any other operation, the specified 
   completion handler will be invoked with the finished parameter set to YES. 
 @param         date                The new position for the playhead.
 @param         completionHandler   The block to invoke when seek operation is complete
 @result        Returns true if the playhead was moved to the supplied date.
 */
- (BOOL)seekToDate:(NSDate *)date completionHandler:(void (^_Nullable)(BOOL finished))completionHandler NS_AVAILABLE(10_9, 6_0);

/*!
 @method        stepByCount:
 @abstract      Moves player's current item's current time forward or backward by the specified number of steps.
 @param         stepCount
   The number of steps by which to move. A positive number results in stepping forward, a negative number in stepping backward.
 @discussion
   The size of each step depends on the enabled AVPlayerItemTracks of the AVPlayerItem. 
 */
- (void)stepByCount:(NSInteger)stepCount;

/*!
 @property      timebase
 @abstract      The item's timebase.
 @discussion 
   You can examine the timebase to discover the relationship between the item's time and the master clock used for drift synchronization.
   This timebase is read-only; you cannot set its time or rate to affect playback.  The value of this property may change during playback.
 */
@property (nonatomic, readonly, nullable) __attribute__((NSObject)) CMTimebaseRef timebase NS_AVAILABLE(10_8, 6_0);

@end


@class AVTextStyleRule;

@interface AVPlayerItem (AVPlayerItemVisualPresentation)

/*!
 @property videoComposition
 @abstract Indicates the video composition settings to be applied during playback.
 */
@property (nonatomic, copy, nullable) AVVideoComposition *videoComposition;

/*!
 @property customVideoCompositor
 @abstract Indicates the custom video compositor instance.
 @discussion
    This property is nil if there is no video compositor, or if the internal video compositor is in use. This reference can be used to provide
    extra context to the custom video compositor instance if required.
 */
@property (nonatomic, readonly, nullable) id customVideoCompositor NS_AVAILABLE(10_9, 7_0);

/*!
 @property seekingWaitsForVideoCompositionRendering
 @abstract Indicates whether the item's timing follows the displayed video frame when seeking with a video composition
 @discussion
   By default, item timing is updated as quickly as possible, not waiting for media at new times to be rendered when seeking or 
   during normal playback. The latency that occurs, for example, between the completion of a seek operation and the display of a 
   video frame at a new time is negligible in most situations. However, when video compositions are in use, the processing of 
   video for any particular time may introduce noticeable latency. Therefore it may be desirable when a video composition is in 
   use for the item's timing be updated only after the video frame for a time has been displayed. This allows, for instance, an 
   AVSynchronizedLayer associated with an AVPlayerItem to remain in synchronization with the displayed video and for the 
   currentTime property to return the time of the displayed video.

   This property has no effect on items for which videoComposition is nil.

 */
@property (nonatomic) BOOL seekingWaitsForVideoCompositionRendering NS_AVAILABLE(10_9, 6_0);

/*!
 @property textStyleRules
 @abstract An array of AVTextStyleRules representing text styling that can be applied to subtitles and other legible media.
 @discussion
    The styling information contained in each AVTextStyleRule object in the array is used only when no equivalent styling information is provided by the media resource being played.  For example, if the text style rules specify Courier font but the media resource specifies Helvetica font, the text will be drawn using Helvetica font.
 
    This property has an effect only for tracks with media subtype kCMSubtitleFormatType_WebVTT.
*/
@property (nonatomic, copy, nullable) NSArray *textStyleRules NS_AVAILABLE(10_9, 6_0);

/*!
 @property  videoApertureMode
 @abstract  Specifies the video aperture mode to apply during playback.
 @discussion
    See AVVideoApertureMode constants defined in AVVideoSettings.h. Default is AVVideoApertureModeCleanAperture.
 */
@property (nonatomic, copy) AVVideoApertureMode videoApertureMode API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0)) __WATCHOS_PROHIBITED;

@end


@interface AVPlayerItem (AVPlayerItemAudioProcessing)

/*!
 @property  audioTimePitchAlgorithm
 @abstract  Indicates the processing algorithm used to manage audio pitch at varying rates and for scaled audio edits.
 @discussion
   Constants for various time pitch algorithms, e.g. AVAudioTimePitchSpectral, are defined in AVAudioProcessingSettings.h.
   The default value on iOS is AVAudioTimePitchAlgorithmLowQualityZeroLatency and on OS X is AVAudioTimePitchAlgorithmSpectral.
*/
@property (nonatomic, copy) AVAudioTimePitchAlgorithm audioTimePitchAlgorithm NS_AVAILABLE(10_9, 7_0);

/*!
 @property audioMix
 @abstract Indicates the audio mix parameters to be applied during playback
 @discussion
   The inputParameters of the AVAudioMix must have trackIDs that correspond to a track of the receiver's asset. Otherwise they will be ignored. (See AVAudioMix.h for the declaration of AVAudioMixInputParameters and AVPlayerItem's asset property.)
 */
@property (nonatomic, copy, nullable) AVAudioMix *audioMix;

@end


@interface AVPlayerItem (AVPlayerItemPlayability)

/*!
 @property loadedTimeRanges
 @abstract This property provides a collection of time ranges for which the player has the media data readily available. The ranges provided might be discontinuous.
 @discussion Returns an NSArray of NSValues containing CMTimeRanges.
 */
@property (nonatomic, readonly) NSArray *loadedTimeRanges;

/*!
 @property playbackLikelyToKeepUp
 @abstract Indicates whether the item will likely play through without stalling.
 @discussion This property communicates a prediction of playability. Factors considered in this prediction
    include I/O throughput and media decode performance. It is possible for playbackLikelyToKeepUp to
    indicate NO while the property playbackBufferFull indicates YES. In this event the playback buffer has
    reached capacity but there isn't the statistical data to support a prediction that playback is likely to 
    keep up. It is left to the application programmer to decide to continue media playback or not. 
    See playbackBufferFull below.
  */
@property (nonatomic, readonly, getter=isPlaybackLikelyToKeepUp) BOOL playbackLikelyToKeepUp;

/*! 
 @property playbackBufferFull
 @abstract Indicates that the internal media buffer is full and that further I/O is suspended.
 @discussion This property reports that the data buffer used for playback has reach capacity.
    Despite the playback buffer reaching capacity there might not exist sufficient statistical 
    data to support a playbackLikelyToKeepUp prediction of YES. See playbackLikelyToKeepUp above.
 */
@property (nonatomic, readonly, getter=isPlaybackBufferFull) BOOL playbackBufferFull;

/* indicates that playback has consumed all buffered media and that playback will stall or end */
@property (nonatomic, readonly, getter=isPlaybackBufferEmpty) BOOL playbackBufferEmpty;

/*!
 @property canUseNetworkResourcesForLiveStreamingWhilePaused
 @abstract Indicates whether the player item can use network resources to keep playback state up to date while paused
 @discussion
    For live streaming content, the player item may need to use extra networking and power resources to keep playback state up to date when paused.  For example, when this property is set to YES, the seekableTimeRanges property will be periodically updated to reflect the current state of the live stream.
 
    For clients linked on or after OS X 10.11 or iOS 9.0, the default value is NO.  To minimize power usage, avoid setting this property to YES when you do not need playback state to stay up to date while paused.
 */
@property (nonatomic, assign) BOOL canUseNetworkResourcesForLiveStreamingWhilePaused NS_AVAILABLE(10_11, 9_0);

/*!
@property   preferredForwardBufferDuration
@abstract   Indicates the media duration the caller prefers the player to buffer from the network ahead of the playhead to guard against playback disruption. 
@discussion The value is in seconds. If it is set to 0, the player will choose an appropriate level of buffering for most use cases.
            Note that setting this property to a low value will increase the chance that playback will stall and re-buffer, while setting it to a high value will increase demand on system resources.
            Note that the system may buffer less than the value of this property in order to manage resource consumption.
*/
@property (nonatomic) NSTimeInterval preferredForwardBufferDuration NS_AVAILABLE(10_12, 10_0);

@end


@interface AVPlayerItem (AVPlayerItemVariantControl)

/*!
 @property preferredPeakBitRate
 @abstract Indicates the desired limit of network bandwidth consumption for this item.

 @discussion
    Set preferredPeakBitRate to non-zero to indicate that the player should attempt to limit item playback to that bit rate, expressed in bits per second.

    If network bandwidth consumption cannot be lowered to meet the preferredPeakBitRate, it will be reduced as much as possible while continuing to play the item.
*/
@property (nonatomic) double preferredPeakBitRate NS_AVAILABLE(10_10, 8_0);

/*!
 @property preferredMaximumResolution
 @abstract Indicates a preferred upper limit on the resolution of the video to be downloaded (or otherwise transferred) and rendered by the player.
 @discussion
    The default value is CGSizeZero, which indicates that the client enforces no limit on video resolution. Other values indicate a preferred maximum video resolution.
    It only applies to HTTP Live Streaming asset.
 */
@property (nonatomic) CGSize preferredMaximumResolution NS_AVAILABLE(10_13, 11_0);

@end


@interface AVPlayerItem (AVPlayerItemMediaSelection) 

/*!
 @method        selectMediaOption:inMediaSelectionGroup:
 @abstract
   Selects the media option described by the specified instance of AVMediaSelectionOption in the specified AVMediaSelectionGroup and deselects all other options in that group.
 @param         mediaSelectionOption    The option to select.
 @param         mediaSelectionGroup     The media selection group, obtained from the receiver's asset, that contains the specified option.
 @discussion
   If the specified media selection option isn't a member of the specified media selection group, no change in presentation state will result.
   If the value of the property allowsEmptySelection of the AVMediaSelectionGroup is YES, you can pass nil for mediaSelectionOption to deselect
   all media selection options in the group.
   Note that if multiple options within a group meet your criteria for selection according to locale or other considerations, and if these options are otherwise indistinguishable to you according to media characteristics that are meaningful for your application, content is typically authored so that the first available option that meets your criteria is appropriate for selection.
 */
- (void)selectMediaOption:(nullable AVMediaSelectionOption *)mediaSelectionOption inMediaSelectionGroup:(AVMediaSelectionGroup *)mediaSelectionGroup NS_AVAILABLE(10_8, 5_0);

/*!
 @method        selectMediaOptionAutomaticallyInMediaSelectionGroup:
 @abstract
    Selects the media option in the specified media selection group that best matches the AVPlayer's current automatic selection criteria. Also allows automatic selection to be re-applied to the specified group subsequently if the relevant criteria are changed.
 @param         mediaSelectionGroup     The media selection group, obtained from the receiver's asset, that contains the specified option.
 @discussion
   Has no effect unless the appliesMediaSelectionCriteriaAutomatically property of the associated AVPlayer is YES and unless automatic media selection has previously been overridden via -[AVPlayerItem selectMediaOption:inMediaSelectionGroup:].
 */
- (void)selectMediaOptionAutomaticallyInMediaSelectionGroup:(AVMediaSelectionGroup *)mediaSelectionGroup NS_AVAILABLE(10_9, 7_0);

/*!
  @property     currentMediaSelection
  @abstract     Provides an instance of AVMediaSelection carrying current selections for each of the receiver's media selection groups.
*/
@property (nonatomic, readonly) AVMediaSelection *currentMediaSelection NS_AVAILABLE(10_11, 9_0);

@end


@class AVPlayerItemAccessLog;
@class AVPlayerItemErrorLog;
@class AVPlayerItemAccessLogInternal;
@class AVPlayerItemErrorLogInternal;
@class AVPlayerItemAccessLogEventInternal;
@class AVPlayerItemErrorLogEventInternal;

@interface AVPlayerItem (AVPlayerItemLogging)

/*!
 @method        accessLog
 @abstract      Returns an object that represents a snapshot of the network access log. Can be nil.
 @discussion    An AVPlayerItemAccessLog provides methods to retrieve the network access log in a format suitable for serialization.
                If nil is returned then there is no logging information currently available for this AVPlayerItem.
                An AVPlayerItemNewAccessLogEntryNotification will be posted when new logging information becomes available. However, accessLog might already return a non-nil value even before the first notification is posted.
 @result        An autoreleased AVPlayerItemAccessLog instance.
 */
- (nullable AVPlayerItemAccessLog *)accessLog NS_AVAILABLE(10_7, 4_3);

/*!
 @method        errorLog
 @abstract      Returns an object that represents a snapshot of the error log. Can be nil.
 @discussion    An AVPlayerItemErrorLog provides methods to retrieve the error log in a format suitable for serialization.
                If nil is returned then there is no logging information currently available for this AVPlayerItem.
 @result        An autoreleased AVPlayerItemErrorLog instance.
 */
- (nullable AVPlayerItemErrorLog *)errorLog NS_AVAILABLE(10_7, 4_3);

@end

@class AVPlayerItemOutput;

@interface AVPlayerItem (AVPlayerItemOutputs)

/*!
 @method        addOutput:
 @abstract      Adds the specified instance of AVPlayerItemOutput to the receiver's collection of outputs.
 @discussion    
    The class of AVPlayerItemOutput provided dictates the data structure that decoded samples are vended in. 
 
    When an AVPlayerItemOutput is associated with an AVPlayerItem, samples are provided for a media type in accordance with the rules for mixing, composition, or exclusion that the AVPlayer honors among multiple enabled tracks of that media type for its own rendering purposes. For example, video media will be composed according to the instructions provided via AVPlayerItem.videoComposition, if present. Audio media will be mixed according to the parameters provided via AVPlayerItem.audioMix, if present.
 @param         output
                An instance of AVPlayerItemOutput
 */

- (void)addOutput:(AVPlayerItemOutput *)output NS_AVAILABLE(10_8, 6_0);

/*!
 @method        removeOutput:
 @abstract      Removes the specified instance of AVPlayerItemOutput from the receiver's collection of outputs.
 @param         output
                An instance of AVPlayerItemOutput
 */

- (void)removeOutput:(AVPlayerItemOutput *)output NS_AVAILABLE(10_8, 6_0);

/*!
 @property      outputs
 @abstract      The collection of associated outputs.
 */

@property (nonatomic, readonly) NSArray *outputs NS_AVAILABLE(10_8, 6_0);

@end

@class AVPlayerItemMediaDataCollector;

@interface AVPlayerItem (AVPlayerItemMediaDataCollectors)

/*!
 @method        addMediaDataCollector:
 @abstract      Adds the specified instance of AVPlayerItemMediaDataCollector to the receiver's collection of mediaDataCollectors.
 @discussion
    This method may incur additional I/O to collect the requested media data asynchronously.
 @param         collector
                An instance of AVPlayerItemMediaDataCollector
*/
- (void)addMediaDataCollector:(AVPlayerItemMediaDataCollector *)collector NS_AVAILABLE(10_11_3, 9_3);

/*!
 @method        removeMediaDataCollector:
 @abstract      Removes the specified instance of AVPlayerItemMediaDataCollector from the receiver's collection of mediaDataCollectors.
 @param         collector
                An instance of AVPlayerItemMediaDataCollector
*/
- (void)removeMediaDataCollector:(AVPlayerItemMediaDataCollector *)collector NS_AVAILABLE(10_11_3, 9_3);

/*!
 @property      mediaDataCollectors
 @abstract      The collection of associated mediaDataCollectors.
*/
@property (nonatomic, readonly) NSArray *mediaDataCollectors NS_AVAILABLE(10_11_3, 9_3);;

@end

@interface AVPlayerItem (AVPlayerItemDeprecated)

/*!
 @method            seekToTime:
 @abstract          Moves the playback cursor.
 @param             time
 @discussion        Use this method to seek to a specified time for the item.
                    The time seeked to may differ from the specified time for efficiency. For sample accurate seeking see seekToTime:toleranceBefore:toleranceAfter:.
                    If the seek time is outside of seekable time ranges as indicated by seekableTimeRanges property, the seek request will be cancelled.
 */
- (void)seekToTime:(CMTime)time NS_DEPRECATED(10_7, 10_13, 4_0, 11_0, "Use -seekToTime:completionHandler:, passing nil for the completionHandler if you don't require notification of completion");

/*!
 @method            seekToTime:toleranceBefore:toleranceAfter:
 @abstract          Moves the playback cursor within a specified time bound.
 @param             time
 @param             toleranceBefore
 @param             toleranceAfter
 @discussion        Use this method to seek to a specified time for the item.
                    The time seeked to will be within the range [time-toleranceBefore, time+toleranceAfter] and may differ from the specified time for efficiency.
                    Pass kCMTimeZero for both toleranceBefore and toleranceAfter to request sample accurate seeking which may incur additional decoding delay. 
                    Messaging this method with beforeTolerance:kCMTimePositiveInfinity and afterTolerance:kCMTimePositiveInfinity is the same as messaging seekToTime: directly.
                    Seeking is constrained by the collection of seekable time ranges. If you seek to a time outside all of the seekable ranges the seek will result in a currentTime
                    within the seekable ranges.
                    If the seek time is outside of seekable time ranges as indicated by seekableTimeRanges property, the seek request will be cancelled.
 */
- (void)seekToTime:(CMTime)time toleranceBefore:(CMTime)toleranceBefore toleranceAfter:(CMTime)toleranceAfter NS_DEPRECATED(10_7, 10_13, 4_0, 11_0, "Use -seekToTime:toleranceBefore:toleranceAfter:completionHandler:, passing nil for the completionHandler if you don't require notification of completion");

/*!
 @method        seekToDate
 @abstract      move playhead to a point corresponding to a particular date.
 @discussion
   For playback content that is associated with a range of dates, move the
   playhead to point within that range. Will fail if the supplied date is outside
   the range or if the content is not associated with a range of dates.
 @param         date    The new position for the playhead.
 @result        Returns true if the playhead was moved to the supplied date.
 */
- (BOOL)seekToDate:(NSDate *)date NS_DEPRECATED(10_7, 10_13, 4_0, 11_0, "Use -seekToDate:completionHandler:, passing nil for the completionHandler if you don't require notification of completion");

/*!
 @method        selectedMediaOptionInMediaSelectionGroup:
 @abstract      Indicates the media selection option that's currently selected from the specified group. May be nil.
 @param         mediaSelectionGroup     A media selection group obtained from the receiver's asset.
 @result        An instance of AVMediaSelectionOption that describes the currently selection option in the group.
 @discussion
   If the value of the property allowsEmptySelection of the AVMediaSelectionGroup is YES, the currently selected option in the group may be nil.
 */
- (nullable AVMediaSelectionOption *)selectedMediaOptionInMediaSelectionGroup:(AVMediaSelectionGroup *)mediaSelectionGroup NS_DEPRECATED(10_8, 10_13, 5_0, 11_0, "Use currentMediaSelection to obtain an instance of AVMediaSelection, which encompasses the currently selected AVMediaSelectionOption in each of the available AVMediaSelectionGroups");

@end

@class AVPlayerItemAccessLogEvent;

/*!
 @class         AVPlayerItemAccessLog
 @abstract      An AVPlayerItemAccessLog provides methods to retrieve the access log in a format suitable for serialization.
 @discussion    An AVPlayerItemAccessLog acculumulates key metrics about network playback and presents them as a collection 
                of AVPlayerItemAccessLogEvent instances. Each AVPlayerItemAccessLogEvent instance collates the data 
                that relates to each uninterrupted period of playback.
*/
NS_CLASS_AVAILABLE(10_7, 4_3)
@interface AVPlayerItemAccessLog : NSObject 
{
@private
    AVPlayerItemAccessLogInternal   *_playerItemAccessLog;
}
AV_INIT_UNAVAILABLE

/*!
 @method        extendedLogData
 @abstract      Serializes an AVPlayerItemAccessLog in the Extended Log File Format.
 @discussion    This method converts the webserver access log into a textual format that conforms to the
                W3C Extended Log File Format for web server log files.
                For more information see: http://www.w3.org/pub/WWW/TR/WD-logfile.html
 @result        An autoreleased NSData instance.
 */
- (nullable NSData *)extendedLogData;

/*!
 @property      extendedLogDataStringEncoding
 @abstract      Returns the NSStringEncoding for extendedLogData, see above.
 @discussion    A string suitable for console output is obtainable by: 
                [[NSString alloc] initWithData:[myLog extendedLogData] encoding:[myLog extendedLogDataStringEncoding]]
 */
 @property (nonatomic, readonly) NSStringEncoding extendedLogDataStringEncoding;

/*!
 @property      events
 @abstract      An ordered collection of AVPlayerItemAccessLogEvent instances.
 @discussion    An ordered collection of AVPlayerItemAccessLogEvent instances that represent the chronological
                sequence of events contained in the access log.
                This property is not observable.
 */
@property (nonatomic, readonly) NSArray *events;

@end

@class AVPlayerItemErrorLogEvent;
/*!
 @class         AVPlayerItemErrorLog
 @abstract      An AVPlayerItemErrorLog provides methods to retrieve the error log in a format suitable for serialization.
 @discussion    An AVPlayerItemErrorLog provides data to identify if, and when, network resource playback failures occured.
*/
NS_CLASS_AVAILABLE(10_7, 4_3)
@interface AVPlayerItemErrorLog : NSObject 
{
@private
    AVPlayerItemErrorLogInternal    *_playerItemErrorLog;
}
AV_INIT_UNAVAILABLE

/*!
 @method        extendedLogData
 @abstract      Serializes an AVPlayerItemErrorLog in the Extended Log File Format.
 @discussion    This method converts the webserver error log into a textual format that conforms to the
                W3C Extended Log File Format for web server log files.
                For more information see: http://www.w3.org/pub/WWW/TR/WD-logfile.html
 @result        An autoreleased NSData instance.
 */
- (nullable NSData *)extendedLogData;

/*!
 @property      extendedLogDataStringEncoding
 @abstract      Returns the NSStringEncoding for extendedLogData, see above.
 @discussion    A string suitable for console output is obtainable by: 
                [[NSString alloc] initWithData:[myLog extendedLogData] encoding:[myLog extendedLogDataStringEncoding]]
 */
 @property (nonatomic, readonly) NSStringEncoding extendedLogDataStringEncoding;

/*!
 @property      events
 @abstract      An ordered collection of AVPlayerItemErrorLogEvent instances.
 @discussion    An ordered collection of AVPlayerItemErrorLogEvent instances that represent the chronological
                sequence of events contained in the error log.
                This property is not observable.
 */
@property (nonatomic, readonly) NSArray *events;

@end

/*!
 @class         AVPlayerItemAccessLogEvent
 @abstract      An AVPlayerItemAccessLogEvent represents a single log entry.
 @discussion    An AVPlayerItemAccessLogEvent provides named properties for accessing the data
                fields of each log event. None of the properties of this class are observable.
*/

NS_CLASS_AVAILABLE(10_7, 4_3)
@interface AVPlayerItemAccessLogEvent : NSObject 
{
@private
    AVPlayerItemAccessLogEventInternal  *_playerItemAccessLogEvent;
}
AV_INIT_UNAVAILABLE

/*!
 @property      numberOfSegmentsDownloaded
 @abstract      A count of media segments downloaded.
 @discussion    Value is negative if unknown. A count of media segments downloaded from the server to this client. Corresponds to "sc-count".
                This property is not observable.
                This property is deprecated. Use numberOfMediaRequests instead.
 */
@property (nonatomic, readonly) NSInteger numberOfSegmentsDownloaded NS_DEPRECATED(10_7, 10_9, 4_3, 7_0);

/*!
 @property      numberOfMediaRequests
 @abstract      A count of media read requests.
 @discussion    Value is negative if unknown. A count of media read requests from the server to this client. Corresponds to "sc-count".
                For HTTP live Streaming, a count of media segments downloaded from the server to this client.
                For progressive-style HTTP media downloads, a count of HTTP GET (byte-range) requests for the resource.
                This property is not observable. 
 */
@property (nonatomic, readonly) NSInteger numberOfMediaRequests NS_AVAILABLE(10_9, 6_0);

/*!
 @property      playbackStartDate
 @abstract      The date/time at which playback began for this event. Can be nil.
 @discussion    If nil is returned the date is unknown. Corresponds to "date".
                This property is not observable.
 */
@property (nonatomic, readonly, nullable) NSDate *playbackStartDate;

/*!
 @property      URI
 @abstract      The URI of the playback item. Can be nil.
 @discussion    If nil is returned the URI is unknown. Corresponds to "uri".
                This property is not observable.
 */
@property (nonatomic, readonly, nullable) NSString *URI;

/*!
 @property      serverAddress
 @abstract      The IP address of the server that was the source of the last delivered media segment. Can be nil.
 @discussion    If nil is returned the address is unknown. Can be either an IPv4 or IPv6 address. Corresponds to "s-ip".
                This property is not observable.
 */
@property (nonatomic, readonly, nullable) NSString *serverAddress;

/*!
 @property      numberOfServerAddressChanges
 @abstract      A count of changes to the property serverAddress, see above, over the last uninterrupted period of playback.
 @discussion    Value is negative if unknown. Corresponds to "s-ip-changes".
                This property is not observable.
 */
@property (nonatomic, readonly) NSInteger numberOfServerAddressChanges;

/*!
 @property      playbackSessionID
 @abstract      A GUID that identifies the playback session. This value is used in HTTP requests. Can be nil.
 @discussion    If nil is returned the GUID is unknown. Corresponds to "cs-guid".
                This property is not observable.
 */
@property (nonatomic, readonly, nullable) NSString *playbackSessionID;

/*!
 @property      playbackStartOffset
 @abstract      An offset into the playlist where the last uninterrupted period of playback began. Measured in seconds.
 @discussion    Value is negative if unknown. Corresponds to "c-start-time".
                This property is not observable.
 */
@property (nonatomic, readonly) NSTimeInterval playbackStartOffset;

/*!
 @property      segmentsDownloadedDuration
 @abstract      The accumulated duration of the media downloaded. Measured in seconds.
 @discussion    Value is negative if unknown. Corresponds to "c-duration-downloaded".
                This property is not observable.
 */
@property (nonatomic, readonly) NSTimeInterval segmentsDownloadedDuration;

/*!
 @property      durationWatched
 @abstract      The accumulated duration of the media played. Measured in seconds.
 @discussion    Value is negative if unknown. Corresponds to "c-duration-watched".
                This property is not observable.
 */
@property (nonatomic, readonly) NSTimeInterval durationWatched;

/*!
 @property      numberOfStalls
 @abstract      The total number of playback stalls encountered.
 @discussion    Value is negative if unknown. Corresponds to "c-stalls".
                This property is not observable.
 */
@property (nonatomic, readonly) NSInteger numberOfStalls;

/*!
 @property      numberOfBytesTransferred
 @abstract      The accumulated number of bytes transferred.
 @discussion    Value is negative if unknown. Corresponds to "bytes".
                This property is not observable.
 */
@property (nonatomic, readonly) long long numberOfBytesTransferred;

/*!
 @property      transferDuration
 @abstract      The accumulated duration of active network transfer of bytes. Measured in seconds.
 @discussion    Value is negative if unknown. Corresponds to "c-transfer-duration".
                This property is not observable.
 */
@property (nonatomic, readonly) NSTimeInterval transferDuration NS_AVAILABLE(10_9, 7_0);

/*!
 @property      observedBitrate
 @abstract      The empirical throughput across all media downloaded. Measured in bits per second.
 @discussion    Value is negative if unknown. Corresponds to "c-observed-bitrate".
                This property is not observable.
 */
@property (nonatomic, readonly) double observedBitrate;

/*!
 @property      indicatedBitrate
 @abstract      The throughput required to play the stream, as advertised by the server. Measured in bits per second.
 @discussion    Value is negative if unknown. Corresponds to "sc-indicated-bitrate".
                This property is not observable.
 */
@property (nonatomic, readonly) double indicatedBitrate;

/*!
 @property      indicatedAverageBitrate
 @abstract      Average throughput required to play the stream, as advertised by the server. Measured in bits per second.
 @discussion    Value is negative if unknown. Corresponds to "sc-indicated-avg-bitrate".
 This property is not observable.
 */
@property (nonatomic, readonly) double indicatedAverageBitrate NS_AVAILABLE(10_12, 10_0);

/*!
 @property      averageVideoBitrate
 @abstract      The average bitrate of video track if it is unmuxed. Average bitrate of combined content if muxed. Measured in bits per second.
 @discussion    Value is negative if unknown. Corresponds to "c-avg-video-bitrate".
 This property is not observable.
 */
@property (nonatomic, readonly) double averageVideoBitrate NS_AVAILABLE(10_12, 10_0);

/*!
 @property      averageAudioBitrate
 @abstract      The average bitrate of audio track. This is not available if audio is muxed with video. Measured in bits per second.
 @discussion    Value is negative if unknown. Corresponds to "c-avg-audio-bitrate".
 This property is not observable.
 */
@property (nonatomic, readonly) double averageAudioBitrate NS_AVAILABLE(10_12, 10_0);

/*!
 @property      numberOfDroppedVideoFrames
 @abstract      The total number of dropped video frames.
 @discussion    Value is negative if unknown. Corresponds to "c-frames-dropped".
                This property is not observable.
 */
@property (nonatomic, readonly) NSInteger numberOfDroppedVideoFrames;

/*!
 @property      startupTime
 @abstract      The accumulated duration until player item is ready to play. Measured in seconds.
 @discussion    Value is negative if unknown. Corresponds to "c-startup-time".
                This property is not observable.
 */
@property (nonatomic, readonly) NSTimeInterval startupTime NS_AVAILABLE(10_9, 7_0);

/*!
 @property      downloadOverdue
 @abstract      The total number of times the download of the segments took too long.
 @discussion    Value is negative if unknown. Corresponds to "c-overdue".
                This property is not observable.
 */
@property (nonatomic, readonly) NSInteger downloadOverdue NS_AVAILABLE(10_9, 7_0);

/*!
 @property      observedMaxBitrate
 @abstract      Maximum observed segment download bit rate.
 @discussion    Value is negative if unknown. Corresponds to "c-observed-max-bitrate".
                This property is not observable.
 */
@property (nonatomic, readonly) double observedMaxBitrate NS_AVAILABLE(10_9, 7_0);

/*!
 @property      observedMinBitrate
 @abstract      Minimum observed segment download bit rate.
 @discussion    Value is negative if unknown. Corresponds to "c-observed-min-bitrate".
                This property is not observable.
 */
@property (nonatomic, readonly) double observedMinBitrate NS_AVAILABLE(10_9, 7_0);

/*!
 @property      observedBitrateStandardDeviation
 @abstract      Standard deviation of observed segment download bit rates.
 @discussion    Value is negative if unknown. Corresponds to "c-observed-bitrate-sd".
                This property is not observable.
 */
@property (nonatomic, readonly) double observedBitrateStandardDeviation NS_AVAILABLE(10_9, 7_0);

/*!
 @property      playbackType
 @abstract      Playback type (LIVE, VOD, FILE).
 @discussion    If nil is returned the playback type is unknown. Corresponds to "s-playback-type".
                This property is not observable.
 */
@property (nonatomic, readonly, nullable) NSString *playbackType NS_AVAILABLE(10_9, 7_0);

/*!
 @property      mediaRequestsWWAN
 @abstract      Number of network read requests over WWAN.
 @discussion    Value is negative if unknown. Corresponds to "sc-wwan-count".
                This property is not observable.
 */
@property (nonatomic, readonly) NSInteger mediaRequestsWWAN NS_AVAILABLE(10_9, 7_0);

/*!
 @property      switchBitrate
 @abstract      Bandwidth that caused us to switch (up or down).
 @discussion    Value is negative if unknown. Corresponds to "c-switch-bitrate".
                This property is not observable.
 */
@property (nonatomic, readonly) double switchBitrate NS_AVAILABLE(10_9, 7_0);

@end

/*!
 @class         AVPlayerItemErrorLogEvent
 @abstract      An AVPlayerItemErrorLogEvent represents a single log entry.
 @discussion    An AVPlayerItemErrorLogEvent provides named properties for accessing the data
                fields of each log event. None of the properties of this class are observable.
*/
NS_CLASS_AVAILABLE(10_7, 4_3)
@interface AVPlayerItemErrorLogEvent : NSObject 
{
@private
    AVPlayerItemErrorLogEventInternal   *_playerItemErrorLogEvent;
}
AV_INIT_UNAVAILABLE

/*!
 @property      date
 @abstract      The date and time when the error occured. Can be nil.
 @discussion    If nil is returned the date is unknown. Corresponds to "date".
                This property is not observable.
 */
@property (nonatomic, readonly, nullable) NSDate *date;

/*!
 @property      URI
 @abstract      The URI of the playback item. Can be nil.
 @discussion    If nil is returned the URI is unknown. Corresponds to "uri".
                This property is not observable.
 */
@property (nonatomic, readonly, nullable) NSString *URI;

/*!
 @property      serverAddress
 @abstract      The IP address of the server that was the source of the error. Can be nil.
 @discussion    If nil is returned the address is unknown. Can be either an IPv4 or IPv6 address. Corresponds to "s-ip".
                This property is not observable.
 */
@property (nonatomic, readonly, nullable) NSString *serverAddress;

/*!
 @property      playbackSessionID
 @abstract      A GUID that identifies the playback session. This value is used in HTTP requests. Can be nil.
 @discussion    If nil is returned the GUID is unknown. Corresponds to "cs-guid".
                This property is not observable.
 */
@property (nonatomic, readonly, nullable) NSString *playbackSessionID;

/*!
 @property      errorStatusCode
 @abstract      A unique error code identifier.
 @discussion    Corresponds to "status".
                This property is not observable.
 */
@property (nonatomic, readonly) NSInteger errorStatusCode;

/*!
 @property      errorDomain
 @abstract      The domain of the error.
 @discussion    Corresponds to "domain".
                This property is not observable.
 */
@property (nonatomic, readonly) NSString *errorDomain;

/*!
 @property      errorComment
 @abstract      A description of the error encountered. Can be nil.
 @discussion    If nil is returned further information is not available. Corresponds to "comment".
                This property is not observable.
 */
@property (nonatomic, readonly, nullable) NSString *errorComment;

@end

NS_ASSUME_NONNULL_END

AVPlayerLayer

下面我们还是直接看API

/*
    File:  AVPlayerLayer.h

    Framework:  AVFoundation
 
    Copyright 2010-2017 Apple Inc. All rights reserved.

*/


/*!
    @class          AVPlayerLayer

    @abstract       AVPlayerLayer is a subclass of CALayer to which an AVPlayer can direct its visual output.

    @discussion     To create an AVPlayerLayer instance:
                    
                    AVPlayer *player = ...;
                    // ... set up an AVPlayer
                    
                    CALayer *superlayer = ...;
                    AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
 
                    // ... set up the AVPlayerLayer's geometry. For example: set the AVPlayerLayer frame according to the presentationSize of the AVPlayer's currentItem.
                    
                    [superlayer addSublayer:playerLayer];
                    
                    AVPlayerLayer provides a property 'videoGravity' that defines how the video content is displayed within the AVPlayerLayer property 'bounds' rect. 
                    The value for the @"contents" key of an AVPlayerLayer is opaque and effectively read-only.

                    Note that during playback AVPlayer may compensate for temporal drift between its visual output
                    and its audible output to one or more independently-clocked audio output devices by adjusting the timing of its
                    associated AVPlayerLayers. The effects of these adjustments are usually very minute; however, clients that
                    wish to remain entirely unaffected by such adjustments may wish to place other layers for which timing is
                    important into indepedently timed subtrees of their layer trees.
*/

#import 
#import 
#import 

@class AVPlayer;
@class AVPlayerLayerInternal;

NS_ASSUME_NONNULL_BEGIN

NS_CLASS_AVAILABLE(10_7, 4_0)
@interface AVPlayerLayer : CALayer
{
@private
    AVPlayerLayerInternal       *_playerLayer;
}

/*!
    @method     layerWithPlayer:
    @abstract       Returns an instance of AVPlayerLayer to display the visual output of the specified AVPlayer.
    @result     An instance of AVPlayerLayer.
*/
+ (AVPlayerLayer *)playerLayerWithPlayer:(nullable AVPlayer *)player;

/*! 
    @property       player
    @abstract       Indicates the instance of AVPlayer for which the AVPlayerLayer displays visual output
*/
@property (nonatomic, retain, nullable) AVPlayer *player;

/*!
    @property       videoGravity
    @abstract       A string defining how the video is displayed within an AVPlayerLayer bounds rect.
    @discusssion    Options are AVLayerVideoGravityResizeAspect, AVLayerVideoGravityResizeAspectFill 
                    and AVLayerVideoGravityResize. AVLayerVideoGravityResizeAspect is default. 
                    See  for a description of these options.
 */
@property(copy) AVLayerVideoGravity videoGravity;

/*!
     @property      readyForDisplay
     @abstract      Boolean indicating that the first video frame has been made ready for display for the current item of the associated AVPlayer.
     @discusssion   Use this property as an indicator of when best to show or animate-in an AVPlayerLayer into view. 
                    An AVPlayerLayer may be displayed, or made visible, while this propoerty is NO, however the layer will not have any user-visible content until the value becomes YES. Note that if an animation is added to an AVPlayerLayer before it becomes readyForDisplay the video image displayed inside might not animate with the receiver.
                    This property remains NO for an AVPlayer currentItem whose AVAsset contains no enabled video tracks.
 */
@property(nonatomic, readonly, getter=isReadyForDisplay) BOOL readyForDisplay;

/*!
    @property       videoRect
    @abstract       The current size and position of the video image as displayed within the receiver's bounds.
 */
@property (nonatomic, readonly) CGRect videoRect NS_AVAILABLE(10_9, 7_0);

/*!
    @property       pixelBufferAttributes
    @abstract       The client requirements for the visual output displayed in AVPlayerLayer during playback.   
    @discussion     Pixel buffer attribute keys are defined in 
 */
@property (nonatomic, copy, nullable) NSDictionary *pixelBufferAttributes NS_AVAILABLE(10_11, 9_0);

@end

NS_ASSUME_NONNULL_END

功能实现

下面我们实现基于AVFoundation框架的视频播放。直接看代码。

#import "ViewController.h"
#import 

@interface ViewController ()

@property (nonatomic, strong) AVPlayer *player;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    //如果没有声音,需要加上这一句话
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
    
    //创建要播放的元素
    NSURL *url = [[NSBundle mainBundle]URLForResource:@"movie.mp4" withExtension:nil];
    //playerItemWithAsset:通过设备相册里面的内容 创建一个 要播放的对象
    // 我们这里直接选择使用URL读取
    AVPlayerItem *item = [AVPlayerItem playerItemWithURL:url];
    
    //    时间控制的类目
    //    current
    //    forwordPlaybackEndTime   跳到结束位置
    //    reversePlaybackEndTime    跳到开始位置
    //    seekToTime   跳到指定位置
    
    //    采取kvo的形式获取视频总时长
    //    通过监视status判断是否准备好
    
    [item addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
    
    //创建播放器
    self.player = [AVPlayer playerWithPlayerItem:item];
    //也可以直接WithURL来获得一个地址的视频文件
    //    externalPlaybackVideoGravity    视频播放的样式
    //    AVLayerVideoGravityResizeAspect   普通的
    //    AVLayerVideoGravityResizeAspectFill   充满的
    //    currentItem  获得当前播放的视频元素
    
    //创建视频显示的图层
    AVPlayerLayer *layer = [AVPlayerLayer playerLayerWithPlayer:self.player];
    layer.frame = self.view.frame;
    
    // 显示播放视频的视图层要添加到self.view的视图层上面
    [self.view.layer addSublayer:layer];
   
    //界面
    [self initUI];
    
    //最后一步开始播放
    [self.player play];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemDidPlayEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
}

#pragma mark - Object Private Function

- (void)initUI
{
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    [self.view addSubview:button];
    [button setTitle:@"快进" forState:UIControlStateNormal];
    button.backgroundColor = [UIColor blueColor];
    button.frame = CGRectMake((self.view.bounds.size.width - 100.0) * 0.5, 100.0, 100.0, 100.0);
    [button addTarget:self action:@selector(buttonDidClick:) forControlEvents:UIControlEventTouchUpInside];
}

#pragma mark - KVO

//    duration   当前播放元素的总时长
//    status  加载的状态
//    AVPlayerItemStatusUnknown,  未知状态
//    AVPlayerItemStatusReadyToPlay,  准备播放的状态
//    AVPlayerItemStatusFailed   失败的状态

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    switch ([change[@"new"] integerValue]) {
        case AVPlayerItemStatusUnknown:{
            NSLog(@"未知状态");
            break;
        }
        case AVPlayerItemStatusReadyToPlay:{
            NSLog(@"获得视频总时长  %f",CMTimeGetSeconds(self.player.currentItem.duration));
            break;
        }
        case AVPlayerItemStatusFailed:{
            NSLog(@"加载失败");
            break;
        }
        default:
            break;
    }
}

#pragma mark - Action && Notification

- (void)buttonDidClick:(UIButton *)button
{
    [self.player seekToTime:CMTimeMakeWithSeconds(self.player.currentTime.value/self.player.currentTime.timescale + 1, self.player.currentTime.timescale) toleranceBefore:CMTimeMake(1, self.player.currentTime.timescale) toleranceAfter:CMTimeMake(1, self.player.currentTime.timescale)];
}

- (void)itemDidPlayEnd:(NSNotification *)notify
{
    NSLog(@"播放结束");
    [self.player seekToTime:kCMTimeZero];
    [self.player play];
}

@end

下面我们看输出结果

2017-12-30 17:26:14.991022+0800 JJMovie_demo2[30256:5612259] 获得视频总时长  8.527000
2017-12-30 17:26:23.264010+0800 JJMovie_demo2[30256:5612259] 播放结束

下面看一下视频效果

几种播放视频文件的方式(三) —— 基于AVFoundation框架视频播放(一)_第1张图片

后记

未完,待续~~~

几种播放视频文件的方式(三) —— 基于AVFoundation框架视频播放(一)_第2张图片

你可能感兴趣的:(几种播放视频文件的方式(三) —— 基于AVFoundation框架视频播放(一))