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 (Cocoa-dev@lists.apple.com) >> >> 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: >> http://lists.apple.com/mailman/options/cocoa-dev/michaelacrawford%40me.com >> >> This email sent to michaelacrawf...@me.com > > _______________________________________________ > > Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) > > 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: > http://lists.apple.com/mailman/options/cocoa-dev/michaelacrawford%40me.com > > This email sent to michaelacrawf...@me.com _______________________________________________ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com