Как автоматически закрыть AVPlayer после завершения воспроизведения?

У меня есть приложение, которое воспроизводит локальные видео с помощью AVPlayerViewController. Но когда видео закончилось, я хочу, чтобы оно закрывалось автоматически (как это делал MPMoviePlayerViewController).

После публикации этого вопроса мне удалось частично решить эту проблему благодаря ответам ниже и частично из «Руководства и примера кода» Apple.

Это код, который работал для меня:

#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

person Johan Grip    schedule 26.08.2016    source источник
comment
Код в моем вопросе отлично работает с удалением одного видео, но я столкнулся с проблемой, когда добавил больше видео и скопировал/вставил код: первое видео удаляется так, как я хочу, но когда второе видео закончило воспроизведение он возвращается к первому контроллеру представления вместо второго VC, где отображаются и воспроизводятся видео (он показывает второй VC в течение одной секунды). Этого не произойдет, если я закрою видео, нажав «Готово». У кого-нибудь есть решение для этого?   -  person Johan Grip    schedule 26.08.2016


Ответы (3)


Это должно работать:

[[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
}
person jacob bullock    schedule 26.08.2016
comment
Мне удалось заставить его работать с помощью вашего ответа и Apples Guides a Sample Code. Я разместил код, который работал у меня в исходном вопросе. Однако я столкнулся с другой проблемой, когда добавил больше видео и скопировал/вставил код: первое видео закрывается так, как я хочу, но когда второе видео завершает воспроизведение, оно возвращается к первому контроллеру представления, а не к первому. второй, где отображаются видеоролики (показывает второй ВК на одну секунду). Этого не произойдет, если я закрою видео, нажав «Готово». Есть ли у вас какие-либо идеи, почему, и как это решить? - person Johan Grip; 26.08.2016
comment
Вы должны удалить прослушиватель, как показано в примере здесь. В вашем обновленном коде первый VC по-прежнему является зарегистрированным наблюдателем. - person jacob bullock; 26.08.2016
comment
Работал отлично! Благодарю вас! - person Johan Grip; 29.08.2016

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

Подпишитесь на уведомление DidPlayToEndTime от AVPlayerItem.

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

Передать AVPlayerItem новому игроку

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

Здесь удалить вид "Отклонить игрока" или "Добавить игрока"

-(void)itemDidFinishPlaying:(NSNotification *) notification {
[self dismissViewControllerAnimated:YES completion:nil];
    [[NSNotificationCenter defaultCenter]removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:playerItem];
}
person Yogendra Girase    schedule 26.08.2016
comment
Мне удалось заставить его работать с помощью вашего ответа и Apples Guides a Sample Code. Я разместил код, который работал у меня в исходном вопросе. Однако я столкнулся с другой проблемой, когда добавил больше видео и скопировал/вставил код: первое видео закрывается так, как я хочу, но когда второе видео завершает воспроизведение, оно возвращается к первому контроллеру представления, а не к первому. второй, где отображаются видеоролики (показывает второй ВК на одну секунду). Этого не произойдет, если я закрою видео, нажав «Готово». Есть ли у вас какие-либо идеи, почему, и как это решить? - person Johan Grip; 26.08.2016

В файле .h

@property(nonatomic, strong)AVPlayerViewController *controller;

В файле .m:

  - (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];

  }

И для увольнения:

- (void)playerItemDidReachEnd:(NSNotification *)notification {
    [self.controller dismissViewControllerAnimated:YES completion:nil];
}
person Tejas Ardeshna    schedule 26.08.2016