Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

mrTortex

macrumors newbie
Original poster
Feb 12, 2011
25
0
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?
 
Last edited:
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];
 
Code:
[[[CCDirectorMac sharedDirector] openGLView] addSubview:shrigNSView];

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.

An NSOpenGLView object cannot have subviews. You can, however, divide a single NSOpenGLView into multiple rendering areas using the glViewport function.

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.
 
Last edited:
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];
 
Last edited:
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.
 
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 :\
 
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.
 
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.
 
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?
 
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.
 
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.
 
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. :\
 
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 :)
 
The odd thing is no matter what, the new window always appears here, outside of the app window.

screenshot20110321at151.png


Moving the main window about causes the blue window to move too, so it's attached. No QTMovie visible though.
 
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?
 
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.
 
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.
 
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. :)
 
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.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.