我有一个包含视频网址的数组,我想在UITableviewcell完全可见时播放这些视频。
我试过这个
- (void)scrollViewDidScroll:(UIScrollView *)aScrollView
{
NSArray* cells = homeTabl.visibleCells;
for (HomeCell* cell in cells)
{
if (cell.frame.origin.y > offset.y &&
cell.frame.origin.y + cell.frame.size.height < offset.y + bounds.size.height)
{
NSIndexPath *path = [homeTabl indexPathForCell:cell] ;
index = path.row;
fullvisible = YES;
[homeTabl reloadData];
}
else
{
fullvisible = NO;
}
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (fullvisible)
{
NSURL *url = [NSURL URLWithString:[[responsearray objectAtIndex:indexPath.row]valueForKey:@"feed_video"]];
cell.videoItem = [AVPlayerItem playerItemWithURL:url];
cell.videoPlayer = [AVPlayer playerWithPlayerItem:cell.videoItem];
cell.avLayer = [AVPlayerLayer playerLayerWithPlayer:cell.videoPlayer];
cell.videoPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone;
[cell.videoItem addObserver:self forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionNew context:nil];
[cell.videoItem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemDidBufferPlaying:) name:AVPlayerItemPlaybackStalledNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemDidFinishPlaying:) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
cell.avLayer.frame = CGRectMake(5, 9, 310, 310);
[cell.contentView.layer addSublayer:cell.avLayer];
[cell.videoPlayer play];
[cell.contentView addSubview:cell.videoActivity];
}
else
{
cell.videoPlayer = nil;
[cell.avLayer removeFromSuperlayer];
cell.videoItem = nil;
[cell.videoPlayer pause];
}
}
这样可以正常工作 - 但可怕的是减缓了表格视图的滚动速度。 请建议我一些其他更好的方法。
答案 0 :(得分:9)
您可以使用
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
isScrolling = NO;
[homeTabl reloadData];
}
-(void)scrollViewWillBeginDragging:(UIScrollView *)aScrollView
{
isScrolling = YES;
[homeTabl reloadData];
index = -1;
}
在cellForRowatindexpath
中if (fullvisible && index == indexPath.row) {
if (!isScrolling) {
NSLog(@"video index---%d",indexPath.row);
if (index == indexPath.row) {
NSLog(@"video index---%d",indexPath.row);
cell.videoActivity.hidden = NO;
// if (index == indexPath.row) {
NSURL *url = [NSURL URLWithString:[[responsearray objectAtIndex:indexPath.row]valueForKey:@"feed_video"]];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
cell.videoItem = [AVPlayerItem playerItemWithURL:url];
dispatch_sync(dispatch_get_main_queue(), ^{
cell.videoPlayer = [AVPlayer playerWithPlayerItem:cell.videoItem];
cell.avLayer = [AVPlayerLayer playerLayerWithPlayer:cell.videoPlayer];
cell.videoPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone;
[cell.videoItem addObserver:self forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionNew context:nil];
[cell.videoItem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemDidBufferPlaying:) name:AVPlayerItemPlaybackStalledNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemDidFinishPlaying:) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
cell.avLayer.frame = CGRectMake(5, 9, 310, 310);
[cell.contentView.layer addSublayer: cell.avLayer];
[ cell.videoPlayer play];
[cell.contentView addSubview:cell.videoActivity];
});
});
// }
// else{
// cell.videoActivity.hidden = YES;
// cell.videoPlayer = nil;
// [cell.avLayer removeFromSuperlayer];
// cell.videoItem = nil;
// [cell.videoPlayer pause];
// }
}
}}
else{
cell.videoActivity.hidden = YES;
cell.videoPlayer = nil;
[cell.avLayer removeFromSuperlayer];
cell.videoItem = nil;
[cell.videoPlayer pause];
}
答案 1 :(得分:8)
您正在主线程中同义地加载视频项目;这意味着在创建表格视图单元格的同时,您的视频项目正在下载并加载到表格视图单元格中。这会导致问题,并使滚动非常迟缓和缓慢。要解决此问题,您需要在单独的线程中异步加载视频。
因此,您必须避免同步加载图像,而是异步加载图像,使用主线程以外的其他线程,以便滚动和加载+显示图像可以依赖地完成,避免任何类型的延迟。
这可能是一个重复的问题,因为它已经被问过并且有教程,但是因为我自己总是在我的第一个iOS应用程序上遇到此问题(但是对于图片)并且发现它非常令人困惑的是,我在这里发布了答案,希望它有用。
尝试将与视频加载/显示相关的所有行(尤其是playerItemWithURL
中的- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath:
)移动到单独的块中。还可以在表视图单元格中搜索和阅读关于&#34;异步视频加载的其他帖子&#34;。关于此,有很多深入的教程和问答。
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
cell.videoItem = [AVPlayerItem playerItemWithURL:url];
dispatch_sync(dispatch_get_main_queue(), ^{
cell.videoPlayer = [AVPlayer playerWithPlayerItem:cell.videoItem];
cell.avLayer = [AVPlayerLayer playerLayerWithPlayer:cell.videoPlayer];
cell.videoPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone;
[cell.videoItem addObserver:self forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionNew context:nil];
[cell.videoItem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemDidBufferPlaying:) name:AVPlayerItemPlaybackStalledNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemDidFinishPlaying:) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
cell.avLayer.frame = CGRectMake(5, 9, 310, 310);
[cell.contentView.layer addSublayer: cell.avLayer];
[ cell.videoPlayer play];
[cell.contentView addSubview:cell.videoActivity];
});
});
答案 2 :(得分:1)
每次要播放视频时,请避免重新加载表格视图。您可以在可见单元格上执行视频播放代码,而无需重新加载整个表格视图。
另外,我怀疑在桌面视图停止滚动之前,你真的不想播放视频。请参阅How to detect when a UIScrollView has finished scrolling(检测UIScrollView
完成滚动的时间出乎意料地不直观)。
如果您确实想在滚动视图停止滚动之前开始播放视频,请至少修改代码以检查可见单元格是否已播放,然后不执行任何操作。现在,只要一个单元格完全可见,我就会多次执行播放视频的tableView:cellForRowAtIndexPath:
代码(我怀疑它会发生很多!)。