PDA

View Full Version : Error building a QT project




larswik
Dec 1, 2011, 07:16 PM
So I am experimenting with opening and viewing quicklime movies tonight. seed pretty easy and I imported the QT framework and used the #import <QTKit/QTKit.h>. I built the project and got this odd error I have never come across before?

ld: warning: ignoring file /Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks//QuickTime.framework/QuickTime, missing required architecture x86_64 in file
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_QTMovie", referenced from:
objc-class-ref in TableViewController.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)


I made an effort to fix it myself but it seems that the problem is that it can not find the QT Framework but I have verified that it is imported?



kainjow
Dec 1, 2011, 09:00 PM
The QuickTime framework is 32-bit only. You shouldn't use it anymore, it's been superseded by QTKit and the various CoreVideo/Audio frameworks.

larswik
Dec 1, 2011, 10:10 PM
Ahhh, I see. All my projects default to 64 bit so that explains it.

Thanks

foidulus
Dec 1, 2011, 11:01 PM
More specifically, QTKit is mostly used for playback of video(it has very, VERY basic editing capabilities), the Core Audio/Video frameworks are obviously a lot more involved, but much more powerful and what you should be using if you intend to do any editing besides splicing a few movies together.

larswik
Dec 2, 2011, 12:37 AM
EDIt: I guess I had a bad QT movie I was trying to play. I slected another file and the code works well. Sorry

It seems like a trivial thing to add a QT movie to an NSView but the whole night I have been struggling with it. I push an NSButton and then pick the video and press OK. I just get the beach ball spinning?

header
QTMovie *movie;
IBOutlet QTMovieView *QTMovieOutlet;


- (IBAction)openMovieButton:(NSButton *)sender {
NSOpenPanel *openPanel;

openPanel = [NSOpenPanel openPanel];
[openPanel setCanChooseDirectories:NO];
[openPanel setAllowsMultipleSelection:NO];
[openPanel setResolvesAliases:YES];
[openPanel setCanChooseFiles:YES];

if ([openPanel runModalForTypes:nil] == NSOKButton)
{
NSArray *filesToOpen = [openPanel filenames];
NSString *theFilePath = [filesToOpen objectAtIndex:0];

movie = [QTMovie movieWithFile:theFilePath error:nil];
[QTMovieOutlet setMovie:movie];
[movie play];

}

}

mfram
Dec 2, 2011, 02:03 AM
I'm guessing the "play" method doesn't return. Not sure. You may need to the the play in a separate thread so you don't block the main thread while the movie is playing.

larswik
Dec 2, 2011, 03:00 AM
I got it working. Tonight is a big experiment / learning experience. I got every working except for the last part. My goal was to open a bunch of QT movie and iterate through them and get the poster frame with other attribute information. Then store an NSImage of the poster frame and info in an object and store that object in an NSMutableArray.

Then retrieve the information and display the NSImage in my NSImageView on my xib. It works but the Method -(void)testLoop is supposed to display the NSImage for each object with a 1 second delay. I see nothing until the very last image. So 10 images means I wait 10 seconds and it only displays the last image. But all in all everything else worked perfectly as I test what I learn.

-(void)collectItemData{ //This method uses the arrays index of file paths and then gets the atributes to the file and saves to NSDict.

for (int i = 0; i < movArray.count ; i++) {

Item *newItem = [[Item alloc]init]; // My item object

NSFileManager * defaultManager = [NSFileManager defaultManager];
NSString *currentItem = [[NSString alloc] initWithString:[movArray objectAtIndex:i]];

NSDictionary *tempInfoDict;
tempInfoDict = [defaultManager attributesOfItemAtPath:currentItem error:NULL]; //Gets the attributes of a QT movie file.

newItem.creationDate = [tempInfoDict objectForKey:@"NSFileCreationDate"];// gets the creation date
long int x = [[tempInfoDict objectForKey:@"NSFileSize"] intValue]; //gets the file size
newItem.size = [NSString stringWithFormat:@"%d MB's", x / 1024];

newItem.thumbView = [self getThumbNail:i];
[movieStillImage setImage:[newItem thumbView]];

[tableViewItemList addObject:newItem];
[currentItem release];
[newItem release];
// [tableView reloadData];
}
[self loopTest];
}
-(NSImage *)getThumbNail:(int) i{

NSString *theFilePath = [movArray objectAtIndex:i];
QTMovie *movieObject = [QTMovie movieWithFile:theFilePath error:nil];
NSImage *newThmb = [movieObject posterImage];

return newThmb;
}
-(void)loopTest{

for (int i = 0; i < tableViewItemList.count; i++) {
Item *loopItem = [[Item alloc]init];
loopItem = [tableViewItemList objectAtIndex:i];
[movieStillImage setImage:[loopItem thumbView]]; // MovieStillImage is an outlet of type NSImageView
sleep(1);
[loopItem release];
}
}

kainjow
Dec 2, 2011, 03:07 AM
It's only showing the last image because sleep() is blocking the main thread which does the drawing until the loop is finished.

You should instead use an NSTimer.

Also:
Item *loopItem = [[Item alloc]init];
loopItem = [tableViewItemList objectAtIndex:i];
...
[loopItem release];
This is incorrect.

What you're doing is creating a *new* Item object and assigning it to loopItem. You then reassign loopItem to the *existing* object in your array, which creates a leak since you lose the reference to the new object you created. After that you release loopItem, but loopItem is pointing to the object in your array, so its retain count is incorrectly decreased. This could cause a crash later on in your program.

What you want to do is only assign loopItem to your array's object. Don't alloc/release it.

larswik
Dec 2, 2011, 12:43 PM
ahhhh I see what you are saying. My thinking was incorrect of what was happening. I read a thread on another site a while back and the person was complaining that his project got very large as he had to import many thousands of things. His work around was to release the objects himself instead of having the system do it. I thought in this case I could be getting 10K images from QT movies since I do lots of video productions. I thought I would would alloc/release for every iteration to keep the size smaller.

After you explained it I see what I was doing wrong. I am in fact reassigning that pointer 'loopItem' to the index of the array and I am loosing my handle on the object I created on the line above. I will change that thanks!

Now the 'sleep' still baffles me. I had it sleep, so it would pause for 1 second after the image was added to the NSImageView. I would think that it would update the image and then sleep?

Thanks again for the explanation. It's becoming easier for me to see the mistakes that people point out so I understand them.

xStep
Dec 2, 2011, 01:13 PM
Just to note. If you are learning QT for historical reasons, great. If you are planning a new project, Apple now recommends you use the AVFoundation framework, available in iOS 4 and OS X 10.7 and up.

larswik
Dec 2, 2011, 01:38 PM
I was using the QuickTime framework but had a problem with 32/64 bit. I then switched and started using QTKit and classes in that framework. Are you telling me that QTKit framework is also outdated?

xStep
Dec 2, 2011, 04:05 PM
Are you telling me that QTKit framework is also outdated?

My understanding is that the QuickTime frameworks are a development dead end. The future is AVFoundation. This is the framework Apple is promoting and will be doing further work on.

If your app needs to work on OS X 10.6 and earlier, then AVFoundation isn't an option. The QT frameworks have been around a long time. I wouldn't expect Apple to just rip them out of OS X any time soon.