畫中畫功能
iOS9
就有了寝凌,以前只能在iPad
上使用纺且,iOS14
開始在iPhone
上也可以使用了难述,一直沒有這方面的需求也沒有具體的研究踩身,不過畢竟是蘋果官方的東西胀茵,相信實現(xiàn)起來不會麻煩,有2種辦法來實現(xiàn)挟阻。前提都需要工程配置一定要對T椎簟:巧凇!
工程配置
// 開啟后臺播放權(quán)限
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionAllowBluetooth error:nil];
[[AVAudioSession sharedInstance] setActive:YES error:nil];
1. 使用AVPlayerViewController
如果使用的是AVPlayerViewController
轨奄,只要AVAudioSession
和BackgroundMode
配置對就默認支持的,不用做其他任何操作。雖然很簡單拒炎,但是相信很少人會直接用這個方式挪拟,幾乎所有的項目都會自定義播放器,而不是直接使用系統(tǒng)的這個全屏播放器击你。
2. 使用AVPictureInPictureController
使用AVPictureInPictureController
承接自己寫的播放器的AVPlayerLayer
即可實現(xiàn)玉组,先放出來一個官方鏈接《≈叮可以直接去看相關(guān)API惯雳。
在API中可以看到有一個根據(jù)AVPlayerLayer來初始化Controller的方法:
/*!
@method initWithPlayerLayer:
@param playerLayer
The player layer from which to source the media content for the Picture in Picture controller.
@abstract Initialize the picture in picture controller with a player layer.
*/
- (nullable instancetype)initWithPlayerLayer:(AVPlayerLayer *)playerLayer;
我們就在ViewController中簡單粗暴的來一個AVPlayer播放一個視頻嘗試一下,剛開始的思路是這樣的鸿摇,先播放視頻石景,當用戶將要退到后臺的時候,初始化AVPictureInPictureController
并且啟動畫中畫拙吉,后來實測發(fā)現(xiàn)這樣是行不通潮孽,初始化AVPictureInPictureController
的動作必須提前,然后在需要開啟或者停止畫中畫功能筷黔,下面的代碼是實現(xiàn)了在播放視頻的時候已經(jīng)初始化了AVPictureInPictureController
往史,然后在應用將要退到后臺的時候開啟畫中畫播放視頻,用戶回到前臺后停止畫中畫佛舱,AVPictureInPictureControllerDelegate
中有一些相關(guān)的代理方法椎例,全是可選實現(xiàn),基本上用不到请祖,可以根據(jù)自己的需要進行實現(xiàn):
#import <AVKit/AVKit.h>
@interface ViewController ()<AVPictureInPictureControllerDelegate>
@property(nonatomic,strong)AVPlayerItem *playItem;
@property(nonatomic,strong)AVPlayer *player;
@property(nonatomic,strong)AVPlayerLayer *playerLayer;
@property(nonatomic,strong)AVPictureInPictureController *pictureInPictureController;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
// https://qiniu.hongwan.com.cn/hongwan/v/1982wi5b4690f4rqbd9kk.mp4 橫屏
// https://qiniu.hongwan.com.cn/hongwan/v/990g76sj2wvedbs53vji.mp4 豎屏
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionAllowBluetooth error:nil];
[[AVAudioSession sharedInstance] setActive:YES error:nil];
NSString *urlStr =@"https://qiniu.hongwan.com.cn/hongwan/v/990g76sj2wvedbs53vji.mp4";
self.playItem = [[AVPlayerItem alloc] initWithURL:[NSURL URLWithString:urlStr]];
self.player = [[AVPlayer alloc] initWithPlayerItem:self.playItem];
_playerLayer = [AVPlayerLayer playerLayerWithPlayer:_player];
_playerLayer.frame = self.view.frame;
_playerLayer.videoGravity = AVLayerVideoGravityResizeAspect;
[self.view.layer addSublayer:_playerLayer];
[self.playItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willResignActive) name:UIApplicationWillResignActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didBecomeActive) name:UIApplicationDidBecomeActiveNotification object:nil];
// 監(jiān)聽實現(xiàn)循環(huán)播放
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(loopPlay:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.player.currentItem];
self.pictureInPictureController = [[AVPictureInPictureController alloc] initWithPlayerLayer:self.playerLayer];
self.pictureInPictureController.delegate = self;
}
-(void)loopPlay:(NSNotification *)notification
{
if (!notification.object) {
return;
}
AVPlayerItem *item = (AVPlayerItem *)notification.object;
__weak __typeof(&*self)weakSelf = self;
[item seekToTime:kCMTimeZero completionHandler:^(BOOL finished) {
if (finished) {
[weakSelf.player play];
}
}];
}
-(void)willResignActive
{
if ([AVPictureInPictureController isPictureInPictureSupported]) {
if (self.pictureInPictureController.isPictureInPictureActive) {
[self.pictureInPictureController stopPictureInPicture];
} else {
[self.pictureInPictureController startPictureInPicture];
}
}
}
-(void)didBecomeActive
{
if ([AVPictureInPictureController isPictureInPictureSupported]) {
if (self.pictureInPictureController.isPictureInPictureActive) {
[self.pictureInPictureController stopPictureInPicture];
}
}
}
#pragma mark -------播放屬性監(jiān)聽--------
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
if ([keyPath isEqualToString:@"status"]) {
switch (self.playItem.status) {
case AVPlayerStatusReadyToPlay:
if (!self.player.timeControlStatus || self.player.timeControlStatus != AVPlayerTimeControlStatusPaused) {
[self.player play];
}
break;
default:
break;
}
}
}
可能有的同學會用到一個很流行的視頻播放框架ZFPlayer
订歪,需要將實現(xiàn)ZFPlayerMediaPlayback
協(xié)議的PlayerManager
,將內(nèi)部的avLayer
拋出來损拢,然后用這個layer來初始化AVPictureInPictureController
即可陌粹。
以上就是項目中簡單實現(xiàn)畫中畫播放視頻的完整流程