使用 AVPlayer 在 iphone 上播放许多不同的视频 [英] Playing many different videos on iphone using AVPlayer

查看:14
本文介绍了使用 AVPlayer 在 iphone 上播放许多不同的视频的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 AVFoundation 开发适用于 iOS 的自定义视频播放器.这个想法是能够通过手势(点击、滑动等)切换到不同的视频.现在播放器在模拟器上完美运行,但是当我在实际设备上测试它时,在 3 或 4 次滑动后视图变为空白.我什至为我的播放器创建了播放控件,当视图变为空白时,这些控件正确加载但什么也不做.有什么想法吗?这是播放器的初始化

I'm working on a custom video player for iOS using AVFoundation. The idea is to be able to switch to a different video with a gesture (tap, swipe, whatever). Right now the player is working flawlessly on simulator, but when I test it on an actual device, the view goes blank after 3 or 4 swipes. I've even created playback controls for my player, when the view goes blank, these controls load correctly but do nothing. Any ideas guys? This is the initialization for the player

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


    }

选择要播放的剪辑的代码:

The code to select the clip to be played:

    -(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 上.

Tried using different AVPlayerLayers for each video file, same situation, works in the simulator, not on the iPad.

编辑 2:我运行仪器来分析核心动画性能,当播放视频时,它显示的帧速率约为 30 fps,当播放器变为空白时,它会一直下降到 1 或 2 fps.这可能是显而易见的,但是,如果它有助于提供更多的光.....

EDIT 2: I ran instruments to analyze core animation performance, and when the video is playing it's showing framerates of about 30 fps, when the player goes blank it drops all the way down to 1 or 2 fps. This may be ovbious, but still, if it helps give a little more light.....

编辑 3:好的,我终于到了某个地方,我知道问题是什么,我有一个核心动画内存泄漏,在模拟器中它有效",因为计算机的内存比 iPad 多很多,但是由于 iPad 的内存非常有限,它很快就会停止工作.如果有人对 Core Animation 泄漏有任何建议,将会很受欢迎.

EDIT 3: Ok, I'm finally getting somewhere, I know what the problem is, I have a core animation memory leak, in the simulator it "works" because the computer has A LOT more memory than the iPad, but since the iPad has very limited memory it stops working very quickly. If anyone has any advice regarding Core Animation leaks, it will be very well received.

推荐答案

我终于解决了.我的设计确实很糟糕,它有一个非常糟糕的内存管理等等.我所做的是,我没有释放我能释放的一切,包括视图、图层、播放器、资产等,我只是创建了一个方法来更新播放器的资产和物品,回收播放器、视图、图层等.

I FINALLY SOLVED IT. The design I had was indeed very poor, It had a very bad memory management and so on. What I did was, instead of releasing everything I could, including views, layers, players, assets, etc, I just created a method to update the player's asset and item, recycling the player, views, layers, etc.

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

现在它正在创造奇迹.谢谢大家的帮助.

And now it's working wonders. Thank you all for your help.

这篇关于使用 AVPlayer 在 iphone 上播放许多不同的视频的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆