一 簡述
一種控制器,用于在浮動的可調整大小的窗口中響應用戶啟動的畫中畫視頻播放。
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中執行以下步驟:
- 打開后臺模式開啟 Audio, AirPlay, and Picture in Picture
image-20201111164716519
- 為音頻會話配置合適的類別,如
AVAudioSessionCategoryPlayback
、AVAudioSessionCategoryPlayAndRecord
等
重要
不支持子類化和重寫其方法,這會導致未定義的行為。
二 官方屬性方法
// 當前設備是否支持畫中畫
+ (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 {
}