0

I have an app that plays local videos using the AVPlayerViewController. But when the video has finished playing I want it to close automatically (like the MPMoviePlayerViewController used to do).

After posting this question, I managed to solve this partially thanks to the answers below and partially from Apples "Guides and Sample code".

This is the code that worked for me:

#import "ViewController.h"
@import AVFoundation;
@import AVKit;


@interface ViewController ()

@property(nonatomic, readonly) AVPlayerItem *currentItem;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

-(void)playerItemDidReachEnd:(NSNotification *) notification {
    //remove the player
   [self dismissViewControllerAnimated:YES completion:nil];
}

- (IBAction)playVideo:(id)sender {

    // grab a local URL to our video
    NSURL *videoURL = [[NSBundle mainBundle]URLForResource:@"bagare" withExtension:@"mp4"];

    // create an AVPlayer
    AVPlayer *player = [AVPlayer playerWithURL:videoURL];

    // create a player view controller
    AVPlayerViewController *controller = [[AVPlayerViewController alloc]init];
    controller.player = player;
    [player play];
    [self presentViewController:controller animated:YES completion:nil];

    // show the view controller
      controller.view.frame = self.view.frame;

    [[NSNotificationCenter defaultCenter] addObserver:self
    selector:@selector(playerItemDidReachEnd:)
    name:AVPlayerItemDidPlayToEndTimeNotification
    object:_currentItem];

  }

@end
EmmyG
  • 23
  • 1
  • 10
  • The code in my question works great with dismissing one video, But, I encountered a problem when I added more videos and copy/pasted the code: The first video is dismissed the way I want it to, but when the second video has finished playing it jumps back to the first view controller, instead of the second VC where the videos are displayed and played (it shows the second VC for one second). This doesn’t happen if i close the videos by pressing ”Done”. Does anyone have a solution for this? – EmmyG Aug 26 '16 at 14:47

3 Answers3

3
NSURL *url=[NSURL URLWithString:@"URLLINK"];
AVAsset *avAsset = [AVAsset assetWithURL:url];
AVPlayerItem *playerItem = [[AVPlayerItem alloc]initWithAsset:avAsset];

Subscribe to the AVPlayerItem's DidPlayToEndTime notification.

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemDidFinishPlaying:) name:AVPlayerItemDidPlayToEndTimeNotification object:playerItem];

Pass the AVPlayerItem to a new player

 AVPlayer *player = [AVPlayer playerWithURL:videoURL]
   AVPlayerViewController *controller=[[AVPlayerViewController alloc]init];
    controller.player=player;
    [player play];
    [self presentViewController:controller animated:YES completion:nil];

Here remove Player dismiss or Player added view

-(void)itemDidFinishPlaying:(NSNotification *) notification {
[self dismissViewControllerAnimated:YES completion:nil];
    [[NSNotificationCenter defaultCenter]removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:playerItem];
}
Yogendra Girase
  • 631
  • 3
  • 15
  • I managed to get it to work, with help from your answer and Apples Guides an Sample Code. I posted the code that worked for me in the original question. However, I encountered another problem when I added more videos and copy/pasted the code: The first video is dismissed the way I want it to, but when the second video has finished playing it jumps back to the first view controller, instead of the second where the videos are displayed (it shows the second VC for one second). This doesn’t happen if i close the videos by pressing ”Done”. Do you have any idea why, and how to solve it? – EmmyG Aug 26 '16 at 14:44
2

This should work:

[[NSNotificationCenter defaultCenter] addObserver:self 
    selector:@selector(videoDidFinish:) 
    name:AVPlayerItemDidPlayToEndTimeNotification
    object:[controller.player currentItem]];

- (void)videoDidFinish:(id)notification
{
    AVPlayerItem *p = [notification object];
    //do something with player if you want

    [[NSNotificationCenter defaultCenter] removeObserver:self];

    //fade out / remove subview
}
jacob bullock
  • 651
  • 4
  • 14
  • I managed to get it to work, with help from your answer and Apples Guides an Sample Code. I posted the code that worked for me in the original question. However, I encountered another problem when I added more videos and copy/pasted the code: The first video is dismissed the way I want it to, but when the second video has finished playing it jumps back to the first view controller, instead of the second where the videos are displayed (it shows the second VC for one second). This doesn’t happen if i close the videos by pressing ”Done”. Do you have any idea why, and how to solve it? – EmmyG Aug 26 '16 at 14:44
  • You have to remove the listener as shown in the example here. In your updated code, the first VC is still a registered observer – jacob bullock Aug 26 '16 at 20:32
  • Worked great! Thank you! – EmmyG Aug 29 '16 at 08:29
0

In .h file

@property(nonatomic, strong)AVPlayerViewController *controller;

In .m file:

  - (IBAction)playVideo:(id)sender {

    // grab a local URL to our video
    NSURL *videoURL = [[NSBundle mainBundle]URLForResource:@"bagare" withExtension:@"mp4"];

    // create an AVPlayer
    AVPlayer *player = [AVPlayer playerWithURL:videoURL];

    // create a player view controller
    self.controller = [[AVPlayerViewController alloc]init];
    controller.player = player;
    [player play];
    [self presentViewController:controller animated:YES completion:nil];

    // show the view controller
      controller.view.frame = self.view.frame;

    [[NSNotificationCenter defaultCenter] addObserver:self
    selector:@selector(playerItemDidReachEnd:)
    name:AVPlayerItemDidPlayToEndTimeNotification
    object:_currentItem];

  }

And for dismiss:

- (void)playerItemDidReachEnd:(NSNotification *)notification {
    [self.controller dismissViewControllerAnimated:YES completion:nil];
}
Tejas Ardeshna
  • 4,343
  • 2
  • 20
  • 39