Jatin Garg
Jatin Garg

Reputation: 206

AVPlayer cause TableView To Lag

I have to play video in my App inside tableView cell. According to view Screen size my Table Can show 2 cell in small screen device and 3 cell in large screen device like iPhone XSMax or Xr

Flow AVPlayerController Class Created

class CustomAVPlayerViewController: AVPlayerViewController {
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        print("touchesBegan")
    }
}

Instances Created in cell class

var myImgArray=[String]()
    var myVideoArray=[String]()
    var myVideoPlayer : AVPlayer?
    var videoPlayerController : CustomAVPlayerViewController?
    var myPlayerItems=[AVPlayerItem]()

Prepare for Reuse Functions

override func prepareForReuse() {
        myVideoPlayer?.replaceCurrentItem(with: nil)
        videoPlayerController=nil
        myVideoPlayer=nil
        self.count=0
        myPlayerItems.removeAll()
        myImgArray.removeAll()
        myVideoArray.removeAll()
        NotificationCenter.default.removeObserver(NSNotification.Name.AVPlayerItemDidPlayToEndTime)
        for vieww in myScrollView.subviews {
            vieww.removeFromSuperview()
        }

    }

I am using AVPLayer instance one for a cell. A single cell can contain multiple videos so used an scrollview for that

if !videoArray.isEmpty {
            /// We've Videos
            for i in 0..<videoArray.count {
                ///Get Origin
                let xOrigin : CGFloat = CGFloat(i) * myScrollView.frame.size.width + (CGFloat(imgArray.count)*myScrollView.frame.size.width)
                let newPlayerItem = AVPlayerItem(url: URL(string: videoArray[i])!)
                myPlayerItems.append(newPlayerItem)
                if i == 0 {
                    self.myVideoPlayer=AVPlayer(playerItem: newPlayerItem)
                    self.videoPlayerController = CustomAVPlayerViewController()
                    NotificationCenter.default.removeObserver(NSNotification.Name.AVPlayerItemDidPlayToEndTime)
                    NotificationCenter.default.addObserver(self, selector: #selector(self.playerDidFinishPlaying(note:)), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: self.myVideoPlayer!.currentItem)
                    self.videoPlayerController?.player = self.myVideoPlayer!
                    self.videoPlayerController?.view.frame = CGRect(x: xOrigin+10, y: 10, width: self.myScrollView.frame.size.width-20, height: self.myScrollView.frame.size.height-20)
                    self.myVideoPlayer?.play()
                    myScrollView.addSubview(self.videoPlayerController!.view)
                    myScrollView.bringSubviewToFront(self.videoPlayerController!.view)
                }
            }
        }

As shown In above code I am looping through Video Array and adding its subview in scrollView

Issue -

it start to lag when there are multiple cell on screen which have video or Next cell to be loaded which have video

I am using prepareForReuse to avoid High Memory Usage. App cycles unto 40 MB in run of 4 Min which include other Features too

What I can do ?

Tried Things

  1. Checking IndexPathForVisibleCell it include three cell which are displayed as soon as my cell goes off screen I remove scrollView subviews and AVPLayer instance.

  2. Using Global AVPLayer Instance but didn't worked. It doesn't play video Reason - When three cell are on screen it won't be dequeued again so Video won't be loaded as global instance will be added in one only and prepareForReuse cause no video to play

Upvotes: 1

Views: 1066

Answers (1)

Hiro
Hiro

Reputation: 400

It may lag because you add and remove the AVPlayer view. Instead of removing them, you can reuse them so you can update the link when the cell is visible on screen. You can refer any article like this: Best way to check if UITableViewCell is completely visible

Upvotes: 2

Related Questions