当前位置: 代码迷 >> 综合 >> 当前滚动位置的视频循环播放功能实现(基于UICollectionView)
  详细解决方案

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

热度:73   发布时间:2024-02-20 07:50:41.0

场景:一个滚动的视频列表,类似抖音,利用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];

}