13

I have an AVPlayer that I load onto a new view whenever a link is clicked.

-(void)createAndConfigurePlayerWithURL:(NSURL *)movieURL sourceType:(MPMovieSourceType)sourceType {
self.playerItem = [AVPlayerItem playerItemWithURL:movieURL];
customControlOverlay = [[AFDetailViewController alloc] initWithNibName:@"AFMovieScrubControl" bundle:nil];
backgroundWindow = [[UIApplication sharedApplication] keyWindow];
[customControlOverlay.view setFrame:backgroundWindow.frame];
[backgroundWindow addSubview:customControlOverlay.view];

playerLayer = [AVPlayerLayer playerLayerWithPlayer:[AVPlayer playerWithPlayerItem:playerItem]];
[playerLayer.player play];
playerLayer.frame = customControlOverlay.view.frame;
[customControlOverlay.view.layer addSublayer:playerLayer]; 
}

The code above adds the AVPlayer to my app and works fine. I have a toggle in my customControlOverlay nib that should remove the view and stop the AVplayer from playing.

-(IBAction)toggleQuality:(id)sender {
if (qualityToggle.selectedSegmentIndex == 0) {
    NSLog(@"HD");
    [playerLayer.player pause];
    [self.view removeFromSuperview];

} else if (qualityToggle.selectedSegmentIndex == 1) {
    NSLog(@"SD");
}
}

The view is removed correctly but the player still plays in the background. After testing a bit the player wont respond to any code in the toggleQuality method but strings I have there as checks are getting logged.

Any thoughts on what I'm doing wrong?

AFraser
  • 996
  • 4
  • 13
  • 27

2 Answers2

27

I know it's an old question, but it might be helpful to someone someday.

Since the playerLayer is being added as a sublayer and not as a subview it simply needs to be removed from its superlayer (instead of the superview) and the player should be set to nil, something like:

/* not sure if the pause/remove order would matter */
[playerLayer.player pause];
// uncomment if the player not needed anymore
// playerLayer.player = nil;
[playerLayer removeFromSuperlayer];
Islam
  • 3,654
  • 3
  • 30
  • 40
  • 1
    Excuse me, sorry it's been a long time. But, where should I put the code below? in `viewDidDisappear:` or `viewWillDisappear:` ? I tried both, but none of them worked.... could you please help me? Thanks in advance. – Calios Sep 23 '15 at 08:55
  • @Lilac did you ever figure out where to put this code? – Jay Q. Oct 02 '15 at 04:13
  • 1
    @JayQ. I'm afraid that I didn't use this method to solve my issue. It doesn't work for me. – Calios Oct 02 '15 at 13:52
2

Here's the answer in Swift.

Like @Paresh Navadiya and @Yoga said in the comments below the answer. The playerLayer's player has to get set to nil. playerLayer?.player = nil

Add the code in viewWillDisappear:

override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)

        player?.pause() // 1. pause the player to stop it
        playerLayer?.player = nil // 2. set the playerLayer's player to nil
        playerLayer?.removeFromSuperlayer() // 3 remove the playerLayer from its superLayer
}
Lance Samaria
  • 17,576
  • 18
  • 108
  • 256