如何在滚动时暂停视频以及如何在屏幕上看到单元格时快速播放视频

问题描述 投票:0回答:1

我有一个用于垂直列表的表格视图单元格,并在水平播放列表中添加了一个集合视图。我想实现类似于YouTube应用程序的视频播放。具体来说,我的目标是在单元格正确可见时播放视频,并在单元格在集合视图中变得不可见时暂停视频。我正在使用AVPlayer。我快完成了,但我面临一个问题。请检查代码。

例如集合视图数组:

Table array:-   [Test:[video.mp4, image.jpg, image.jpg, image.jpg, image.jpg, image.jpg, video.mp4],Test2:[video.mp4, image.jpg, image.jpg, image.jpg, image.jpg, image.jpg, video.mp4],Test3:[video.mp4, image.jpg, image.jpg, image.jpg, image.jpg, image.jpg, video.mp4]]

Collection array:-   [video.mp4, image.jpg, image.jpg, image.jpg, image.jpg, image.jpg, video.mp4]

应用程序运行时,会自动显示并检查是否包含mp4文件,然后自动播放视频并在视频时长结束时暂停。我面临的问题是,当我们垂直滚动(滚动 Tablview)屏幕并到达索引 2 或 3 时,最后一个视频会自动播放。

代码:-

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    stringArrayUrl.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "VideoCell", for: indexPath) as! VideoCell
    if stringArrayUrl[indexPath.item].contains(".mp4") || stringArrayUrl[indexPath.item].contains(".MP4") {
        cell.videoMainView.isHidden = false
        cell.videoThumbImg.getThumbnailImageFromVideoUrl(url: URL(string: self.stringArrayUrl[indexPath.item])!) { (thumbNailImage) in
            cell.videoThumbImg.image = thumbNailImage
        }
        cell.imgPlayBtn.actionBlock {
            self.playVideoWhileScrlling(cell: cell, indexPath: indexPath)
        }
    }
    return cell
}

 func playVideoWhileScrlling(cell:StoryTableImageCell,indexPath:IndexPath){
    if self.stringArrayUrl.indices.contains(indexPath.item+1) {
        self.checkNextVideoUrlIsAvalibleOrNot(indexPath: indexPath.item)
    }
    cell.videoPlayerView.isHidden = false
    self.returnVideoPlayer(inputUrl: self.stringArrayUrl[indexPath.item])
}

func returnVideoPlayer(inputUrl:String) {
    let playerItem = AVPlayerItem(url: URL(string: inputUrl)!)
    videoPlayer.replaceCurrentItem(with: playerItem)
    videoPlayer.play()
}

func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
    if let cell = cell as? VideoCell {
        if stringArrayUrl[indexPath.item].contains(".mp4") || stringArrayUrl[indexPath.item].contains(".MP4") {
            playVideoWhileScrlling(cell: cell, indexPath: indexPath)
        }
    }
}

ScreenShot

问题:如何在滚动时暂停视频并在屏幕上可见单元格时播放视频。 ?

有人可以向我解释一下如何做到这一点吗?我已经尝试过上面的代码,但还没有结果。如果我做错了请纠正我。

任何帮助将不胜感激

ios xcode uitableview uicollectionview avplayer
1个回答
0
投票
Table View Code

 func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        scrollToMostVisibleCell()
    }
    
    func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
        if !decelerate{
            scrollToMostVisibleCell()
        }
    }
    
    func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "stopvideo"), object: nil)
    }
    
    func scrollToMostVisibleCell() {
        let visibleRect = CGRect(origin: tableVW.contentOffset, size: tableVW.bounds.size)
        let visiblePoint = CGPoint(x: visibleRect.midX, y: visibleRect.midY)
        guard let visibleIndexPath = tableVW.indexPathForRow(at: visiblePoint) else { return }
        
        if let cell = tableVW.cellForRow(at: visibleIndexPath) as? FeedBookTVC {
            let convertedRect = tableVW.convert(cell.frame, to: cell.collectionVW)
            if let visibleCollectionViewIndexPath = cell.collectionVW.indexPathForItem(at: CGPoint(x: convertedRect.midX, y: convertedRect.midY)) {
                let collectionViewIndex = visibleCollectionViewIndexPath.item
                if collectionViewIndex < cell.imagesData.count {
                    if let cell2 = cell.collectionVW.cellForItem(at: visibleCollectionViewIndexPath) as? FeedBookCVC {
                        if cell.imagesData[collectionViewIndex].video != "" {
                            cell.configureVideoPlayer(view: cell2.videoData, videoURL: URL(string: "\(imageBaseURL)\(cell.imagesData[collectionViewIndex].video ?? "")")!, placeholderImageURL: "\(imageBaseURL)\(cell.imagesData[collectionViewIndex].thumnails ?? "")")
                            cell.playVideo()
                        }
                    }
                }
            }
        }
        
        print(visibleIndexPath,"indxxxxxxxx")
        for indexPath in tableVW.indexPathsForVisibleRows ?? [] {
            if indexPath != visibleIndexPath {
                if let cell = tableVW.cellForRow(at: indexPath) as? FeedBookTVC {
                    cell.stopVideo()
                }
            }
        }
    }



Collection View Cell 


 var selectIndex = 0
    var visibleIndex = 0
    var imagesData = [AllFeedsModelFeedsImage]()
    
    var player: AVPlayer?
    var playerLayer: AVPlayerLayer?
    
    override func awakeFromNib() {
        super.awakeFromNib()
        NotificationCenter.default.addObserver(self, selector: #selector(stopvideo), name: NSNotification.Name(rawValue: "stopvideo"), object: nil)
    }
    
    
    @objc func stopvideo(){
        self.stopVideo()
    }
    
    func configureVideoPlayer(view: UIView, videoURL: URL, placeholderImageURL: String) {

        player = AVPlayer(url: videoURL)
        playerLayer = AVPlayerLayer(player: player)
        playerLayer?.frame = view.bounds
        playerLayer?.videoGravity = .resizeAspectFill
        view.layer.addSublayer(playerLayer!)
        player?.play()
        NotificationCenter.default.addObserver(self, selector: #selector(playerDidFinishPlaying(_:)), name: .AVPlayerItemDidPlayToEndTime, object: player?.currentItem)
    }
    
    @objc func playerDidFinishPlaying(_ notification: Notification) {
        player?.seek(to: .zero)
        player?.play()
    }
    
    func playVideo() {
        guard let player = self.player else { return }
        player.play()
    }
    
    func stopVideo() {
        guard let player = self.player else { return }
        player.pause()
    }
    
    func isVisible() -> Bool {
        if self.window == nil {
            return false
        }
        let displayBounds = UIScreen.main.bounds
        let selfFrame = self.convert(self.bounds, to: UIApplication.shared.keyWindow)
        let intersection = displayBounds.intersection(selfFrame)
        let visibility = (intersection.width * intersection.height) / (frame.width * frame.height)
        return visibility >= 0.9
    }
    

   func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return imagesData.count
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "FeedBookCVC", for: indexPath) as! FeedBookCVC
        cell.btnPlay.isHidden = true
        cell.setData(imagesDataa: imagesData[indexPath.item])
        return cell
    }
    
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        let firstVisibleCellIndexPath = collectionVW.indexPathsForVisibleItems.first
        if let firstVisibleCellIndexPath = firstVisibleCellIndexPath {
            visibleIndex = firstVisibleCellIndexPath.item
            collectionVW.reloadItems(at: [firstVisibleCellIndexPath])
        }
    }
    
    func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
        if let cell = cell as? FeedBookCVC{
            if imagesData[indexPath.item].thumnails != "" {
                if visibleIndex == indexPath.item {
                    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "stopvideo"), object: nil)
                    cell.videoData.isHidden = false
                    if imagesData[indexPath.item].video != "" {
                        configureVideoPlayer(view: cell.videoData, videoURL: URL(string: "\(imageBaseURL)\(imagesData[indexPath.item].video ?? "")")!, placeholderImageURL: "\(imageBaseURL)\(imagesData[indexPath.item].thumnails ?? "")")
                    }
                }else{
                    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "stopvideo"), object: nil)
                }
            }else{
                cell.videoData.isHidden = true
                player?.pause()
            }
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.