Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AVPlayer continues to play after ViewController is removed from NavigationController

So I'm using ARC in my project and when I add an AVPlayerLayer it works just fine and dandy, but when I pop the UIViewController from my UINavigationItem the video continues to play in the background. Does anyone know how you would handle this? It seems like something easy I'm just overlooking. Here's the code I have for the initially instantiations.

self.currentItem = [[AVPlayerItem alloc] initWithURL:url];

self.player = [[AVPlayer alloc]initWithPlayerItem:self.currentItem];
self.avPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:player];

self.avPlayerLayer.bounds = self.view.bounds;
self.avPlayerLayer.frame = CGRectMake(0,55, 1024, 670);

self.view.backgroundColor = [UIColor clearColor];

[self.view.layer addSublayer:avPlayerLayer];

Also this is how I have the properties definied.

@property (strong) AVPlayer *player;
@property (strong) AVPlayerLayer *avPlayerLayer;
@property (strong) AVPlayerItem *currentItem;

Maybe that's entirely wrong as well. I'm not exactly sure when to use (strong) vs (weak). Any case thank you ahead of time for any help.

like image 914
James Parker Avatar asked Nov 09 '11 23:11

James Parker


2 Answers

If avPlayerLayer is the only class interacting with the avPlayer, you don't need to maintain a reference to it with a property in the class you're using to present it (unless this class uses it outside the code you've shared). In fact, this is probably why it isn't working the way you expect.

The reason the clip continues to play (I think) is because the player isn't being deallocated. You create it, own it with the strong property in your class, than it's owned again by the AVPlayerLayer class you hand it to. So when the AVPlayerLayer is deallocated, the AVPlayer looses one owner. But it still has an owner (your class), so it isn't deallocated, and it keeps playing. The solution here is to get rid of your owning property altogether for *avPlayer. You don't need it. Create the AVPlayer and pass it to AVPlayerLayer. That should be all that's needed.

Something else you could do which might fix the behavior but not the problem, call:

[avPlayer pause] 

In your AVPlayerLayer's dealloc method.

Re: Strong vs. Weak references: A strong reference implies ownership. As ARC is managing memory, it'll be doing all the [object retain]ing and [object release]ing that you previously would have done in code OR that you would have done with properties, ie:

@property (retain) NSObject *iAmRetainedWhenProperyIsAssigned; 

So now with ARC, we simple users don't use words like retain or release in code or when defining properties. But we still design software. ARC is smart, but not smart enough to infer the architectural implications of relationships that we're defining. It still needs to be told that a class "owns" a reference to the object that the property refers to. Which reduces us, in the most basic terms:

(strong) means to ARC what (retain) meant to properties pre-ARC (owned/retained)

(weak) means to ARC what (assign) meant to properites pre-ARC (not owned/not retained)

like image 59
isaac Avatar answered Sep 28 '22 11:09

isaac


Maybe you did not pause. Do it and then remove layer and nullify player.

[player Pause];
[player removefromsuperlayer];
player = nil;
like image 31
Vijyendra Sisodia Avatar answered Sep 28 '22 09:09

Vijyendra Sisodia