目前很多App都通過iOS系統(tǒng)提供的畫中畫api將應(yīng)用功能擴(kuò)展到我們的手機(jī)桌面上了省骂,比較出名的就是網(wǎng)易云的桌面歌詞、b站的畫中畫播放穆碎、還有一些app的桌面倒計(jì)時(shí)以及懸浮提詞功能。
正好接觸提詞器的功能,網(wǎng)上查詢了很多資料都是付費(fèi)的橄仍,在此記錄一下實(shí)現(xiàn)方法
畫中畫功能本來是蘋果針對(duì)iPad等大屏設(shè)備提供的多任務(wù)處理的一種實(shí)現(xiàn)方式,可以將視頻窗口獨(dú)立懸浮出來牍戚,滿足用戶觀看視頻時(shí)處理其他任務(wù)的需求侮繁。
但隨著手機(jī)屏幕越做越大,該功能也逐漸下放至iOS平臺(tái)如孝,并且在iOS14以后的系統(tǒng)上開放給開發(fā)者使用鼎天。
話不多說,本篇先記錄畫中畫的基礎(chǔ)使用:
接入Pip
首先要做的是接入系統(tǒng)提供的畫中畫功能
在didFinishLaunchingWithOptions
中加入如下代碼:
#import <AVFoundation/AVFoundation.h>
#import <AVKit/AVKit.h>
//1.判斷是否支持畫中畫功能
if ([AVPictureInPictureController isPictureInPictureSupported]) {
//2.開啟權(quán)限
@try {
NSError *error = nil;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&error];
[[AVAudioSession sharedInstance] setActive:YES error:&error];
} @catch (NSException *exception) {
NSLog(@"AVAudioSession發(fā)生錯(cuò)誤");
}
}
配置畫中畫
前面說過暑竟,畫中畫本是為了將視頻畫面獨(dú)立出來斋射,因此我們需要一個(gè)視頻播放器來調(diào)起pip。
我們可以使用系統(tǒng)的AVPlayer
也可以使用其他自定義播放器但荤,這里使用AVPlayer
這里注意:playerLayer.frame 決定了畫中畫彈窗出現(xiàn)和消失時(shí)動(dòng)畫的位置和形狀罗岖,根據(jù)需求調(diào)整
重點(diǎn):初始視頻的比例決定了畫中畫窗口的大小和比例,常見的有正方形腹躁、16\9桑包、9\16、還有長(zhǎng)條形纺非,如果要控制窗口大小哑了,在這里更換視頻即可
@property (nonatomic, strong) AVPlayer *player;
@property (nonatomic, strong) AVPlayerLayer *playerLayer;
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"full16_9" ofType:@"mp4"]];
AVAsset *asset = [AVAsset assetWithURL:url];
AVPlayerItem * item = [[AVPlayerItem alloc] initWithAsset:asset];
self.player = [AVPlayer playerWithPlayerItem:item];
self.player.actionAtItemEnd = AVPlayerActionAtItemEndNone;
self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
self.playerLayer.videoGravity = AVLayerVideoGravityResize;
self.playerLayer.hidden = YES;
self.playerLayer.frame = CGRectMake(0, 0, kScreenWidth, 1);
[self.view.layer addSublayer:_playerLayer];
if ([AVPictureInPictureController isPictureInPictureSupported]) {
self.pipVC = [[AVPictureInPictureController alloc] initWithPlayerLayer:self.playerLayer];
if (@available(iOS 14.0, *)) {
self.pipVC.requiresLinearPlayback = YES;
} else {
}
self.pipVC.delegate = self;
}
這里為AVPictureInPictureController
添加了代理AVPictureInPictureControllerDelegate
,對(duì)畫中畫的生命周期暴露:
// 即將開啟畫中畫
- (void)pictureInPictureControllerWillStartPictureInPicture:(AVPictureInPictureController *)pictureInPictureController {
NSLog(@" 即將開啟畫中畫");
}
// 已經(jīng)開啟畫中畫
- (void)pictureInPictureControllerDidStartPictureInPicture:(AVPictureInPictureController *)pictureInPictureController {
NSLog(@" 已經(jīng)開啟畫中畫");
}
// 開啟畫中畫失敗
- (void)pictureInPictureController:(AVPictureInPictureController *)pictureInPictureController failedToStartPictureInPictureWithError:(NSError *)error {
NSLog(@" 開啟畫中畫失敗-%@", error);
}
// 即將關(guān)閉畫中畫
- (void)pictureInPictureControllerWillStopPictureInPicture:(AVPictureInPictureController *)pictureInPictureController {
}
// 已經(jīng)關(guān)閉畫中畫
- (void)pictureInPictureControllerDidStopPictureInPicture:(AVPictureInPictureController *)pictureInPictureController {
}
// 關(guān)閉畫中畫且恢復(fù)播放界面
- (void)pictureInPictureController:(AVPictureInPictureController *)pictureInPictureController restoreUserInterfaceForPictureInPictureStopWithCompletionHandler:(void (^)(BOOL restored))completionHandler {
}
開啟畫中畫
開啟畫中畫時(shí)烧颖,使用AVPIP提供的isPictureInPictureSupported
判斷設(shè)備是否支持開啟畫中畫弱左。
這里還可以判斷一下當(dāng)前畫中畫是否已啟動(dòng),通過startPictureInPicture
和stopPictureInPicture
來操作畫中畫視圖的開啟關(guān)閉炕淮。
@property (nonatomic, strong) AVPictureInPictureController *pipVC;
// 判斷是否支持畫中畫功能
if ([AVPictureInPictureController isPictureInPictureSupported]) {
if (self.pipVC.isPictureInPictureActive) {
[self.pipVC stopPictureInPicture];
} else {
[self.pipVC startPictureInPicture];
}
} else {
// [CC_MBProgressHUD showWithStatus:@"當(dāng)前系統(tǒng)版本過低拆火,無法使用該功能,請(qǐng)升級(jí)系統(tǒng)版本后使用"];
}
到這里,播放視頻的畫中畫窗口就可以正常展示了们镜,下一篇記錄在畫中畫上添加提詞器視圖币叹。