Я работаю над пользовательским видеоплеером для 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];
}
РЕДАКТИРОВАТЬ: Попытка использовать разные AVPlayerLayers для каждого видеофайла, та же ситуация, работает в симуляторе, а не на iPad.
РЕДАКТИРОВАТЬ 2: Я запускал инструменты для анализа производительности основной анимации, и когда воспроизводится видео, оно показывает частоту кадров около 30 кадров в секунду, когда проигрыватель гаснет, он падает до 1 или 2 кадров в секунду. Это может быть многословно, но все же, если это поможет дать немного больше света .....
РЕДАКТИРОВАТЬ 3: Хорошо, я наконец-то что-то получаю, я знаю, в чем проблема, у меня утечка памяти основной анимации, в симуляторе это "работает", потому что у компьютера НАМНОГО больше памяти, чем у iPad, но поскольку у iPad очень ограниченная память, он перестает работать очень быстро. Если у кого-нибудь есть какой-либо совет относительно утечек в Core Animation, он будет очень хорошо принят.