场景:一个滚动的视频列表,类似抖音,利用UICollctionView实现当cell到达一定位置就播放该cell视频,cell滑出就停止播放。
实现思路:其中MyPlayViewCell为cell的类,playingCell为记录当前播放的cell
1.列表为UICollctionView,判断当前cell滚动位置并播放:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
NSIndexPath *indexPathPlay;
if (scrollView.contentOffset.y <= 0) {
indexPathPlay = [NSIndexPath indexPathForItem:0 inSection:0];
}else{
indexPathPlay = [self.collectionView indexPathForItemAtPoint:CGPointMake(0, scrollView.contentOffset.y + self.collectionView.frame.size.height/2)];
}
MyPlayViewCell *cell = (MyPlayViewCell *)[self.collectionView cellForItemAtIndexPath:indexPathPlay];
if ([cell isKindOfClass:[MyPlayViewCell class]] && !self.isLoadingData) {
if (!cell.isPlaying) {
[self.playingCell stopPlayVideo];
[cell startPlayVideo];
self.playingCell = cell;
}
}
}
}
2.cell文件中实现循环播放,其中playUrl为播放地址,通过参数传值过来,使用系统Avplayer,timeObserver为视频时间监控的定时器,每次播放完毕都清除重新开始
- (void)startPlayVideo{
if (self.isPlaying) {
[self stopPlayVideo];
}
self.avPlayerItem = [AVPlayerItem playerItemWithURL:[NSURL URLWithString:self.model.oooVideo]];
self.avPlayer = [AVPlayer playerWithPlayerItem:self.avPlayerItem];
self.avPlayer.muted = YES;
self.avPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:self.avPlayer];
self.avPlayerLayer.backgroundColor = (__bridge CGColorRef _Nullable)([UIColor blackColor]);
self.avPlayerLayer.frame = self.videoPlayImgV.bounds;
self.avPlayerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
//NSLog(@"%@", NSStringFromCGRect(self.avPlayerLayer.videoRect));
[self.videoPlayImgV.layer addSublayer:self.avPlayerLayer];
kWeakSelf(self);
self.timeObserver =[self.avPlayer addPeriodicTimeObserverForInterval:CMTimeMake(1.0,1.0) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
CMTime duration = weakself.avPlayer.currentItem.duration;
float totalSeconds = CMTimeGetSeconds(duration);
float currentSeconds = CMTimeGetSeconds(time);
float rate = currentSeconds/totalSeconds;
// NSLog(@"1v1(%@)视频 rate == %f",weakself.model.username,rate);
if (rate >= 0.998) {
[weakself moviePlayDidEnd];
}
}];
self.isPlaying = YES;
[self.avPlayer play];
}
- (void)stopPlayVideo{
self.videoPlayImgV.hidden = YES;
self.playBackV.hidden = YES;
self.isPlaying = NO;
[self.avPlayer pause];
[self.avPlayerLayer removeFromSuperlayer];
self.avPlayerLayer = nil;
[self.avPlayer removeTimeObserver:self.timeObserver];
self.timeObserver = nil;
self.avPlayer = nil;
}
- (void)moviePlayDidEnd{
[self stopPlayVideo];
[self startPlayVideo];
}