当前滚动位置的视频循环播放功能实现(基于UICollectionView)

场景:一个滚动的视频列表,类似抖音,利用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)];//这里取的是collctionview高程中心点

            }

            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文件中实现循环播放,其中videoUrl为播放地址,通过参数传值过来,使用系统Avplayer进行播放,timeObserver为视频时间监控的定时器,videoPlayImgV是底部imagView,每次播放完毕都清除重新开始

- (void)startPlayVideo{

    if (self.isPlaying) {

        [self stopPlayVideo];

    }

 

    self.avPlayerItem = [AVPlayerItem playerItemWithURL:[NSURL URLWithString:self.model.videoUrl]];

    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;

    //注意:这里可以用之前的一篇文章讲到通过图片URL获取图片尺寸,获取数据后就计算保存在model中,不再赘述,当然你也可以获取视频第一帧,当然最好的还是上传的时候就计算并通过后台传回视频尺寸;

    self.avPlayerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;//如果视频封面尺寸宽度大于高度可以使用AVLayerVideoGravityResizeAspect

    //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(@"视频 rate == %f",,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];

}

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页