joe*_*oey 5 avfoundation uitableview ios
我正在尝试设置一个可以播放视频的UITableView。许多在此使用MPMoviePlayer(以前做题播放视频到UITableView的,在SWIFT播放视频的UITableView,播放视频从UITableView的),现在已不建议在iOS版9为数不多的以使用过AVFoundation(什么我使用),是这样的:当UITableViewCell完全可见并且是我从中获取大部分代码的地方时,播放视频。这是我的代码,位于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;
Run Code Online (Sandbox Code Playgroud)
据我了解,在播放视频之前,我需要异步下载视频。我以前异步下载图像,其中的“下载”部分始终涉及转换NSURL-> NSData-> UIImage。然后,当您拥有UIImage时,就可以在单元格中显示它了,因此可以调出主队列和dispatch_async并执行单元格。在主队列上。
在这里,我有一个NSURL,但是我不太明白这里的哪些步骤应该在主队列中,哪些应该不在主线程中。我尝试了前面提到的SO问题中提出的建议,但到目前为止它没有用。表格单元格刚刚加载,视频从不播放。我只看到第一帧。有时它的前1秒会播放,但随后会缓冲,不会播放。我正在使用一个只有1个对象的表视图,因此只有1个视频要播放,但仍然没有播放。
我在做什么错,有人可以帮助我确切说明哪些部分需要在主线程上,哪些需要关闭?我在顶部提到的线程中的响应者说,“那里有很多教程”,但是在扫描google时我没有看到任何内容。“异步”和“ iOS”这两个词几乎总是会获得有关图片下载而非视频的搜索结果。但是,如果有任何教程,那么很高兴看到它。
谢谢
以下是我用来在表格视图单元格中播放视频的方法。我不确定这是最好的方法,无论如何它可能会帮助你:)
首先,我创建了一个自定义单元格。在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];
}
Run Code Online (Sandbox Code Playgroud)
我发现在你的代码中你写了这样的播放函数[videoCell.player play];
仅当播放器状态变为“AVPlayerStatusReadyToPlay”时才应调用播放函数。这就是我使用 KVO 的原因。
希望这可以帮助你:)
| 归档时间: |
|
| 查看次数: |
5117 次 |
| 最近记录: |