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。