Adding a QTMovieView, and QTMovie.

Discussion in 'Mac Programming' started by mrTortex, Mar 17, 2011.

  1. mrTortex, Mar 17, 2011
    Last edited: Mar 17, 2011

    mrTortex macrumors newbie

    Joined:
    Feb 12, 2011
    #1
    Hello.

    Not sure if this is the best way to go about this, but here it is :) I'm working on a Cocos2D for Mac test app, and want to add a QTMovie to a scene/layer.

    Code:
    shrigString = [[NSBundle mainBundle] pathForResource:@"shrig_h264_720p" ofType:@"mov"];
    		shrigURL = [NSURL fileURLWithPath:shrigString];
    		shrigMovie = [QTMovie movieWithURL:shrigURL error:nil];
    		[shrigMovieView setMovie:shrigMovie];
    		
    		[[[CCDirectorMac sharedDirector] openGLView] addSubview:shrigMovieView.view];
    		shrigMovieView.frame = CGRectMake(size.width /2, size.height /2, 1024, 576);
    		[shrigMovie autoplay];
    Compiles fine, doesn't add the movie, or at least it's not visible. Any ideas?

    I guess another thing to cosnider would be, can you add a QTMovie to an NSView programatically, or is it only supported via Interface Builder?
     
  2. mrTortex thread starter macrumors newbie

    Joined:
    Feb 12, 2011
    #2
    Changes to code, again compiles and runs but no movie is visible. Wondering if it's at the bottom of the stack?

    Code:
    shrigString = [[NSBundle mainBundle] pathForResource:@"shrig_h264_720p" ofType:@"mov"];
    		shrigURL = [NSURL fileURLWithPath:shrigString];
    		shrigMovie = [QTMovie movieWithFile:@"shrig_h264_720p.mov" error:nil];
    		//shrigMovie = [QTMovie movieWithURL:shrigURL error:nil];
    		shrigMovieView = [QTMovieLayer layerWithMovie:shrigMovie];
    		
    		[[[CCDirectorMac sharedDirector] openGLView] addSubview:shrigNSView];
    		[shrigNSView setLayer:shrigMovieView];
    		//shrigMovieView.frame = CGRectMake(size.width /2, size.height /2, 1024, 576);
    		[shrigMovie autoplay];
     
  3. jiminaus, Mar 17, 2011
    Last edited: Mar 17, 2011

    jiminaus macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #3
    If the code about is trying to add a subview to an NSOpenGLView it won't work. See the quote below from the documentation of NSOpenGLView.

    Alas, I don't know OpenGL or QTKit enough to know how to get a movie to play within an OpenGL scene, if that's even possible. Perhaps check out the QTCoreVideo samples.
     
  4. mrTortex, Mar 17, 2011
    Last edited: Mar 17, 2011

    mrTortex thread starter macrumors newbie

    Joined:
    Feb 12, 2011
    #4
    Thanks for that, I had come to a similar conclusion through trial and error, but it's nice to know for certain. I'm now creating a new NSWindow, and attempting to add the NSView to that, with no luck at all :)

    Still no joy, but current code:

    Code:
    shrigString = [[NSBundle mainBundle] pathForResource:@"shrig_h264_720p" ofType:@"mov"];
    		shrigURL = [NSURL fileURLWithPath:shrigString];
    		shrigMovie = [QTMovie movieWithFile:@"shrig_h264_720p.mov" error:nil];
    		//shrigMovie = [QTMovie movieWithURL:shrigURL error:nil];
    		shrigMovieView = [QTMovieLayer layerWithMovie:shrigMovie];
    		
    		[[[[CCDirectorMac sharedDirector] openGLView] window] addChildWindow:shrigWindow ordered:NSWindowAbove];
    		[shrigWindow setContentView:shrigNSView];
    		[shrigNSView setLayer:shrigMovieView];
    		shrigMovieView.frame = CGRectMake(size.width /2, size.height /2, 1024, 576);
    		[shrigMovie autoplay];
    
     
  5. kainjow Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #5
    Code:
    shrigMovie = [QTMovie movieWithFile:@"shrig_h264_720p.mov" error:nil];
    //shrigMovie = [QTMovie movieWithURL:shrigURL error:nil];
    
    This code is at least the initial problem.

    You create a movie using a relative path of the file name. This is wrong. You need to use the commented-out code instead with the full path/URL of the file.

    Debugging 101: Use NSLog() on your variables to see if they're nil of not. For example:
    Code:
    NSLog(@"shrigMovie: %@", shrigMovie);
    will give you a basic idea of whether or not the movie is loading.
     
  6. mrTortex thread starter macrumors newbie

    Joined:
    Feb 12, 2011
    #6
    Hello.

    Thanks for the pointer, I've just ordered a couple of books to get me going a little more - some reading for the weeks ahead.

    With the code back as it was, the console shows:

    Code:
    shrigMovie: <QTMovie: 0x10063b520 time scale = 2500, duration = 287400, rate = 1.000000, tracks = { 0x10064fc20 0x10064f680 }>
    And the app runs, it takes much longer to load, which I take as a good sign. However the movie still doesn't show :\
     
  7. mrTortex thread starter macrumors newbie

    Joined:
    Feb 12, 2011
    #7
    One more thing, the movie isn't playing (at least I can't hear it's audio).

    I'm calling [shrigMovie play]; and have also tired autoplay, no joy.
     
  8. mrTortex thread starter macrumors newbie

    Joined:
    Feb 12, 2011
    #8
    Something else, which may or may not be a clue, is that if I call the Movie Timer every 0.5 seconds, using:

    Code:
    [self schedule: @selector(timerTest:) interval: 0.5];
    and:

    Code:
    - (void) timerTest: (ccTime) dt
    {
    	NSLog(@"ding dong");
    	NSLog(@"shrigMovie is: %@", QTStringFromTime([shrigMovie currentTime]));
    }
    I get this error in the console:

    Code:
    [Switching to process 74729]
    Program received signal:  “EXC_BAD_ACCESS”.
    [Switching to process 74729]
    sharedlibrary apply-load-rules all
    kill
    quit
    If I simply want to log the text Ding Dong, I get no errors.
     
  9. kainjow Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #9
    I suspect you're assigning shrigMovie, but not retaining it and if you don't have garbage collection on, then shrigMovie will autorelease and become an invalid pointer, causing the EXC_BAD_ACCESS.

    The only way I know you can mix OpenGL and QTKit is via layers, but that means everything must be rendered as layers.

    How exactly are you wanting your movie and OpenGL to be displayed together?
     
  10. mrTortex thread starter macrumors newbie

    Joined:
    Feb 12, 2011
    #10
    Hello.

    Thanks, I'll look into that. :)

    I simple want to have the movie visible! Nothing complex, I'd like to be able to set it's position, and once it's working I'll add a custom play and pause button, but right now all I want is the damn thing to be added. I'm using OpenGL as that's how Cocos2D is set up, and it's what I'm comfortable with, and it allows me to use features I want to include later.

    But ye, right now, having the movie visible and playing would make my day. :)

    Thanks for your continued interest.
     
  11. kainjow Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #11
    Try making a borderless window and adding a QTMovieView onto it with your movie, then add that as a child window of the OpenGL window. It seems like you tried this, but don't use layers this time and see what happens.
     
  12. mrTortex thread starter macrumors newbie

    Joined:
    Feb 12, 2011
    #12
    Hello.

    Well, I'm getting somewhere in that I can now see a window, however it's not working exactly as planned. My added code:

    Code:
    - (void) createWindow
    {
    	CGSize sizer = [[CCDirector sharedDirector] winSize];
    	NSRect frame = NSMakeRect(sizer.width/2, sizer.height/2, 200, 200);
    	NSWindow *__window = [[NSWindow alloc] initWithContentRect:frame styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
    	[__window setBackgroundColor:[NSColor blueColor]];
    	[__window makeKeyAndOrderFront:NSApp];
    }
    Creates the window, it's borderless, and appear on screen but not in my main app. Trying to add this to my OpenGL window in the same way as I was before compiles and runs, but the window doesn't show. :\
     
  13. mrTortex thread starter macrumors newbie

    Joined:
    Feb 12, 2011
    #13
    OK, getting closer. Big code chunk:

    Code:
    -(id) init
    {
    	// always call "super" init
    	// Apple recommends to re-assign "self" with the "super" return value
    	if( (self=[super init])) {
    		
    		// create and initialize a Label
    		CCLabelTTF *label = [CCLabelTTF labelWithString:@"One more thing..." fontName:@"Marker Felt" fontSize:64];
    
    		// ask director the the window size
    		CGSize size = [[CCDirector sharedDirector] winSize];
    	
    		// position the label on the center of the screen
    		label.position =  ccp( size.width /2 , size.height/2 );
    		
    		// add the label as a child to this Layer
    		[self addChild: label];
    		
    		//[[[[CCDirectorMac sharedDirector] openGLView] window] addChildWindow:shrigWindow ordered:NSWindowBelow];
    		
    		[self schedule: @selector(timerTest:) interval: 0.5];
    		[self createWindow];
    	}
    	return self;
    }
    
    - (void) createWindow
    {
    	CGSize sizer = [[CCDirectorMac sharedDirector] winSize];
    	
    	//can we add a movie?
    	shrigString = [[NSBundle mainBundle] pathForResource:@"shrig_h264_720p" ofType:@"mov"];
    	shrigURL = [NSURL fileURLWithPath:shrigString];
    	shrigMovie = [QTMovie movieWithURL:shrigURL error:nil];
    	shrigMovieView = [QTMovieLayer layerWithMovie:shrigMovie];
    	
    	[shrigWindow setContentView:shrigNSView];
    	[shrigNSView setLayer:shrigMovieView];
    	shrigMovieView.frame = CGRectMake(sizer.width /2, sizer.height /2, 1024, 576);
    	[shrigMovie play];
    	[shrigMovie setVolume:100.00f];
    	
    	NSRect frame = NSMakeRect(sizer.width/2, sizer.height/2, 1024, 576);
    	NSWindow *__window = [[NSWindow alloc] initWithContentRect:frame styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
    	[__window setBackgroundColor:[NSColor blueColor]];
    	[__window makeKeyAndOrderFront:NSApp];
    	
    	[[[[CCDirectorMac sharedDirector] openGLView] window] addChildWindow:__window ordered:NSWindowAbove];
    	[__window setContentView:shrigNSView];
    	
    	[shrigMovie retain];
    	
    	NSLog(@"shrigMovie: %@", shrigMovie);
    	NSLog(@"shrigMovie is: %@", QTStringFromTime([shrigMovie currentTime]));
    }
    
    - (void) timerTest: (ccTime) dt
    {
    	NSLog(@"ding dong");
    	NSLog(@"shrigMovie is: %@", QTStringFromTime([shrigMovie currentTime])); //- will cause crash - not any more it doesn't.
    }
    So, the console shows the movie is loaded and playing. However, it's still not visible. And the new borderless window get's is size from some fairy living in the corner of the shed, rather than from the CCDirector's window size. This makes placement really difficult. But it runs, and I feel I'm getting closer. :)

    And the sun is out, I'd like to nail this today.

    Thanks for the words of wisdom, really pointing me in the correct direction :)
     
  14. mrTortex thread starter macrumors newbie

    Joined:
    Feb 12, 2011
    #14
    The odd thing is no matter what, the new window always appears here, outside of the app window.

    [​IMG]

    Moving the main window about causes the blue window to move too, so it's attached. No QTMovie visible though.
     
  15. mrTortex thread starter macrumors newbie

    Joined:
    Feb 12, 2011
    #15
    Hello.

    OK, the movie now loads and plays (I can hear the audio) but I can't see it.

    Code:

    Code:
    - (void) createWindow
    {
    	CGSize sizer = [[CCDirectorMac sharedDirector] winSize];
    	
    	NSRect frame = NSMakeRect(sizer.width/2, sizer.height/2, 576, 576);
    	
    	//can we add a movie?
    	shrigString = [[NSBundle mainBundle] pathForResource:@"shrig_h264_720p" ofType:@"mov"];
    	shrigURL = [NSURL fileURLWithPath:shrigString];
    	shrigMovie = [QTMovie movieWithURL:shrigURL error:nil];
    	shrigMovieView = [QTMovieLayer layerWithMovie:shrigMovie];
    	shrigWindow = [[NSWindow alloc] initWithContentRect:frame styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
    	
    	[shrigWindow setLevel:1];
    	[shrigWindow setContentView:shrigNSView];
    	[shrigNSView setLayer:shrigMovieView];
    	[shrigMovie gotoBeginning];
    	[shrigMovie play];
    	[shrigMovie setVolume:100.00f];
    	
    	//__window = [[NSWindow alloc] initWithContentRect:frame styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
    	//[__window setBackgroundColor:[NSColor blueColor]];
    	//[__window makekey:NSApp];
    	
    	//[[[[CCDirectorMac sharedDirector] openGLView] window] addChildWindow:__window ordered:NSWindowBelow];
    	//[__window setContentView:shrigNSView];
    	//[__window addChildWindow:shrigWindow ordered:NSWindowAbove];
    	
    	[shrigMovie retain];
    	
    	NSLog(@"shrigMovie: %@", shrigMovie);
    	NSLog(@"shrigMovie is: %@", QTStringFromTime([shrigMovie currentTime]));
    }
    Any ideas?
     
  16. kainjow Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #16
    Make sure shrigNSView's bounds are set properly.

    Are you displaying the window? Set the window as a normal window (NSTitledWindowMask) so you know it's there and then make it borderless once you see all the content working - one less issue to troubleshoot.

    I would scrap the layer and just use QTMovieView, if that is all you're using this window for.
     
  17. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #17
    The latest posted code is missing makeKeyAndOrderFront:, or any other messages that cause the window to appear. It's in earlier posted code, just not in latest code.

    Might want to review basics of window programming, or at least look at Apple sample code that shows the basics. If you look at the samples for QTMovieView, it may even give a complete example.
     
  18. mrTortex thread starter macrumors newbie

    Joined:
    Feb 12, 2011
    #18
    Hello.

    Apologies for posting non-completed code:

    Code:
    - (void) createWindow
    {
    	CGSize sizer = [[CCDirectorMac sharedDirector] winSize];
    	
    	NSRect frame = NSMakeRect(sizer.width/2, sizer.height/2, 1024, 576);
    	
    	//can we add a movie?
    	shrigString = [[NSBundle mainBundle] pathForResource:@"shrig_h264_720p" ofType:@"mov"];
    	shrigURL = [NSURL fileURLWithPath:shrigString];
    	shrigMovie = [QTMovie movieWithURL:shrigURL error:nil];
    	shrigMovieView = [QTMovieLayer layerWithMovie:shrigMovie];
    	shrigWindow = [[NSWindow alloc] initWithContentRect:frame
    											  styleMask:NSBorderlessWindowMask
    												backing:NSBackingStoreBuffered
    												  defer:NO];
    	
    	[shrigWindow setLevel:5];
    	[shrigNSView setLayer:shrigMovieView];
    	[shrigWindow setContentView:shrigNSView];
    	
    	
    	[shrigMovie gotoBeginning];
    	[shrigMovie play];
    	[shrigMovie setVolume:5.00f];
    	
    	[shrigMovie retain];
    	[shrigMovieView retain];
    	
    	[shrigNSView setBounds:frame];
    	
    	[shrigWindow makeKeyAndOrderFront:NSApp];
    	
    	[[[[CCDirectorMac sharedDirector] openGLView] window] addChildWindow:shrigWindow ordered:NSWindowBelow];
    	
    	NSLog(@"shrigMovie: %@", shrigMovie);
    	NSLog(@"shrigMovie is: %@", QTStringFromTime([shrigMovie currentTime]));
    }
    Thanks for the pointers, I've looked at Apple's examples but can't find anything to do with adding to an OpenGL view.

    I'm going to clean this out as it's got messy, and start fresh. Cocoa book arrived so I'll go through that also.

    Thanks again. :)
     
  19. kainjow Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #19
    The bounds of a window's content view should always have its origin set at {0,0}. I would double check this in your code.
     

Share This Page