gpt4 book ai didi

ios - 在 uitableview 单元格中播放视频

转载 作者:可可西里 更新时间:2023-11-01 04:43:27 25 4
gpt4 key购买 nike

我正在尝试设置一个可以播放视频的 UITableView。许多以前关于此的 SO 问题使用了 MPMoviePlayer(Playing Video into UITableViewPlaying video in UItableView in SWIFTPlaying Video From UITableView),现在在 iOS 9 中已弃用。使用 AVFoundation(我正在使用的)的少数人之一就是这个: Play video on UITableViewCell when it is completely visible并且是我从中获取大部分代码的地方。这是我的代码,在 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;

据我了解,我需要在播放视频之前异步下载它们。我以前异步下载过图像,其中的“下载”部分总是涉及转换 NSURL -> NSData -> UIImage。然后,当您拥有 UIImage 时,您就可以在单元格中显示它了,因此您可以启动主队列并执行 dispatch_async 并执行 cell.imageView.image = yourImage;在主队列上。

在这里,我有一个 NSURL,但我不太明白这里的哪些步骤应该放在主队列中,哪些应该离开主线程。我尝试了上述 SO 问题中的建议,但到目前为止它没有用。表格单元格只是加载,视频从不播放。我只看到第一帧。有时它会播放前 1 秒,但之后会缓冲并且不会播放。我正在处理一个目前只有 1 个对象的表格 View ,因此只有 1 个视频要播放,但它仍然没有播放。

我做错了什么,有人能帮我解释一下哪些部分需要在主线程上,哪些部分需要关闭吗?我在顶部提到的线程中的响应者说“那里有很多教程”,但是在扫描谷歌时我没有看到任何教程。将“异步”和“iOS”这两个词放在一起几乎总是会得到有关图像下载的搜索结果,而不是视频。但如果有任何教程,很高兴看到一个。

谢谢

最佳答案

以下是我用来在 tableview 单元格中播放视频的方法。我不确定这是最好的方法,无论如何它可能对你有帮助:)

首先,我创建了一个自定义单元格。在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];

}

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

您应该仅在播放器状态变为“AVPlayerStatusReadyToPlay”时调用播放函数。这就是我使用 KVO 的原因。

希望这对你有帮助:)

关于ios - 在 uitableview 单元格中播放视频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36168519/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com