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

Reply via email to