Играет много разных видео на iphone, используя AVPlayer

Я работаю над пользовательским видеопроигрывателем для iOS, использующим AVFoundation. Идея состоит в том, чтобы иметь возможность переключиться на другое видео с жестом (коснитесь, проведите по экрану, что угодно). Сейчас игрок работает безупречно на симуляторе , но когда я тестирую его на реальном устройстве, представление исчезает после 3 или 4 щелчков. Я даже создал элементы управления воспроизведением для своего плеера, когда представление пуста, эти элементы управления загружаются правильно, но ничего не делают. Любые идеи парней? Это инициализация игрока

- (id)initWithContentURL:(NSString *)aContentURL delegate:(id)aDelegate { self = [super initWithNibName:@"NoCashMoviePlayer" bundle:nil]; if (self == nil) return nil; delegate = aDelegate; systemPath = [aContentURL retain]; contentURL = [[NSURL alloc]initFileURLWithPath:systemPath]; asset = [AVURLAsset URLAssetWithURL:contentURL options:nil]; playerItem = [AVPlayerItem playerItemWithAsset:asset]; isPaused = false; controlsHidden = false; self.player = [[AVPlayer playerWithPlayerItem:playerItem] retain]; duration = self.player.currentItem.asset.duration; return self; } 

Это код, который воспроизводит видео:

  -(void)playMovie{ UITapGestureRecognizer *tapRecon = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(toggleControls:)]; [tapRecon setNumberOfTapsRequired:2]; [self.movieContainer addGestureRecognizer:tapRecon]; [tapRecon release]; NSLog(@"Playing item: %@",contentURL); playerLayer = [AVPlayerLayer playerLayerWithPlayer:player]; [movieContainer.layer addSublayer:playerLayer]; playerLayer.frame = movieContainer.layer.bounds; playerLayer.videoGravity = AVLayerVideoGravityResizeAspect; self.seeker.alpha = 1.0; [self.view addSubview:movieContainer]; [self.movieContainer addSubview:controls]; [self setSlider]; [player play]; player.actionAtItemEnd = AVPlayerActionAtItemEndNone; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerItemDidReachEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:[player currentItem]]; } 

Код для выбора ролика, который нужно воспроизвести:

  -(void)viewSelect: (double) curTime{ self.myView.backgroundColor = [UIColor blackColor]; UISwipeGestureRecognizer *swipeRecognizer = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(handleSwipeFrom:)]; swipeRecognizer.direction = UISwipeGestureRecognizerDirectionRight; [self.myView addGestureRecognizer:swipeRecognizer]; [swipeRecognizer release]; UISwipeGestureRecognizer *leftRecognizer = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(handleSwipeFromLeft:)]; swipeRecognizer.direction = UISwipeGestureRecognizerDirectionLeft; [self.myView addGestureRecognizer:leftRecognizer]; [leftRecognizer release]; if(isMain){ [UIView animateWithDuration:0.5 delay:0.0 options:UIViewAnimationTransitionFlipFromLeft animations:^{ self.myView.alpha = 1.0; moviePlayer = [[NoCashMoviePlayer alloc]initWithContentURL:[self movieURL:vidIndex] delegate:self]; self.moviePlayer.view.frame = self.myView.bounds; self.moviePlayer.view.autoresizingMask = UIViewAutoresizingFlexibleWidth |UIViewAutoresizingFlexibleHeight; [self.myView addSubview:moviePlayer.view]; }completion:^(BOOL finished) { [self.moviePlayer.player seekToTime:CMTimeMake(curTime, 1)]; [self.moviePlayer playMovie]; }]; }else{ [UIView animateWithDuration:0.5 delay:0.0 options:UIViewAnimationTransitionFlipFromLeft animations:^{ self.otherView.alpha = 1.0; moviePlayer = [[NoCashMoviePlayer alloc]initWithContentURL:[self movieURL:vidIndex] delegate:self]; self.moviePlayer.view.frame = self.otherView.bounds; self.moviePlayer.view.autoresizingMask = UIViewAutoresizingFlexibleWidth |UIViewAutoresizingFlexibleHeight; [self.otherView addSubview:moviePlayer.view]; }completion:^(BOOL finished) { [self.moviePlayer.player seekToTime:CMTimeMake(curTime, 1)]; [self.moviePlayer playMovie]; }]; } } 

И последнее действие жеста:

  - (void)handleSwipeFromLeft:(UISwipeGestureRecognizer *)recognizer { double elapsedTime = 0.0; if(vidIndex==0){ vidIndex = 3; }else vidIndex = vidIndex --; elapsedTime = [self.moviePlayer currentTimeInSeconds]; [self.moviePlayer stopMovie]; isMain = !isMain; [self viewSelect: elapsedTime]; } 

EDIT: Пробовал использовать разные AVPlayerLayers для каждого видеофайла, такая же ситуация, работает в симуляторе, а не на iPad.

EDIT 2: Я запускал инструменты для анализа производительности основной анимации, и когда видео воспроизводится, он показывает частоты кадров около 30 кадров в секунду, когда проигрыватель гаснет, он полностью опускается до 1 или 2 кадра в секунду. Это может быть неприятно, но все же, если это помогает дать немного больше света …..

EDIT 3: Хорошо, я наконец-то добираюсь куда-нибудь, я знаю, в чем проблема, у меня есть основная утечка памяти памяти, в симуляторе это «работает», потому что на компьютере больше памяти, чем у iPad, но с iPad имеет очень ограниченную память, она перестает работать очень быстро. Если у кого-нибудь есть какие-либо рекомендации относительно утечек Core Animation, он будет очень хорошо принят.

Я ПОЛНОСТЬЮ РЕШЕН ЭТО. Дизайн, который у меня был, был действительно очень беден, у него было очень плохое управление памятью и так далее. То, что я сделал, вместо того, чтобы выпускать все, что я мог, включая взгляды, слои, игроки, активы и т. Д., Я только что создал метод обновления активов и предмета игрока, повторного использования проигрывателя, просмотров, слоев и т. Д.

  [player pause]; contentURL = [[NSURL alloc] initFileURLWithPath:newPath]; AVAsset *newAsset = [AVURLAsset URLAssetWithURL:contentURL options:nil]; AVPlayerItem *newPlayerItem = [AVPlayerItem playerItemWithAsset:newAsset]; [player replaceCurrentItemWithPlayerItem:newPlayerItem]; [contentURL release]; 

И теперь это творит чудеса. Спасибо за вашу помощь.

В коде есть 2 места, где вы сохранили объект, и я не вижу соответствующий релиз в любом месте кода, который вы опубликовали. Я бы начал, убедившись, что счетчик ссылок на память увеличивается и уменьшается, все соответственно сбалансированы.

Первое удержание выглядит подозрительным для меня. Обычно вы должны сначала авторезистировать переменную, которую вы назначаете, а затем сохранить следующим образом:

 [systemPath autorelease]; systemPath = [aContentURL retain] 

В приведенном выше коде легко видеть, что согласование сохранения / выпуска поддерживается и гораздо менее подвержено ошибкам, чем другие схемы. Обратите внимание, что если systemPath == aContentURL объект не будет выпущен.

  • как удалить subviews из scrollview?
  • как правильно использовать insertRowsAtIndexPaths?
  • Игнорировать все предупреждения в определенном файле, используя LLVM / Clang
  • Отключить приглашение администратора сервера Mac OS X?
  • AppDelegate, rootViewController и presentViewController
  • «Запустить> Остановить на исключении Objective-C» в Xcode 4?
  • Компилировать программы OpenMP с помощью gcc-компилятора в OS X Yosemite
  • xcode 4.5 как выбрать раскадровки при запуске
  • Как создать задержку в Swift?
  • Ошибка кодового знака в macOS High Sierra Xcode - ресурс fork, информация Finder или подобный детрит не разрешены
  • Простой пример XML-анализа libxml2 с использованием Objective-c, Xcode и HTMLparser.h
  • Давайте будем гением компьютера.