ForgetSou | Blog

❤ 武统台湾 刻不容缓 ❤

0%

iOS开发-iOS14画中画(OC)

一 简述

一种控制器,用于在浮动的可调整大小的窗口中响应用户启动的画中画视频播放。

API_AVAILABLE(ios(9.0), macos(10.15), tvos(14.0)) API_UNAVAILABLE(watchos)
@interface AVPictureInPictureController : NSObject

注意

画中画(PiP)是Apple希望始终在用户控制下的一项用户功能。仅在响应用户的明确请求时才调用PiP。如果某个应用以非用户直接指导的方式调用PiP,则App Store审核小组将拒绝它。

要在iOS中使用画中画,要在Xcode中执行以下步骤:

  1. 打开后台模式开启 Audio, AirPlay, and Picture in Picture

image-20201111164716519

  1. 为音频会话配置合适的类别,如AVAudioSessionCategoryPlaybackAVAudioSessionCategoryPlayAndRecord

重要

不支持子类化和重写其方法,这会导致未定义的行为。

二 官方属性方法

// 当前设备是否支持画中画
+ (BOOL)isPictureInPictureSupported;
// 创建画中画控制器
- (nullable instancetype)initWithPlayerLayer:(AVPlayerLayer *)playerLayer NS_DESIGNATED_INITIALIZER;
// 要播放媒体的播放器层
@property (nonatomic, readonly) AVPlayerLayer *playerLayer;
// 是否允许用户跳过媒体内容
@property (nonatomic) BOOL requiresLinearPlayback API_AVAILABLE(ios(14.0), macos(11.0), tvos(14.0)) API_UNAVAILABLE(watchos);
// 委托对象
@property (nonatomic, weak, nullable) id <AVPictureInPictureControllerDelegate> delegate;
// 当前是否可以进行画中画回放
@property (nonatomic, readonly, getter = isPictureInPicturePossible) BOOL pictureInPicturePossible;
// 控制器的画中画窗口是否在屏幕上
@property (nonatomic, readonly, getter = isPictureInPictureActive) BOOL pictureInPictureActive;
// 系统是否挂起控制器的画中画窗口
@property (nonatomic, readonly, getter = isPictureInPictureSuspended) BOOL pictureInPictureSuspended;

// 开始播放
- (void)startPictureInPicture;
// 停止播放(如果当前处于活跃状态)
- (void)stopPictureInPicture;
// 是否处于活跃状态并且可以关闭
@property (nonatomic, readonly) BOOL canStopPictureInPicture API_AVAILABLE(tvos(14.0)) API_UNAVAILABLE(ios, macos, watchos);

// 系统默认的“画中画”开始模板图像,用于应用程序的“画中画”按钮。
@property (class, nonatomic, readonly) UIImage *pictureInPictureButtonStartImage API_AVAILABLE(ios(13.0), tvos(14.0));
// 系统默认的画中画停止模板图像,用于应用程序的画中画按钮。
@property (class, nonatomic, readonly) UIImage *pictureInPictureButtonStopImage API_AVAILABLE(ios(13.0), tvos(14.0));

// 告诉委托人画中画即将停止的时间,使您的应用有机会恢复其视频播放用户界面。
- (void)pictureInPictureController:(AVPictureInPictureController *)pictureInPictureController restoreUserInterfaceForPictureInPictureStopWithCompletionHandler:(void (^)(BOOL restored))completionHandler;
// 当画中画即将开始时
- (void)pictureInPictureControllerWillStartPictureInPicture:(AVPictureInPictureController *)pictureInPictureController;
// 该画中画回放已经开始
- (void)pictureInPictureControllerDidStartPictureInPicture:(AVPictureInPictureController *)pictureInPictureController;
// 画中画无法启动
- (void)pictureInPictureController:(AVPictureInPictureController *)pictureInPictureController failedToStartPictureInPictureWithError:(NSError *)error;
// 画中画即将停止
- (void)pictureInPictureControllerWillStopPictureInPicture:(AVPictureInPictureController *)pictureInPictureController;
// 画中画停止
- (void)pictureInPictureControllerDidStopPictureInPicture:(AVPictureInPictureController *)pictureInPictureController;

三 简单示例

1. 导入框架`#import <AVKit/AVKit.h>`

2. 创建画中画对象

//1.判断是否支持画中画功能
if ([AVPictureInPictureController isPictureInPictureSupported]) {
//2.开启权限
@try {
NSError *error = nil;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&error];
[[AVAudioSession sharedInstance] setActive:YES error:&error];
} @catch (NSException *exception) {
NSLog(@"AVAudioSession错误");
}
self.pip = [[AVPictureInPictureController alloc] initWithPlayerLayer:self.player];
self.pip.delegate = self;
}

注意:上述代码里的self.player必须是AVPlayerLayer类型。

3. 开启/关闭

if (self.pip.isPictureInPictureActive) {
[self.pip stopPictureInPicture];
} else {
[self.pip startPictureInPicture];
}

4. 实现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 {

}
-------------本文结束感谢您的阅读-------------
坚持原创技术分享,您的支持将鼓励我继续创作!

欢迎关注我的其它发布渠道