使用AVPlayer在uitableview中播放多个视频

时间:2013-05-09 07:37:46

标签: uitableview avplayer vine

我在UITableView中有多个视频。 我想做藤蔓的饲料。 滚动到视频时自动播放视频 我使用AVPlyer来做到这一点。 但是我发现当两个视频切换时它并不是那么顺利 谁能提出一些建议?

这是我的tableViewController的observeValueForKeyPath,我用它来做视频切换;

[oldCell cleanupMoviePlayer]会做一些干净的工作(用于清理视图删除一些观察者)

[(MOVideoPlayer_AVPlayer *)newItem startPlay]会做一些初始化和设置(设置AVPlayerItem并播放)

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{


    id newItem = [change objectForKey:NSKeyValueChangeNewKey];
    id oldCell = [change objectForKey:NSKeyValueChangeOldKey];
    if (oldCell == (id)[NSNull null]) {

    } else if([oldCell isKindOfClass:[MOVideoPlayer_AVPlayer class]]) {
        [oldCell cleanupMoviePlayer];

    }

    if ([newItem isKindOfClass:[MOVideoPlayer_AVPlayer class]]) {
        [(MOVideoPlayer_AVPlayer*)newItem startPlay];
    }


}

-(void) startPlay
{    
    willStartePlay = YES;

    double delayInSeconds = 0.5;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){

        [self.indicator startAnimating];

        if (isClearnup) {
            return;
        }

        NSString *videoFilePath =[NSString stringWithFormat:@"%@%@",NSTemporaryDirectory(),[self.post.video_url lastPathComponent]];
        //NSLog(@"the videoFilePath is %@",videoFilePath);

            NSFileManager *fileManager = [NSFileManager defaultManager];
            if (![fileManager fileExistsAtPath:videoFilePath]) {
                NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:self.post.video_url]];
                NSLog(@"post.video_url:%@",self.post.video_url);
                downloadOperation = [[AFDownloadRequestOperation alloc] initWithRequest:request targetPath:videoFilePath shouldResume:NO];
                [downloadOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {

                    if ([fileManager fileExistsAtPath:videoFilePath]) {
                        [self createAndPlayMovieForURL:[NSURL fileURLWithPath:videoFilePath] sourceType:MPMovieSourceTypeFile];
                    }


                } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
                    NSLog(@"the error is %@",error);
                    NSLog(@"%@",operation.description);
                    dispatch_async(dispatch_get_main_queue(), ^{
                        [self.indicator stopAnimating];

            });
            }];
                [downloadOperation start];

            } else {

                [self createAndPlayMovieForURL:[NSURL fileURLWithPath:videoFilePath] sourceType:MPMovieSourceTypeFile];
            }


    });



}



-(void)createAndPlayMovieForURL:(NSURL *)movieURL sourceType:(MPMovieSourceType)sourceType
{

    if (isClearnup) {
        return;
    }

    AVURLAsset *asset = [AVURLAsset URLAssetWithURL:movieURL options:nil];
    NSArray *requestedKeys = [NSArray arrayWithObjects: kPlayableKey, nil];
    [asset loadValuesAsynchronouslyForKeys:requestedKeys completionHandler:^{
        dispatch_async(dispatch_get_main_queue(), ^{
            [self prepareToPlayAsset:asset withKeys:requestedKeys];
        });
    }];


}


-(void)prepareToPlayAsset:(AVURLAsset *)asset withKeys:(NSArray *)requestedKeys
{


    if (isClearnup) {
        return;
    }

    for (NSString *thisKey in requestedKeys)
    {
        NSError *error = nil;
        AVKeyValueStatus keyStatus = [asset statusOfValueForKey:thisKey error:&error];
        if (keyStatus == AVKeyValueStatusFailed)
        {

            return;
        }

    }

    if (!asset.playable) {
        return;
    }

    if (self.currentPlayerItem) {
        [self.currentPlayerItem removeObserver:self forKeyPath:kStatusKey context:MOAVPlayerStatusObservationContext];
        [[NSNotificationCenter defaultCenter] removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:self.currentPlayerItem];
    }


    self.currentPlayerItem = [AVPlayerItem playerItemWithAsset:asset];
    [self.currentPlayerItem addObserver:self
                             forKeyPath:kStatusKey
                                options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
                                context:MOAVPlayerStatusObservationContext];

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


    if (!self.player) {
        self.player = [AVPlayer playerWithPlayerItem:self.currentPlayerItem];


        [self.player addObserver:self
                       forKeyPath:kCurrentItemKey
                          options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
                          context:MOAVPlayerCurrentItemObservationContext];



        /* Observe the AVPlayer "rate" property to update the scrubber control. */
        [self.player addObserver:self
                       forKeyPath:kRateKey
                          options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
                          context:MOAVPlayerRateObservationContext];


    } 

    if (self.player.currentItem != self.currentPlayerItem) {
        [self.player replaceCurrentItemWithPlayerItem:self.currentPlayerItem];

    }



}


-(void)playerItemDidReachEnd:(NSNotification*)notication
{
    [self.player seekToTime:kCMTimeZero];
    [self.player play];
}


-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{

    if (context == MOAVPlayerStatusObservationContext) {

        AVPlayerStatus status = [[change objectForKey:NSKeyValueChangeNewKey] integerValue];
        switch (status) {
            case AVPlayerStatusUnknown:
            {
                //NSLog(@"AVPlayerStatusUnknown");
            }

                break;
            case AVPlayerStatusReadyToPlay:
            {
                NSLog(@"AVPlayerStatusReadyToPlay");
                [self.player play];
            }
                break;
            case AVPlayerStatusFailed:
            {
                //NSLog(@"AVPlayerStatusFailed");
            }
                break;
        }
    } else if (context == MOAVPlayerRateObservationContext) {

        //NSLog(@"MOAVPlayerRateObservationContext");

    } else if (context == MOAVPlayerCurrentItemObservationContext){

       // NSLog(@"CurrentItem change");
        AVPlayerItem *newPlayerItem = [change objectForKey:NSKeyValueChangeNewKey];

        if(newPlayerItem == (id)[NSNull null]){
            // newPlayeritem is null?
            //NSLog(@"newPlayerItem IS null");

        } else {


            //self.playerView.frame = self.backgroundImageView.frame;

            //[self addSubview:self.playerView];

            if (isClearnup) {
                return;
            }

            isStartePlay = YES;

            double delayInSeconds = 0.2;
            dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
            dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
                //self.playerView.player = self.player;
                [self.indicator stopAnimating];
                //[self.playerView setVideoFillMode:AVLayerVideoGravityResizeAspect];
                //dispatch_async(dispatch_get_main_queue(), ^{
                  //  [self.player play];
                    self.playerView.player = self.player;
                //});
                //

            });




        }

    }  else {

        [super observeValueForKeyPath:keyPath  ofObject:object change:change context:context];
    }



}


-(void)cleanupMoviePlayerView
{

    //[self.playerView removeFromSuperview];
    self.playerView.player = nil;
    //[self.moviePlayer.view removeFromSuperview];
    //[self.maskView removeFromSuperview];
}

-(void)handleTap:(UITapGestureRecognizer*)tapGestureRecognizer;
{

    if (interrupted) {
        return;
    }
   // NSLog(@"tapGestureRecognizer");
    if (isplaying) {
        [self.moviePlayer pause];
    } else {
        [self.moviePlayer play];
    }



}

// Remove the movie notification observers from the movie object.
-(void)removeMovieNotificationHandlers
{

    [[NSNotificationCenter defaultCenter] removeObserver:self];

    }


-(void) cleanupMoviePlayer
{

    if (willStartePlay && isStartePlay) {
        [self.player seekToTime:kCMTimeZero];
        //[self.moviePlayer stop];
        [self cleanupMoviePlayerView];
        [self removeMovieNotificationHandlers];
    }

    isClearnup = YES;


}

-(void)prepareForReuse
{
    willStartePlay = isStartePlay = isClearnup = NO;
}

-(void) startPlay { willStartePlay = YES; double delayInSeconds = 0.5; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ [self.indicator startAnimating]; if (isClearnup) { return; } NSString *videoFilePath =[NSString stringWithFormat:@"%@%@",NSTemporaryDirectory(),[self.post.video_url lastPathComponent]]; //NSLog(@"the videoFilePath is %@",videoFilePath); NSFileManager *fileManager = [NSFileManager defaultManager]; if (![fileManager fileExistsAtPath:videoFilePath]) { NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:self.post.video_url]]; NSLog(@"post.video_url:%@",self.post.video_url); downloadOperation = [[AFDownloadRequestOperation alloc] initWithRequest:request targetPath:videoFilePath shouldResume:NO]; [downloadOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { if ([fileManager fileExistsAtPath:videoFilePath]) { [self createAndPlayMovieForURL:[NSURL fileURLWithPath:videoFilePath] sourceType:MPMovieSourceTypeFile]; } } failure:^(AFHTTPRequestOperation *operation, NSError *error) { NSLog(@"the error is %@",error); NSLog(@"%@",operation.description); dispatch_async(dispatch_get_main_queue(), ^{ [self.indicator stopAnimating]; }); }]; [downloadOperation start]; } else { [self createAndPlayMovieForURL:[NSURL fileURLWithPath:videoFilePath] sourceType:MPMovieSourceTypeFile]; } }); } -(void)createAndPlayMovieForURL:(NSURL *)movieURL sourceType:(MPMovieSourceType)sourceType { if (isClearnup) { return; } AVURLAsset *asset = [AVURLAsset URLAssetWithURL:movieURL options:nil]; NSArray *requestedKeys = [NSArray arrayWithObjects: kPlayableKey, nil]; [asset loadValuesAsynchronouslyForKeys:requestedKeys completionHandler:^{ dispatch_async(dispatch_get_main_queue(), ^{ [self prepareToPlayAsset:asset withKeys:requestedKeys]; }); }]; } -(void)prepareToPlayAsset:(AVURLAsset *)asset withKeys:(NSArray *)requestedKeys { if (isClearnup) { return; } for (NSString *thisKey in requestedKeys) { NSError *error = nil; AVKeyValueStatus keyStatus = [asset statusOfValueForKey:thisKey error:&error]; if (keyStatus == AVKeyValueStatusFailed) { return; } } if (!asset.playable) { return; } if (self.currentPlayerItem) { [self.currentPlayerItem removeObserver:self forKeyPath:kStatusKey context:MOAVPlayerStatusObservationContext]; [[NSNotificationCenter defaultCenter] removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:self.currentPlayerItem]; } self.currentPlayerItem = [AVPlayerItem playerItemWithAsset:asset]; [self.currentPlayerItem addObserver:self forKeyPath:kStatusKey options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:MOAVPlayerStatusObservationContext]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerItemDidReachEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.currentPlayerItem]; if (!self.player) { self.player = [AVPlayer playerWithPlayerItem:self.currentPlayerItem]; [self.player addObserver:self forKeyPath:kCurrentItemKey options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:MOAVPlayerCurrentItemObservationContext]; /* Observe the AVPlayer "rate" property to update the scrubber control. */ [self.player addObserver:self forKeyPath:kRateKey options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:MOAVPlayerRateObservationContext]; } if (self.player.currentItem != self.currentPlayerItem) { [self.player replaceCurrentItemWithPlayerItem:self.currentPlayerItem]; } } -(void)playerItemDidReachEnd:(NSNotification*)notication { [self.player seekToTime:kCMTimeZero]; [self.player play]; } -(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if (context == MOAVPlayerStatusObservationContext) { AVPlayerStatus status = [[change objectForKey:NSKeyValueChangeNewKey] integerValue]; switch (status) { case AVPlayerStatusUnknown: { //NSLog(@"AVPlayerStatusUnknown"); } break; case AVPlayerStatusReadyToPlay: { NSLog(@"AVPlayerStatusReadyToPlay"); [self.player play]; } break; case AVPlayerStatusFailed: { //NSLog(@"AVPlayerStatusFailed"); } break; } } else if (context == MOAVPlayerRateObservationContext) { //NSLog(@"MOAVPlayerRateObservationContext"); } else if (context == MOAVPlayerCurrentItemObservationContext){ // NSLog(@"CurrentItem change"); AVPlayerItem *newPlayerItem = [change objectForKey:NSKeyValueChangeNewKey]; if(newPlayerItem == (id)[NSNull null]){ // newPlayeritem is null? //NSLog(@"newPlayerItem IS null"); } else { //self.playerView.frame = self.backgroundImageView.frame; //[self addSubview:self.playerView]; if (isClearnup) { return; } isStartePlay = YES; double delayInSeconds = 0.2; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ //self.playerView.player = self.player; [self.indicator stopAnimating]; //[self.playerView setVideoFillMode:AVLayerVideoGravityResizeAspect]; //dispatch_async(dispatch_get_main_queue(), ^{ // [self.player play]; self.playerView.player = self.player; //}); // }); } } else { [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } } -(void)cleanupMoviePlayerView { //[self.playerView removeFromSuperview]; self.playerView.player = nil; //[self.moviePlayer.view removeFromSuperview]; //[self.maskView removeFromSuperview]; } -(void)handleTap:(UITapGestureRecognizer*)tapGestureRecognizer; { if (interrupted) { return; } // NSLog(@"tapGestureRecognizer"); if (isplaying) { [self.moviePlayer pause]; } else { [self.moviePlayer play]; } } // Remove the movie notification observers from the movie object. -(void)removeMovieNotificationHandlers { [[NSNotificationCenter defaultCenter] removeObserver:self]; } -(void) cleanupMoviePlayer { if (willStartePlay && isStartePlay) { [self.player seekToTime:kCMTimeZero]; //[self.moviePlayer stop]; [self cleanupMoviePlayerView]; [self removeMovieNotificationHandlers]; } isClearnup = YES; } -(void)prepareForReuse { willStartePlay = isStartePlay = isClearnup = NO; }

0 个答案:

没有答案