AVKit框架基于AVFoundation框架,提供了一個用于播放視頻內容的高級界面,創建用于媒體播放的視圖級服務。主要包含兩個類:AVPictureInPictureController
、AVPlayerViewController
。
一、AVPlayerViewController
AVPlayerViewController類繼承與UIViewController,在iOS 8.0之后可以使用,用來代替MPMoviePlayerController(iOS 9.0后被廢棄)。用于顯示AVPlayer對象的視頻內容以及系統提供的播放控制。
@property (nonatomic, strong, nullable) AVPlayer *player;
用于從視圖控制器獲取媒體內容的播放器。@property (nonatomic) BOOL showsPlaybackControls;
是否顯示播放控制。 默認為YES。-
@property (nonatomic, copy) NSString *videoGravity;
定義視頻在AVPlayerLayer中的顯示方式字符串。此處都是系統定義的字符串,有關選項的說明,請參閱<AVFoundation / AVAnimation.h>
。-
AVLayerVideoGravityResizeAspect
:默認項,在layer層范圍內保持長寬比適配。不會變形和缺失。 -
AVLayerVideoGravityResizeAspectFill
:在layer層范圍內保持長寬比完全填充滿。不會變形但是會使顯示部分缺失。 -
AVLayerVideoGravityResize
:平鋪,會變形。
-
@property (nonatomic, readonly, getter = isReadyForDisplay) BOOL readyForDisplay;
表示第一個視頻幀已經準備就緒,可以顯示相關AVPlayer的當前項目,就是說是否準備好播放視頻。@property (nonatomic, readonly) CGRect videoBounds;
視頻圖像顯示在父視圖范圍內的當前大小和位置。@property (nonatomic, readonly, nullable) UIView *contentOverlayView;
獲取在視頻內容和視頻控制控件之間用來添加其他自定義視圖的內容疊加層視圖。
以上屬性是8.0后就可以使用,下面是關于實現畫中畫效果的屬性和方法,對于SDK要求比較高(所謂畫中畫,即是用戶可以將當前播放的視頻縮小放在屏幕上同時進行其他應用程序的使用,畫中畫僅在iPad上可用)
@property (nonatomic, weak, nullable) id <AVPlayerViewControllerDelegate> delegate API_AVAILABLE(ios(9.0));
設置代理。@property (nonatomic) BOOL allowsPictureInPicturePlayback API_AVAILABLE(ios(9.0));
是否允許畫中畫播放。 默認為YES。只在iPad上有效。@property (nonatomic) BOOL updatesNowPlayingInfoCenter API_AVAILABLE(ios(10.0));
指示播放器視圖控制器是否更新現在正在播放的信息中心。@property (nonatomic) BOOL entersFullScreenWhenPlaybackBegins API_AVAILABLE(ios(11.0));
當播放按鈕被點擊時,是否自動進入全屏。 默認為NO。@property (nonatomic) BOOL exitsFullScreenWhenPlaybackEnds API_AVAILABLE(ios(11.0));
當播放完后,是否自動退出全屏。 默認為NO。
AVPlayerViewControllerDelegate代理方法:
- (void)playerViewControllerWillStartPictureInPicture:(AVPlayerViewController *)playerViewController;
畫中畫將要開始時調用。- (void)playerViewControllerDidStartPictureInPicture:(AVPlayerViewController *)playerViewController;
畫中畫已經開始時調用。- (void)playerViewController:(AVPlayerViewController *)playerViewController failedToStartPictureInPictureWithError:(NSError *)error;
在畫中畫無法啟動時調用。- (void)playerViewControllerWillStopPictureInPicture:(AVPlayerViewController *)playerViewController;
在畫中畫將要停止是調用。- (void)playerViewControllerDidStopPictureInPicture:(AVPlayerViewController *)playerViewController;
在畫中畫已經停止是調用。- (BOOL)playerViewControllerShouldAutomaticallyDismissAtPictureInPictureStart:(AVPlayerViewController *)playerViewController;
是否在開始畫中畫時自動將當前的播放界面dismiss掉 返回YES則自動dismiss 返回NO則不會自動dismiss。- (void)playerViewController:(AVPlayerViewController *)playerViewController restoreUserInterfaceForPictureInPictureStopWithCompletionHandler:(void (^)(BOOL restored))completionHandler;
用戶點擊還原按鈕 從畫中畫模式還原時調用的方法。
簡單示例:
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
playerVC = [[AVPlayerViewController alloc] init];
// 本地文件
// NSURL * playerURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test" ofType:@"mp4"]];
// 網絡資源
NSURL * playerURL = [NSURL URLWithString:@"http://103.18.209.144/vhot2.qqvideo.tc.qq.com/AbGiL-wj27eJwdsfQXSfTHJzXd7a2v4iEN2oZpBfSh1I/o01836xm9bv.p702.1.mp4?sdtfrom=v1010&guid=fc947bf167ab7aa7ec24d7523d73b91b&vkey=BA71FD41E98CE214630AB773019FBCFDCA1653725707A23E819DE057AE20C4C94250FA0B0C1E63031FB89621068D2218C43BDEDF7E0421B31B667CD8621ABD4032617463E3F169876D39BFA50AFCD0CD710B8D68501140A62E4E1BC7746997EF8F43E4710BC4D53C376676B0CFB9E3F3CD97213F7DF356F6"];
playerVC.player = [AVPlayer playerWithURL:playerURL];
playerVC.delegate = self;
playerVC.allowsPictureInPicturePlayback = YES;
if (@available(iOS 11.0, *)) {
playerVC.entersFullScreenWhenPlaybackBegins = YES;
playerVC.exitsFullScreenWhenPlaybackEnds = YES;
} else {
// Fallback on earlier versions
}
[self presentViewController:playerVC animated:YES completion:nil];
}
- (void)playerViewController:(AVPlayerViewController *)playerViewController restoreUserInterfaceForPictureInPictureStopWithCompletionHandler:(void (^)(BOOL))completionHandler
{
[self presentViewController:playerVC animated:YES completion:^{
completionHandler(YES);
}];
}
二、AVPictureInPictureController
AVPictureInPictureController是NSObject的一個子類,可用于呈現浮動在應用程序之上的AVPlayerLayer的內容。主要針對使用自定義AVPlayer播放的畫中畫設置。
+ (BOOL)isPictureInPictureSupported;
判斷當前設備及當前上下文是否支持畫中畫。一般在顯示提供畫中畫按鈕之前調用。+ (UIImage *)pictureInPictureButtonStartImageCompatibleWithTraitCollection:(nullable UITraitCollection *)traitCollection;
參數給nil返回系統默認的“畫中畫”啟動模板圖像,用于播放器的“畫中畫”按鈕。+ (UIImage *)pictureInPictureButtonStopImageCompatibleWithTraitCollection:(nullable UITraitCollection *)traitCollection;
參數給nil返回系統默認的“畫中畫”停止模板圖像,用于播放器的“畫中畫”按鈕。- (nullable instancetype)initWithPlayerLayer:(AVPlayerLayer *)playerLayer;
指定的初始化方法。@property (nonatomic, readonly) AVPlayerLayer *playerLayer;
獲取播放圖層。@property (nonatomic, weak, nullable) id <AVPictureInPictureControllerDelegate> delegate;
- (void)startPictureInPicture;
如果允許啟動提供的AVPlayerLayer的畫中畫,在設置delegate后,delegate將會在開始和完成是分別調用- (void)pictureInPictureControllerWillStartPictureInPicture:(AVPictureInPictureController *)pictureInPictureController;
和- (void)pictureInPictureControllerDidStartPictureInPicture:(AVPictureInPictureController *)pictureInPictureController;
兩個代理方法。
如果調用畫中畫失敗則會調用- (void)pictureInPictureController:(AVPictureInPictureController *)pictureInPictureController failedToStartPictureInPictureWithError:(NSError *)error;
方法。- (void)stopPictureInPicture;
如果允許停止提供的AVPlayerLayer的畫中畫,與開始方法對應,在設置delegate后,delegate將會在開始和完成是分別調用- (void)pictureInPictureControllerWillStopPictureInPicture:(AVPictureInPictureController *)pictureInPictureController;
和- (void)pictureInPictureControllerDidStopPictureInPicture:(AVPictureInPictureController *)pictureInPictureController;
兩個代理方法。@property (nonatomic, readonly, getter = isPictureInPicturePossible) BOOL pictureInPicturePossible;
指示當前是否可以進行畫中畫播放。該處要區別于isPictureInPictureSupported
,這里主要檢驗在設備、系統支持的前提下是否有其他應用程序干擾實現畫中畫功能,如FaceTime,正在播放畫中畫內容,該屬性的值是NO。@property (nonatomic, readonly, getter = isPictureInPictureActive) BOOL pictureInPictureActive;
指示控制器的畫中畫窗口是否在屏幕上。@property (nonatomic, readonly, getter = isPictureInPictureSuspended) BOOL pictureInPictureSuspended;
指示控制器的畫中畫窗口是否暫停。當另一個應用程序(通常為FaceTime)正在使用該功能時,您的應用程序的圖片內容播放將被暫停。在這種狀態下,您的視頻播放是活動的,但已暫停和離開屏幕。當其他應用程序使用PiP完成時,您的應用程序的PiP播放將自動恢復。
以下為代理方法:AVPictureInPictureControllerDelegate
- (void)pictureInPictureControllerWillStartPictureInPicture:(AVPictureInPictureController *)pictureInPictureController;
將要進入畫中畫模式。- (void)pictureInPictureControllerDidStartPictureInPicture:(AVPictureInPictureController *)pictureInPictureController;
已經進入畫中畫模式。- (void)pictureInPictureController:(AVPictureInPictureController *)pictureInPictureController failedToStartPictureInPictureWithError:(NSError *)error;
進入畫中畫模式失敗后調用。- (void)pictureInPictureControllerWillStopPictureInPicture:(AVPictureInPictureController *)pictureInPictureController;
將要停止畫中畫模式。- (void)pictureInPictureControllerDidStopPictureInPicture:(AVPictureInPictureController *)pictureInPictureController;
已經停止畫中畫模式。- (void)pictureInPictureController:(AVPictureInPictureController *)pictureInPictureController restoreUserInterfaceForPictureInPictureStopWithCompletionHandler:(void (^)(BOOL restored))completionHandler;
當畫中畫即將停止時,調用它,讓應用恢復其視頻播放用戶界面。要允許系統完成恢復用戶界面,必須使block回調YES。