Re: AVPlayerLayer on Lion will only play one movie then zaps super layer
Re: AVPlayerLayer on Lion will only play one movie then zaps super layer
- Subject: Re: AVPlayerLayer on Lion will only play one movie then zaps super layer
- From: Michael Crawford <email@hidden>
- Date: Fri, 30 Dec 2011 23:51:11 -0500
I have a working solution.
In the end I had to recycle everything but the AVAsset instances. Between each movie run, I must destroy the AVPlayerItem, the AVPlayer, the AVPlayerLayer, and the parent NSView since the backing layer that results from -[NSView setWantsLayer:] disappears without so much a whimper (no exceptions in Objective-C or C++ land), once the movie playback completes.
If this is mentioned in the programming guide for AVFoundation, I missed it completely.
Painful lesson.
-Michael
On Dec 30, 2011, at 9:44 PM, Michael Crawford wrote:
> Little more information.
>
> I created a custom view so that I could monitor -[NSView setWantsLayer:] and found that there are no calls change the layer backed state of the view to false. The views layer simply disappears in that it is set to nil after the movie plays once.
>
> -Michael
>
> On Dec 29, 2011, at 9:07 AM, Michael Crawford wrote:
>
>> I'm creating a simple menu-drive movie player and have run into a problem with AVPlayerLayer. The first time I attach a player with a movie the playback is fine. When a second movie is selected from the menu, I never receive a status of -[AVPlayerLayer readyForDisplay] set to true. If I ignore this status the player will play but I only get audio playback (no video). Investigating the status of the view and associated layers involved shows that the layer for the layer-backed (not hosted) view becomes nil after playing the first movie.
>>
>> I have no idea how this is happening. I've included the relevant snippets below because I'm probably looking right at the problem and not seeing it. Hopefully someone out that has a little more experience with AVFoundation and can give me a clue.
>>
>> I'm using ARC.
>>
>>
>> @interface JTVMovieViewController : NSViewController
>> {
>> AVPlayerLayer* __strong playerLayer;
>> }
>>
>> @property (assign) IBOutlet id<JTVMoviewViewDelegate> delegate;
>> @property (strong) IBOutlet NSButton* homeButton;
>> @property (strong) IBOutlet NSView* playerView;
>>
>> - (void)awakeFromNib
>> {
>> playerLayer = [AVPlayerLayer layer];
>> playerLayer.frame = self.playerView.bounds;
>> playerLayer.videoGravity = AVLayerVideoGravityResizeAspect;
>> [playerLayer addObserver:self
>> forKeyPath:kReadyForDisplayKey
>> options:NSKeyValueObservingOptionNew
>> context:KVOPlayerLayerContext];
>> [self.playerView.layer addSublayer:playerLayer];
>> }
>>
>> - (void)observeValueForKeyPath:(NSString*)keyPath
>> ofObject:(id)object
>> change:(NSDictionary*)change
>> context:(void*)context
>> {
>> if ( context == KVOMoviePlaylistContext )
>> {
>> [self startPlayingNewPlayer:[self.moviePlaylist selection]];
>> }
>> else if ( context == KVOPlayerLayerContext )
>> {
>> NSLog(@"Player layer %@ ready for display.",
>> playerLayer.readyForDisplay ? @"is" : @"is not");
>>
>> if ( YES == playerLayer.readyForDisplay )
>> {
>> [playerLayer.player play];
>> }
>> }
>> }
>>
>> - (void)startPlayingNewPlayer:(AVPlayer*)player
>> {
>> [playerLayer setPlayer:player];
>>
>> if ( YES == playerLayer.readyForDisplay )
>> {
>> [player play];
>> }
>>
>> [self.delegate controllerDidBeginVideoPlayback:self];
>> }
>>
>> - (void)stopPlayback
>> {
>> [[playerLayer player] pause];
>> [[playerLayer player] seekToTime:kCMTimeZero]; // reset player
>> [playerLayer setPlayer:nil];
>> }
>>
>> (lldb) po [self playerView]
>> (NSView *) $2 = 0x000000010bf83310 <NSView: 0x10bf83310>
>> (lldb) po [[self playerView] layer]
>> (id) $3 = 0x000000010bf833d0 <_NSViewBackingLayer:0x10bf833d0; position = CGPoint (0 0); bounds = CGRect (0 0; 1920 1080); delegate = <NSView: 0x10bf83310>; backgroundFilters = (
>> ); filters = (
>> ); shadowColor = (null); anchorPoint = CGPoint (0 0)>
>> (lldb) po [[[self playerView] layer] sublayers]
>> (id) $4 = 0x000000010bf88880 <CALayerArray 0x10bf88880>(
>> <AVPlayerLayer:0x10bf84b50; position = CGPoint (960 540); bounds = CGRect (0 0; 1920 1080); >
>> )
>>
>> (lldb) c
>> Process 96211 resuming
>> 2011-12-29 08:35:33.421 JTVideoPlayer[96211:503] Player layer is ready for display.
>> << here is where I stop playback from the UI>
>> 2011-12-29 08:36:35.289 JTVideoPlayer[96211:503] Player layer is not ready for display.
>> (lldb) po [self playerView]
>> (NSView *) $13 = 0x000000010bf83310 <NSView: 0x10bf83310>
>> (lldb) po [[self playerView] layer]
>> (id) $14 = 0x0000000000000000 <nil>
>> (lldb) po [playerLayer superlayer]
>> (id) $15 = 0x0000000000000000 <nil>
>> (lldb)
>>
>> -Michael
>> _______________________________________________
>>
>> Cocoa-dev mailing list (email@hidden)
>>
>> Please do not post admin requests or moderator comments to the list.
>> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>>
>> Help/Unsubscribe/Update your Subscription:
>>
>> This email sent to email@hidden
>
> _______________________________________________
>
> Cocoa-dev mailing list (email@hidden)
>
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden