7 objective-c uitableview ios avplayer
我有一个包含视频URL的数组,我想在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];
}
}
Run Code Online (Sandbox Code Playgroud)
这工作正常 - 但它可怕减慢表视图的滚动速度.请建议我一些其他更好的方法.
您可以使用
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
isScrolling = NO;
[homeTabl reloadData];
}
-(void)scrollViewWillBeginDragging:(UIScrollView *)aScrollView
{
isScrolling = YES;
[homeTabl reloadData];
index = -1;
}
Run Code Online (Sandbox Code Playgroud)
并在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];
}
Run Code Online (Sandbox Code Playgroud)
您正在主线程中同义地加载视频项目; 这意味着在创建表格视图单元格的同时,您的视频项目正在下载并加载到表格视图单元格中.这会导致问题,并使滚动非常迟缓和缓慢.要解决此问题,您需要在单独的线程中异步加载视频.
因此,您必须避免同步加载图像,而是异步加载图像,使用主线程以外的其他线程,以便可以依赖地完成滚动和加载+显示图像,避免任何类型的延迟.
这可能是一个重复的问题,因为它已经被问到并且有教程,但由于我自己总是在我的第一个iOS应用程序上有这个问题(但是对于图片)并且发现它非常令人困惑,我发布了回答这里,希望它有所帮助.
尝试移动与视频加载/显示相关的所有行,尤其是playerItemWithURL在您- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath:的单独块中.另外搜索并阅读关于"表视图单元格中的异步视频加载"的其他帖子.有很多深入的教程和Q/As.
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];
});
});
Run Code Online (Sandbox Code Playgroud)