'Reloading tableview row without interrupting the vide playing inside

I implemented AVQueuePlayer inside of each tableview cell and those cells showing a video.

When I reload any of these rows, the video inside gets interrupted and plays from the beginning.

My question is that how can I reload the row without touching the video at all.

    UIView.performWithoutAnimation {
        self.tableView.reloadRows(at: [indexPath], with: .none)
    }

CellForRowAt

let cell: PostsWithVideoCustom = tableView.dequeueReusableCell(withIdentifier: "CellWithVideo", for: indexPath) as! PostsWithVideoCustom

let scale = UIScreen.main.bounds.width / CGFloat(release.photoWidth)
                let bestHeight = CGFloat(release.photoHeight) * scale
                cell.videoViewHeight.constant = bestHeight
                cell.videoView.frame.size.height = bestHeight

                let soundMuteTap = UITapGestureRecognizer(target: self, action: #selector(videoSoundMute))
                cell.videoView.addGestureRecognizer(soundMuteTap)

                cell.videoView.layer.sublayers?
                    .filter { $0 is AVPlayerLayer }
                    .forEach { $0.removeFromSuperlayer() }

                CacheManager.shared.getFileWith(stringUrl: release.photoFilename) { result in

                    switch result {
                    case let .success(url):

                        let playerItem = AVPlayerItem(url: url)
                        cell.videoView.player = AVQueuePlayer(playerItem: playerItem)
                        cell.videoView.looper = AVPlayerLooper(player: cell.videoView.player!, templateItem: playerItem)

                        var layer = AVPlayerLayer()
                        layer = AVPlayerLayer(player: cell.videoView.player)
                        layer.backgroundColor = UIColor.white.cgColor
                        layer.frame = cell.videoView.bounds
                        layer.videoGravity = .resizeAspectFill
                        cell.videoView.layer.addSublayer(layer)

                        if self.userDefaults.string(forKey: "videoSound") == "1" {
                            cell.videoView.player?.isMuted = false
                        } else {
                            cell.videoView.player?.isMuted = true
                        }
                        

                    case let .failure(error):
                        print(error)
                    }
                }

return cell


Solution 1:[1]

Assuming you only play one video at a time, you could programatically create an AVQueuePlayer and give it desired frame and position instead of putting it in your cells. Doing this have two merits:

  1. It achieves your goal.
  2. Less memory usage.

You would also have to implement UIScrollViewDelegate to update AVPlayer's current position & playing state.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 m3r1yn