Possible to "reuse" AVPlayerLayer? Removing from superview for cell reuse affects my performance

1.5k Views Asked by At

I've created a real simple player class that I've added as a property of a custom uitableviewcell. I was fairly pleased with the scrolling, but figured it could be better. I have a "cleanup" method that I call from within the player class to prepare the player to be reused.

-(void)URLFromWeb:(NSURL*)URL{


    [self cleanPlayer];



    AVAsset* avAsset = [AVAsset assetWithURL:URL];
    AVPlayerItem *playerItem =[[AVPlayerItem alloc]initWithAsset:avAsset];

    if (!self.player) {

        self.player = [AVPlayer playerWithPlayerItem:playerItem];
        [self.player setActionAtItemEnd:AVPlayerActionAtItemEndNone];

    }

    if (!self.avPlayerLayer) {


        self.avPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
        self.avPlayerView = [[UIView alloc] initWithFrame:CGRectZero];
        [self.avPlayerView.layer addSublayer:self.avPlayerLayer];

        [self addSubview:self.avPlayerView];

        [self.avPlayerLayer setFrame:CGRectMake(0, 0, 320, 320)];

        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(playerPlayedToEnd:)
                                                     name:AVPlayerItemDidPlayToEndTimeNotification
                                                   object:nil];
    }

    [self.avPlayerView removeFromSuperview];
    [self addSubview:self.avPlayerView];

}

Here is the code for "cleanPlayer"

    -(void)cleanPlayer{

   [self.avPlayerView removeFromSuperview];

    self.avPlayerView = nil;
    self.avPlayerLayer = nil;
    self.player = nil;


}

The scrolling is AMAZING if I remove the [self.avPlayerView removeFromSuperview] line from the cleanPlayer method, but after a scrolling a fair amount of times, cells stop playing video and the wrong videos begin displaying in cells. Adding the code back causes a slight "hiccup" each time the cell is created and it's a bit annoying. Any insight on what is happening would be greatly appreciated. Oh, I have used the profiler and have found nothing useful in determining the cause. Thanks in advance!

1

There are 1 best solutions below

0
On

I don't think you ought clear your player and its layer every single time.

You can instantiate a player and its layer in UITableViewCell.awakeFromNib() then just call AVPlayer.replaceCurrentItemWithPlayerItem(newItem) when you need.

You may do that in UITableView.cellForRowAtIndexPath(indexPath) for example. You can also add a AVPlayer.replaceCurrentItemWithPlayerItem(nil) in your UITableViewCell.prepareForReuse()

That might seems a bit tricky but there is no need to remove anything here ;)

Hope this'll help!