本文介绍了应用程序变为活动状态后恢复AVPlayer视频播放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从AVPlayer编写自定义播放器以进行视频播放。根据Apple docs设置的视频图层:

I write custom player from AVPlayer for video playback. According to Apple docs set the video layer:

    self.player = [IPLPlayer new];
    self.player.playerLayer = (AVPlayerLayer *)self.playerView.layer;

其中self.playerView是这些文档的常用类:

Where self.playerView is usual class from those docs:

    @implementation PlayerView

+ (Class) layerClass {
    return [AVPlayerLayer class];
}

- (AVPlayer *)player {
    return [(AVPlayerLayer *)[self layer] player];
}

- (void)setPlayer:(AVPlayer *) player {
    [(AVPlayerLayer *) [self layer] setPlayer:player];
}

问题是:
当关闭应用程序(主页按钮)时,或阻止屏幕,视频播放停止,当恢复仅播放音频播放时,屏幕上的图像仍然是块屏幕之前的图像 - 它是完全静态的并且记录更改帧。

The problem is:When close app (Home button), or block screen, the video playback is stopped, and when resume ONLY audio playback resumed, the image on screen is still those was before block screen - it's fully static and note change frames.

如何在屏幕被屏蔽后恢复视频播放?

似乎我必须注册通知,并在应用变为活动后恢复视频图层:

Seems I must to register notifications, and after app become active resume video layer:

    -(void)registerNotification
{
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(willEnterBackground)
                                                 name:UIApplicationWillResignActiveNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(didEnterForeground)
                                                 name:UIApplicationDidBecomeActiveNotification object:nil];
}

-(void)unregisterNotification
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}


-(void)willEnterBackground
{
    NSLog(@"willEnterBackground");
    [self.playerView willEnterBackground];
}

-(void)didEnterForeground
{
    NSLog(@"didEnterForeground");
    [self.playerView didEnterForeground];
}


推荐答案

一个解决所有问题的解决方案这些信息在一起。

And one solution that binds all this information together.

也许播放器状态应该以不同方式处理,但我喜欢递归方式。

Maybe player status should be handled differently, but I like the recursive way.

注意:如果您不需要确切的搜索时间,可以使用 [_ player seekToTime:<#(CMTime)#> completionHandler:<#^(BOOL已完成)completionHandler#>] 它更快,但它会寻找最近的关键帧。

Note: If you do not need the exact seek time, you can use [_player seekToTime:<#(CMTime)#> completionHandler:<#^(BOOL finished)completionHandler#>] It's faster but it seeks to the nearest key frame.

- (void)viewDidLoad
{
    [super viewDidLoad];

....

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appEnteredForeground) name:UIApplicationWillEnterForegroundNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appEnteredBackground) name:UIApplicationDidEnterBackgroundNotification object:nil];
}

-(void)viewWillDisappear:(BOOL)animated
{
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillEnterForegroundNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil];
}

....

-(void) appEnteredForeground {
    AVPlayerLayer *player = (AVPlayerLayer *)[playerView layer];
    [player setPlayer:NULL];
    [player setPlayer:_player];
    [self playAt:currentTime];
}

-(void) appEnteredBackground {
    [_player pause];
    currentTime = [_player currentTime];
}

-(void)playAt: (CMTime)time {
    if(_player.status == AVPlayerStatusReadyToPlay && _player.currentItem.status == AVPlayerItemStatusReadyToPlay) {
        [_player seekToTime:time toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero completionHandler:^(BOOL finished) {
            [_player play];
        }];
    } else {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [self playAt:time];
        });
    }
}

这篇关于应用程序变为活动状态后恢复AVPlayer视频播放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-04 22:48