一、实现
实现画中画很简单,步骤一二三就行。
1、预备画中画
#import <AVKit/AVKit.h>
@property (nonatomic, strong) AVPictureInPictureController *pipVC;
@property (nonatomic, strong) AVPlayerLayer *playerLayer;
@property (nonatomic, strong) AVPlayer *player;
2、装备
- (void)startPip {
self.player = [AVPlayer playerWithURL:[NSURL URLWithString:self.liveVideo.hdlurl]];
self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
self.playerLayer.frame = CGRectMake(100, 80, 100, 200);
[self.player play];
[self.view.layer addSublayer:self.playerLayer];
//1.判断是否支持画中画功用
if ([AVPictureInPictureController isPictureInPictureSupported]) {
//2.敞开权限
@try {
NSError *error = nil;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback mode:AVAudioSessionModeMoviePlayback options:AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers error:&error];
// 为什么注释掉这里?你会发现有时 AVAudioSession 会有敞开失败的状况。故用上面的办法
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionOrientationBack error:&error];
[[AVAudioSession sharedInstance] setActive:YES error:&error];
} @catch (NSException *exception) {
NSLog(@"AVAudioSession发生过错");
}
self.pipVC = [[AVPictureInPictureController alloc] initWithPlayerLayer:self.playerLayer];
self.pipVC.delegate = self;
}
}
3、开始/封闭
- (void)openOrClose {
if (self.pipVC.isPictureInPictureActive) {
[self.pipVC stopPictureInPicture];
} else {
[self.pipVC startPictureInPicture];
}
}
//各种署理
// 行将敞开画中画
- (void)pictureInPictureControllerWillStartPictureInPicture:(AVPictureInPictureController *)pictureInPictureController {
NSLog(@"");
}
// 现已敞开画中画
- (void)pictureInPictureControllerDidStartPictureInPicture:(AVPictureInPictureController *)pictureInPictureController {
NSLog(@"");
}
// 敞开画中画失败
- (void)pictureInPictureController:(AVPictureInPictureController *)pictureInPictureController failedToStartPictureInPictureWithError:(NSError *)error {
NSLog(@"%@", error);
}
// 行将封闭画中画
- (void)pictureInPictureControllerWillStopPictureInPicture:(AVPictureInPictureController *)pictureInPictureController {
NSLog(@"");
}
// 现已封闭画中画
- (void)pictureInPictureControllerDidStopPictureInPicture:(AVPictureInPictureController *)pictureInPictureController {
NSLog(@"");
}
// 封闭画中画且康复播放界面
- (void)pictureInPictureController:(AVPictureInPictureController *)pictureInPictureController restoreUserInterfaceForPictureInPictureStopWithCompletionHandler:(void (^)(BOOL restored))completionHandler {
NSLog(@"");
}
二、留意点和坑
-
AVPlayerLayer frame设置后,可调整画中画的大小
-
画中画底层为AVPlayer,有人说只能播放视频,其实是错的,可以播放.m3u8的直播(目前某音已有该逻辑)
- 所以存在问题,假如APP中播放器使用其它协议的URL,那么如何切换?一般APP中为SDK提供的播放器。
- 直播中,若APP中和画中画使用不必协议的URL,其实影响不大,由于画面总是实时的,不存在同步问题,只要UI过度上需求处理。
-
画中画为AVPictureInPictureController,若要APP内全局显示,需让单例持有
-
真机上调试!模拟器可玩不转
-
app杀死,画中画也立即消失