日常收录

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

2022-10-09  本文已影响0人  凌晨四点的洛杉矶

目前很多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:@"当前系统版本过低,无法使用该功能,请升级系统版本后使用"];
    }

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

上一篇下一篇

猜你喜欢

热点阅读