I'm using some AppleScript in my Obj-C cocoa project to control QuickTime player (play, pause, stop, jog forward and back etc.) with great success, though my knowledge of AppleScript is very limited. However, what I want most of all is the movie's 'Current Time' offset to convert into time-stamps for writing a subtitle script.
The following simple method shows the precise current position in (float) seconds in a dialog, but I'd really like the AppleScript to return me a variable that I can use in the rest of app. How could I modify the code below to do that? Is it even possible to access this value? Thanks a million in advance :-)
-(IBAction)currentPlayTime:(id)sender
{
NSString *scriptString=[NSString stringWithFormat:
// get time of current frame... (works perfectly)!
@"tell application \"QuickTime Player\"\n"
@"set timeScale to 600\n"
@"set curr_pos to current time of movie 1/timeScale\n"
@"display dialog curr_pos\n" // ...not in a practical form to use
@"end tell\n"];
NSDictionary *errorDict= nil;
NSAppleScript *appleScriptObject=[[NSAppleScript alloc] initWithSource:scriptString];
NSAppleEventDescriptor *eventDescriptor=[appleScriptObject executeAndReturnError: &errorDict];
// handle any errors here (snipped for brevity)
[appleScriptObject release]; // can I retain this?
}
Here's the appropriate AppleScript that you'd want to run:
property timeScale : 600
set currentPosition to missing value
tell application "QuickTime Player"
set currentPosition to (current time of document 1) / timeScale
end tell
return currentPosition
In case you're not familiar with it, property
is a way to specify a global variable in AppleScript. Also, missing value
is the AppleScript equivalent of nil
in Objective-C. So, this script first defines a variable named currentPosition
, and sets the value to missing value
. It then enters the tell
block which, if it succeeds, will alter the currentPosition
variable. Then, outside of the tell block, it returns the currentPosition
variable.
In the Objective-C code, when you create an NSAppleScript
with the above code, its -executeAndReturnError:
method will return the currentPosition
variable in an NSAppleScriptEventDescriptor
.
-(IBAction)currentPlayTime:(id)sender {
NSDictionary *error = nil;
NSMutableString *scriptText = [NSMutableString stringWithString:@"property timeScale : 600\n"];
[scriptText appendString:@"set currentPosition to missing value\n"];
[scriptText appendString:@"tell application \"QuickTime Player\"\n "];
[scriptText appendString:@"set currentPosition to (current time of document 1) / timeScale\n"];
[scriptText appendString:@"end tell\n"];
[scriptText appendString:@"return currentPosition\n"];
NSAppleScript *script = [[[NSAppleScript alloc] initWithSource:scriptText] autorelease];
NSAppleEventDescriptor *result = [script executeAndReturnError:&error];
NSLog(@"result == %@", result);
DescType descriptorType = [result descriptorType];
NSLog(@"descriptorType == %@", NSFileTypeForHFSTypeCode(descriptorType));
// returns a double
NSData *data = [result data];
double currentPosition = 0;
[data getBytes:¤tPosition length:[data length]];
NSLog(@"currentPosition == %f", currentPosition);
}
You can extract the contents of the NSAppleEventDescriptor
as shown above.
Using the Scripting Bridge framework does have a slight learning curve, but would allow working with native types such as NSNumber
s rather than having to go the somewhat "messier" route of extracting the raw bytes out of AppleEvent descriptor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With