iOS使用画中画展示后台歌词

Posted 想名真难

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS使用画中画展示后台歌词相关的知识,希望对你有一定的参考价值。

画中画的基本使用

如果你想自定义播放器实现画中画,就可以采用 AVKit 框架中的AVPictureInPictureController类。 

1.开启后台模式

2.导入框架#import <AVKit/AVKit.h> 创建AVPictureInPictureController

注:如果是使用系统播放器AVPlayerViewController,设置allowsPictureInPicturePlayback = YES即可

- (void)viewDidLoad 
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    if ([AVPictureInPictureController isPictureInPictureSupported]) 
        @try 
            NSError *error = nil;
            [[AVAudiosession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&error];
            [[AVAudioSession sharedInstance] setActive:YES withOptions:1 error:&error];
         @catch (NSException *exception) 
            NSLog(@"AVAudioSession发生错误");
        
        [self setupPip];
        [self setupUI];
        [self setupCustomView];
        
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleEnterForeground) name:UIApplicationDidBecomeActiveNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleEnterBackground) name:UIApplicationDidEnterBackgroundNotification object:nil];
        
     else 
        NSLog(@"不支持画中画");
    
    
    // 拍视频画中画文本滚动不停止
    [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^
        [[UIApplication sharedApplication] endBackgroundTask:UIBackgroundTaskInvalid];
    ];


// 配置画中画
- (void)setupPip 
    NSURL *url = [[NSBundle mainBundle] URLForResource:@"竖向视频" withExtension:@"MP4"];
    AVAsset *asset = [AVAsset assetWithURL:url];
    AVPlayerItem * item = [[AVPlayerItem alloc] initWithAsset:asset];
    
    AVPlayer *player = [[AVPlayer alloc] initWithPlayerItem:item];
    player.muted = YES;
    player.allowsExternalPlayback = YES;
    
    AVPlayerLayer * layer = [AVPlayerLayer playerLayerWithPlayer:player];
    layer.frame = CGRectMake(90, 90, 200, 200);
    [self.view.layer addSublayer:layer];
    
    self.pipController = [[AVPictureInPictureController alloc] initWithPlayerLayer: layer];
    self.pipController.delegate = self;
    // 使用 KVC,隐藏播放按钮、快进快退按钮
    [self.pipController setValue:[NSNumber numberWithInt:1] forKey:@"controlsStyle"];

3.开启或关闭画中画

#pragma - mark 开启\\关闭 画中画

- (void)pipButtonClicked 
    if (self.pipController.isPictureInPictureActive) 
        [self.pipController stopPictureInPicture];
     else 
        [self.pipController startPictureInPicture];
    

4.代理 AVPictureInPictureControllerDelegate

// 即将开启画中画
- (void)pictureInPictureControllerWillStartPictureInPicture:(AVPictureInPictureController *)pictureInPictureController;
// 已经开启画中画
- (void)pictureInPictureControllerDidStartPictureInPicture:(AVPictureInPictureController *)pictureInPictureController;
// 开启画中画失败
- (void)pictureInPictureController:(AVPictureInPictureController *)pictureInPictureController failedToStartPictureInPictureWithError:(NSError *)error;
// 即将关闭画中画
- (void)pictureInPictureControllerWillStopPictureInPicture:(AVPictureInPictureController *)pictureInPictureController;
// 已经关闭画中画
- (void)pictureInPictureControllerDidStopPictureInPicture:(AVPictureInPictureController *)pictureInPictureController;
// 关闭画中画且恢复播放界面
- (void)pictureInPictureController:(AVPictureInPictureController *)pictureInPictureController restoreUserInterfaceForPictureInPictureStopWithCompletionHandler:(void (^)(BOOL restored))completionHandler;
// 开启画中画失败,原因
- (void)pictureInPictureController:(AVPictureInPictureController *)pictureInPictureController failedToStartPictureInPictureWithError:(NSError *)error;

值得注意的是,关闭画中画会执行, 此方法用来恢复播放界面的

- (void)pictureInPictureController:(AVPictureInPictureController *)pictureInPictureController restoreUserInterfaceForPictureInPictureStopWithCompletionHandler:(void (^)(BOOL restored))completionHandler;

全局画中画注意点

  1. 通过一个全局变量持有画中画控制器,可以在pictureInPictureControllerWillStartPictureInPicture持有,pictureInPictureControllerDidStopPictureInPicture释放;
  2. 有可能不是点画中画按钮,而是从其它途径来打开当前画中画控制器,可以在viewWillAppear 进行判断并关闭;
  3. 已有画中画的情况下开启新的画中画,需要等完全关闭完再开启新的,防止有未知的错误出现,因为关闭画中画是有过程的;
  4. 如果创建AVPictureInPictureController并同时开启画中画功能,有可能会失效,出现这种情况延迟开启画中画功能即可。

使用画中画来实现展示自定义视图

iOS 14,基于 AVPictureInPictureController,实现自定义画中画,

基本思路:使用一个全黑的视频开启画中画,获取画中画的window,在这个window上添加自定义视图。

// 即将开始画中画展示
- (void)pictureInPictureControllerWillStartPictureInPicture:(AVPictureInPictureController *)pictureInPictureController 
    // 注意是 first window,不是 last window 也不是 key window
    UIWindow *firstWindow = [UIApplication sharedApplication].windows.firstObject;
    // 把自定义view放到画中画上
    [firstWindow addSubview:self.customView];
    [self.customView mas_makeConstraints:^(MASConstraintMaker *make) 
        make.edges.mas_equalTo(firstWindow);
    ];
  • 添加任意 UIView 到画中画窗口;
  • 按需隐藏系统的快进快退按钮、播放按钮、进度条;
  • 用代码动态修改画中画窗口的形状,横向、竖向 or 方形;
  • 用代码旋转画中画窗口;
  • 基于常驻线程的线程保活措施,让你的画中画永不停歇;
  • 拍照和录视频不会中断画中画;
  • 拍摄视频画中画的 timer 也不会停止;
  • 高精度timer;
  • 用代码控制进入后台自动开启画中画;

https://github.com/CaiWanFeng/CustomPictureInPicture

在锁屏封面上显示歌词,在歌词改变的时候把歌词和歌曲封面合成一张新图片作为歌曲封面。

iOS 音乐播放器之锁屏歌词+歌词解析+锁屏效果 - 简书

以上是关于iOS使用画中画展示后台歌词的主要内容,如果未能解决你的问题,请参考以下文章

iOS 14在FaceTime的5个改进:画中画1080p眼神修正等

为啥iOS启动片刻后画中画立即停止?

iOS 14中最喜欢的Safari功能:网页翻译和画中画

iOS 9 用于播放直播视频的画中画问题

SwiftUI:允许用户通过按下按钮启用画中画(iOS)

iPad开发-分屏画中画(即多任务处理增强功能)