I’m hoping that someone can either point me in the right direction or offer a solution to my problem.
I’m relatively comfortable with AppleScript but have recently found the need to make some calls into Cocoa to solve this problem.
I have an AppleScript application that essentially opens a .m2v file and captures every frame of the m2v file by stepping through each frame one-by-one.
My first pass at doing this worked really well as I simply scripted QT to export an image sequence. However, it turns out that I needed to have more granular control over each image as they are being exported. This led me down the path of having to use the QTKit in Cocoa as well as AppleScript. Well needless to say there’s a little bit of a headache there when you’re not an Objective-C coder!
Right now I can open the m2v just fine. I can play the m2v just fine and I can step the m2v frame by frame jsut fine. All of these are using the ‘call method’ approach to a Cocoa file.
What I just simply can’t seem to figure out is how to capture an image. There’s plenty of reference’s in the Cocoa world to grabbing the ‘currentFrameImage’ - but is there an equivalent in AS?
One word of note, I am not opening Quicktime and scripting it as I want the application to appear as a dedicated application, so I’ve created it as an Xcode project instead.
The movie load is:
set theMoviePath to POSIX path of (choose file with prompt "Choose a movie:" without invisibles)
set movieLoaded to (call method "loadMovie:withPath:" of class "methods" with parameters {movieView, theMoviePath})
Then in Cocoa:
+ (id)loadMovie:(QTMovieView *)movieView withPath:(NSString *)moviePath {
if ([QTMovie canInitWithFile:moviePath]) {
[[movieView movie] stop];
[movieView setMovie:[[QTMovie alloc] initWithFile:moviePath error:nil]];
return [NSNumber numberWithBool:TRUE];
} else {
return [NSNumber numberWithBool:FALSE];
}
}
Stepping through is a simple call:
call method "myStepForward:" of class "methods" with parameters {movieView}
With the associated Cocoa mehtod:
+ (void)myStepForward:(QTMovieView *)movieView {
[[movieView movie] stepForward];
}
And here’s the image grab call:
set myNewVar to (call method "saveCurrentImage:withPath:" of class "methods" with parameters {movieView, saveFileName})
And the method (which doesn’t actually save anything and is the problem I’m having):
+ (NSString *)saveCurrentImage:(QTMovieView *)movieView withPath:(NSString *)saveFilePath {
NSString *returnData = saveFilePath;
NSImage *frameImage = [[movieView movie] currentFrameImage];
NSData *imageData = [frameImage TIFFRepresentation];
NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:imageData];
NSDictionary *imageProps = [NSDictionary dictionaryWithObject: [NSNumber
numberWithFloat:0.9] forKey:NSImageCompressionFactor];
imageData = [imageRep representationUsingType:NSJPEGFileType
properties:imageProps];
[imageData writeToFile: saveFilePath atomically:YES];
NSLog(saveFilePath);
return returnData;
}
The code above should grab the current frame image as an NSImage and then save it to a file passed in from the AS call. Everything appears to work except no file ever gets created! The ‘return returnData’ is simply sending the filename passed in back to AS so I could display it whilst debugging to ensure the method actually got called.
What I’m hoping is that there is a way to do this in AS, that I’ve completely missed. I’ve literally spent 2 days searching for a solution here as well as on Google but just can’t nail it.
The reason for not using a native image sequence is two fold - first of all I need to manipulate the way each image is saved (file location, naming etc) without having to roll back through a list of images after they are created. The second is because I wanted a complete single application hat doesn’t launch QT Player as a separate application.
Hope someone out there can help! Much appreciated.
Oh - one more thing - this is all in Xcode 3 running on Leopard.