Search code examples
iosobjective-ciphonecocoa-touchios9

How to restore full screen video player after PictureInPicture


I'm using AVPlayerViewController with allowsPictureInPicturePlayback = YES;,

So when i click on the PictureInPicture button , the AVPlayerViewController will be dismissed and the small player will be showed ..

But when I click on the restore button in the small player, it will be closed without showing the AVPlayerViewController again ..

So how can I restore the AVPlayerViewController after clicking the restore button in the small player ??

My code:

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

@interface ViewController ()<AVPlayerViewControllerDelegate>{
    AVPlayerViewController *_AVPlayerViewController;
}

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
    [[AVAudioSession sharedInstance] setActive: YES error: nil];

    // create a movie player
    NSURL *url = [NSURL URLWithString:@"http://38.96.175.119:1935/aletejahtv/aletejahtv3/playlist.m3u8"];

    _AVPlayerViewController = [AVPlayerViewController new];
    _AVPlayerViewController.delegate = self;
    _AVPlayerViewController.showsPlaybackControls = YES;
    _AVPlayerViewController.allowsPictureInPicturePlayback = YES;
    _AVPlayerViewController.videoGravity = AVLayerVideoGravityResizeAspect;
    _AVPlayerViewController.player = [AVPlayer playerWithURL:url];
    [_AVPlayerViewController.player play];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self presentViewController:_AVPlayerViewController animated:YES completion:nil];
    });
}


- (void)playerViewControllerWillStartPictureInPicture:(AVPlayerViewController *)playerViewController{
    NSLog(@"playerViewControllerWillStartPictureInPicture");
}

- (void)playerViewControllerDidStartPictureInPicture:(AVPlayerViewController *)playerViewController{
    NSLog(@"playerViewControllerDidStartPictureInPicture");
}

- (void)playerViewController:(AVPlayerViewController *)playerViewController failedToStartPictureInPictureWithError:(NSError *)error{
    NSLog(@"failedToStartPictureInPictureWithError");
}

- (void)playerViewControllerWillStopPictureInPicture:(AVPlayerViewController *)playerViewController{
    NSLog(@"playerViewControllerWillStopPictureInPicture");
}

- (void)playerViewControllerDidStopPictureInPicture:(AVPlayerViewController *)playerViewController{
    NSLog(@"playerViewControllerDidStopPictureInPicture");
}

- (BOOL)playerViewControllerShouldAutomaticallyDismissAtPictureInPictureStart:(AVPlayerViewController *)playerViewController{
    return YES;
}

- (void)playerViewController:(AVPlayerViewController *)playerViewController restoreUserInterfaceForPictureInPictureStopWithCompletionHandler:(void (^)(BOOL restored))completionHandler{
    NSLog(@"restoreUserInterfaceForPictureInPictureStopWithCompletionHandler");
}

@end

Solution

  • I was able to solve this issue by using presentViewController: animated: in the playerViewController:restoreUserInterfaceForPictureInPictureStopWithCompletionHandler: in the delegate

    So it will represent the AVPlayerViewController again after it was dismissed before

    My new code:

    - (void)playerViewController:(AVPlayerViewController *)playerViewController restoreUserInterfaceForPictureInPictureStopWithCompletionHandler:(void (^)(BOOL restored))completionHandler{
        [self presentViewController:playerViewController animated:YES completion:nil];
        NSLog(@"restoreUserInterfaceForPictureInPictureStopWithCompletionHandler");
    }