0

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
Utku Dalmaz
  • 9,780
  • 28
  • 90
  • 130
  • Could you please share codes in `cellForItemAt` – Omer Tekbiyik Mar 21 '22 at 15:34
  • @OmerTekbiyik shared – Utku Dalmaz Mar 21 '22 at 15:42
  • As far as I know when the ```reloadRows``` get called a new cell is created and data source will be reassigned. So according to your code new ```AVPlayerItem``` will be created and the video will play from the beginning. So you have to save the current location for the video at the moment it is reloaded and start the video from that position after it is reloaded. – udi Mar 21 '22 at 15:48
  • @udi I tried to get the current time and play again from that time but I failed actually. Can you please help me with that task? – Utku Dalmaz Mar 21 '22 at 15:55
  • Check [this](https://stackoverflow.com/questions/12134109/seek-to-a-certain-position-in-avplayer-right-after-the-asset-was-loaded) – udi Mar 21 '22 at 16:11
  • When you call `reloadRows`, a new cell is generated. So two ideas I have is, you keep track of the progress of the video and set that in `cellForRow atIndexPath` when the new cell is instantiated. Or keep a reference to the individual AVPlayers outside of the cell and add the avplayer on the cell when needed. This is not your exact issue but I have an example of caching the AVPlayer here: https://stackoverflow.com/a/71466751/1619193 – Shawn Frank Mar 22 '22 at 03:12

1 Answers1

0

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.

m3r1yn
  • 1
  • 4