美文网首页音视频UII love iOS
iOS画中画播放视频

iOS画中画播放视频

作者: BoxJing | 来源:发表于2021-09-28 16:12 被阅读0次

    画中画功能iOS9就有了,以前只能在iPad上使用,iOS14开始在iPhone上也可以使用了,一直没有这方面的需求也没有具体的研究,不过毕竟是苹果官方的东西,相信实现起来不会麻烦,有2种办法来实现。前提都需要工程配置一定要对!!!

    工程配置

    配置BackgroundMode
    //  开启后台播放权限
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionAllowBluetooth error:nil];
    [[AVAudioSession sharedInstance] setActive:YES error:nil];
    

    1. 使用AVPlayerViewController

    如果使用的是AVPlayerViewController,只要AVAudioSessionBackgroundMode配置对就默认支持的,不用做其他任何操作。虽然很简单,但是相信很少人会直接用这个方式,几乎所有的项目都会自定义播放器,而不是直接使用系统的这个全屏播放器。

    2. 使用AVPictureInPictureController

    使用AVPictureInPictureController承接自己写的播放器的AVPlayerLayer即可实现,先放出来一个官方链接。可以直接去看相关API。
    在API中可以看到有一个根据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并且启动画中画,后来实测发现这样是行不通,初始化AVPictureInPictureController的动作必须提前,然后在需要开启或者停止画中画功能,下面的代码是实现了在播放视频的时候已经初始化了AVPictureInPictureController,然后在应用将要退到后台的时候开启画中画播放视频,用户回到前台后停止画中画,AVPictureInPictureControllerDelegate中有一些相关的代理方法,全是可选实现,基本上用不到,可以根据自己的需要进行实现:

    #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];
    //   监听实现循环播放
        [[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 -------播放属性监听--------
    - (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,需要将实现ZFPlayerMediaPlayback协议的PlayerManager,将内部的avLayer抛出来,然后用这个layer来初始化AVPictureInPictureController即可。

    以上就是项目中简单实现画中画播放视频的完整流程

    相关文章

      网友评论

        本文标题:iOS画中画播放视频

        本文链接:https://www.haomeiwen.com/subject/poqrnltx.html