在uitableview单元格中播放video

我正在尝试设置一个可以播放video的UITableView。 很多关于这个使用MPMoviePlayer的问题( 在UITableView中播放video,在SWIFT中播放video在UItableView中 播放video,在UITableView中播放video ),这在iOS 9中已经被弃用了。使用AVFoundation的less数人之一),是这样的: 在UITableViewCell播放video时,它是完全可见的,并且是我从中获取大部分代码的地方。 这里是我的代码,在cellForRowAtIndexPath:

VideoCell *videoCell = (VideoCell *)[self.tableView dequeueReusableCellWithIdentifier:@"VideoCell"]; dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); NSURL *url = [[NSURL alloc] initWithString:urlString]; dispatch_async(queue, ^{ videoCell.item = [AVPlayerItem playerItemWithURL:url]; dispatch_sync(dispatch_get_main_queue(), ^{ videoCell.player = [[AVPlayer alloc] initWithPlayerItem:videoCell.item]; videoCell.player.actionAtItemEnd = AVPlayerActionAtItemEndNone; AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:videoCell.player]; playerLayer.frame = CGRectMake(0, 0, videoCell.contentView.frame.size.width, videoCell.contentView.frame.size.height); [videoCell.contentView.layer addSublayer:playerLayer]; playerLayer.videoGravity = AVLayerVideoGravityResize; [videoCell.player play]; }); }); return videoCell; 

据我所知,我需要在播放video之前先asynchronous下载video。 我已经asynchronous下载图像之前,其中的“下载”部分总是涉及转换NSURL – > NSData – > UIImage。 然后当你有UIImage的时候,你已经准备好将它显示在单元格中,所以你把主要的队列和dispatch_async放在一起,然后执行cell.imageView.image = yourImage; 在主队列上。

在这里,我有一个NSURL,但是我不太清楚哪个步骤应该在主队列中,哪个步骤应该在主线程之外。 我尝试了上述SO问题中提到的内容,但到目前为止它并不能正常工作。 表格单元格刚刚加载,并且video从不播放。 我只看到第一帧。 有时它的前1秒会播放,但之后会缓冲,不会。 我正在使用仅有1个对象的表格视图,因此只有1个video可以播放,但仍然不能播放。

我做错了什么,有人可以帮我解释哪些部分需要在主线程上,哪些是closures的? 我在顶部提到的线程中的响应者说有“这里有很多教程”,但在扫描谷歌我没有看到任何。 术语“asynchronous”和“iOS”几乎总是获得关于图像下载的search结果,而不是video。 但是,如果有任何教程存在,将很高兴看到一个。

谢谢

以下是我用来在tableview单元格中播放video的方法。 我不知道这是最好的方法,无论如何它可以帮助你:)

首先,我创build了一个自定义单元格。 在setter方法中,我调用了一个设置AVPlayer的方法。

 - (void)setUpAVPlayer { @try { self.videoPlayer = [[AVPlayer alloc]initWithPlayerItem:self.videoPlayerItem]; } @catch (NSException *exception) { NSLog(@"Exception : %@",exception.description); [self.videoPlayer replaceCurrentItemWithPlayerItem:self.videoPlayerItem]; } // Setting player properties. playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.videoPlayer]; playerLayer.videoGravity = AVLayerVideoGravityResize; [self.previewImageView.layer addSublayer:playerLayer]; self.previewImageView.clipsToBounds = YES; playerLayer.hidden = YES; [playerLayer addObserver:self forKeyPath:@"readyForDisplay" options:0 context:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pauseAllRunningPlayers) name:@"pause" object:nil]; // AVPlayer KVO [self.videoPlayer addObserver:self forKeyPath:@"rate" options:NSKeyValueObservingOptionNew context:kRateDidChangeKVO]; [self.videoPlayer addObserver:self forKeyPath:@"currentItem.status" options:NSKeyValueObservingOptionNew context:kStatusDidChangeKVO]; [self.videoPlayer addObserver:self forKeyPath:@"currentItem.duration" options:NSKeyValueObservingOptionNew context:kDurationDidChangeKVO]; [self.videoPlayer addObserver:self forKeyPath:@"currentItem.loadedTimeRanges" options:NSKeyValueObservingOptionNew context:kTimeRangesKVO]; [self.videoPlayer addObserver:self forKeyPath:@"currentItem.playbackBufferFull" options:NSKeyValueObservingOptionNew context:kBufferFullKVO]; [self.videoPlayer addObserver:self forKeyPath:@"currentItem.playbackBufferEmpty" options:NSKeyValueObservingOptionNew context:kBufferEmptyKVO]; [self.videoPlayer addObserver:self forKeyPath:@"currentItem.error" options:NSKeyValueObservingOptionNew context:kDidFailKVO]; [videoLoadingIndicator stopAnimating]; } 

我发现在你的代码中你已经写了这样的播放function[videoCell.player play];

只有当播放器状态变为“AVPlayerStatusReadyToPlay”时,才应该调用播放function。 这就是为什么我使用KVO。

希望这可能会帮助你:)

只需在你的cellForRowAtIndexPath中添加下面的代码。

 player = [AVPlayer playerWithURL:media.lowResolutionVideoURL]; // layer = [AVPlayerLayer layer]; [layer setPlayer:player]; layer.frame = @"Your Frame"; [layer setBackgroundColor:[UIColor clearColor].CGColor]; [layer setVideoGravity:AVLayerVideoGravityResizeAspect]; [cell.contentView.layer addSublayer:layer]; [player play];