iOS画中画悬浮提词功能(上)

目前很多App都通过iOS系统提供的画中画api将应用功能扩展到我们的手机桌面上了,比较出名的就是网易云的桌面歌词、b站的画中画播放、还有一些app的桌面倒计时以及悬浮提词功能。
正好接触提词器的功能,网上查询了很多资料都是付费的,在此记录一下实现方法

画中画功能本来是苹果针对iPad等大屏设备提供的多任务处理的一种实现方式,可以将视频窗口独立悬浮出来,满足用户观看视频时处理其他任务的需求。
但随着手机屏幕越做越大,该功能也逐渐下放至iOS平台,并且在iOS14以后的系统上开放给开发者使用。

话不多说,本篇先记录画中画的基础使用:

接入Pip

首先要做的是接入系统提供的画中画功能
didFinishLaunchingWithOptions中加入如下代码:

#import <AVFoundation/AVFoundation.h>
#import <AVKit/AVKit.h>

   //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发生错误");
        }
    }

配置画中画

前面说过,画中画本是为了将视频画面独立出来,因此我们需要一个视频播放器来调起pip。
我们可以使用系统的AVPlayer 也可以使用其他自定义播放器,这里使用AVPlayer

这里注意:playerLayer.frame 决定了画中画弹窗出现和消失时动画的位置和形状,根据需求调整
重点:初始视频的比例决定了画中画窗口的大小和比例,常见的有正方形、16\9、9\16、还有长条形,如果要控制窗口大小,在这里更换视频即可

@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,对画中画的生命周期暴露:

// 即将开启画中画
- (void)pictureInPictureControllerWillStartPictureInPicture:(AVPictureInPictureController *)pictureInPictureController {
    NSLog(@" 即将开启画中画");
}

// 已经开启画中画
- (void)pictureInPictureControllerDidStartPictureInPicture:(AVPictureInPictureController *)pictureInPictureController {
    NSLog(@" 已经开启画中画");
}

// 开启画中画失败
- (void)pictureInPictureController:(AVPictureInPictureController *)pictureInPictureController failedToStartPictureInPictureWithError:(NSError *)error {
    NSLog(@" 开启画中画失败-%@", error);
}

// 即将关闭画中画
- (void)pictureInPictureControllerWillStopPictureInPicture:(AVPictureInPictureController *)pictureInPictureController {
}

// 已经关闭画中画
- (void)pictureInPictureControllerDidStopPictureInPicture:(AVPictureInPictureController *)pictureInPictureController {
}

// 关闭画中画且恢复播放界面
- (void)pictureInPictureController:(AVPictureInPictureController *)pictureInPictureController restoreUserInterfaceForPictureInPictureStopWithCompletionHandler:(void (^)(BOOL restored))completionHandler {
}

开启画中画

开启画中画时,使用AVPIP提供的isPictureInPictureSupported判断设备是否支持开启画中画。
这里还可以判断一下当前画中画是否已启动,通过startPictureInPicturestopPictureInPicture来操作画中画视图的开启关闭。

@property (nonatomic, strong) AVPictureInPictureController *pipVC;

    // 判断是否支持画中画功能
    if ([AVPictureInPictureController isPictureInPictureSupported]) {
        if (self.pipVC.isPictureInPictureActive) {
            [self.pipVC stopPictureInPicture];
        } else {
            [self.pipVC startPictureInPicture];
        }
    } else {
//        [CC_MBProgressHUD showWithStatus:@"当前系统版本过低,无法使用该功能,请升级系统版本后使用"];
    }

到这里,播放视频的画中画窗口就可以正常展示了,下一篇记录在画中画上添加提词器视图。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,525评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,203评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,862评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,728评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,743评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,590评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,330评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,244评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,693评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,885评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,001评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,723评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,343评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,919评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,042评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,191评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,955评论 2 355

推荐阅读更多精彩内容