1 #import "iTunesRemote.h"
3 @implementation iTunesRemote
7 return [[[iTunesRemote alloc] init] autorelease];
12 return @"iTunes Plug-in";
15 - (NSString *)information;
17 return @"Default MenuTunes plugin to control iTunes.";
27 iTunesPSN = [self iTunesPSN];
28 asComponent = OpenDefaultComponent(kOSAComponentType, kAppleScriptSubtype);
30 //Register for application termination in NSWorkspace
32 NSLog(@"iTunes Plugin loaded");
38 iTunesPSN.highLongOfPSN = kNoProcess;
39 CloseComponent(asComponent);
41 //Unregister for application termination in NSWorkspace
45 - (PlayerState)playerState
47 NSString *result = [self runScriptAndReturnResult:@"get player state"];
49 if ([result isEqualToString:@"playing"]) {
51 } else if ([result isEqualToString:@"paused"]) {
53 } else if ([result isEqualToString:@"stopped"]) {
55 } else if ([result isEqualToString:@"rewinding"]) {
57 } else if ([result isEqualToString:@"fast forwarding"]) {
64 - (NSArray *)playlists
67 int numPresets = [[self runScriptAndReturnResult:@"get number of playlists"] intValue];
68 NSMutableArray *presets = [[NSMutableArray alloc] init];
70 for (i = 0; i < numPresets; i++) {
71 [presets addObject:[self runScriptAndReturnResult:[NSString stringWithFormat:@"get name of playlist %i", i]]];
74 return [NSArray arrayWithArray:presets];
77 - (int)numberOfSongsInPlaylistAtIndex:(int)index
79 NSString *result = [self runScriptAndReturnResult:[NSString stringWithFormat:@"get number of tracks in playlist %i", index]];
80 return [result intValue];
83 - (NSString *)classOfPlaylistAtIndex:(int)index
85 //Not working yet. It returns the 4 character code instead of a name.
87 result = [[ITAppleEventCenter sharedCenter]
88 sendTwoTierAEWithRequestedKey:@"pcls"
89 fromObjectByKey:@"pPla" eventClass:@"core" eventID:@"getd"
90 appPSN:[self iTunesPSN]];*/
91 NSString *result = [self runScriptAndReturnResult:[NSString stringWithFormat:@"get class of playlist %i", index]];
95 - (int)currentPlaylistIndex
98 result = [[ITAppleEventCenter sharedCenter]
99 sendTwoTierAEWithRequestedKeyForNumber:@"pidx"
100 fromObjectByKey:@"pPla" eventClass:@"core" eventID:@"getd"
101 appPSN:[self iTunesPSN]];
105 - (NSString *)songTitleAtIndex:(int)index
107 NSString *result = [self runScriptAndReturnResult:[NSString stringWithFormat:@"get name of track %i of current playlist", index]];
111 - (int)currentSongIndex
114 result = [[ITAppleEventCenter sharedCenter]
115 sendTwoTierAEWithRequestedKeyForNumber:@"pidx"
116 fromObjectByKey:@"pTrk" eventClass:@"core" eventID:@"getd"
117 appPSN:[self iTunesPSN]];
121 - (NSString *)currentSongTitle
123 return [[ITAppleEventCenter sharedCenter] sendTwoTierAEWithRequestedKey:@"pnam"
124 fromObjectByKey:@"pTrk" eventClass:@"core" eventID:@"getd"
125 appPSN:[self iTunesPSN]];
128 - (NSString *)currentSongArtist
130 return [[ITAppleEventCenter sharedCenter] sendTwoTierAEWithRequestedKey:@"pArt"
131 fromObjectByKey:@"pTrk" eventClass:@"core" eventID:@"getd"
132 appPSN:[self iTunesPSN]];
135 - (NSString *)currentSongAlbum
137 return [[ITAppleEventCenter sharedCenter] sendTwoTierAEWithRequestedKey:@"pAlb"
138 fromObjectByKey:@"pTrk" eventClass:@"core" eventID:@"getd"
139 appPSN:[self iTunesPSN]];
142 - (NSString *)currentSongGenre
144 return [[ITAppleEventCenter sharedCenter] sendTwoTierAEWithRequestedKey:@"pGen"
145 fromObjectByKey:@"pTrk" eventClass:@"core" eventID:@"getd"
146 appPSN:[self iTunesPSN]];
149 - (NSString *)currentSongLength
151 return [[ITAppleEventCenter sharedCenter] sendTwoTierAEWithRequestedKey:@"pTim"
152 fromObjectByKey:@"pTrk" eventClass:@"core" eventID:@"getd"
153 appPSN:[self iTunesPSN]];
156 - (NSString *)currentSongRemaining
158 long duration = [[ITAppleEventCenter sharedCenter]
159 sendTwoTierAEWithRequestedKeyForNumber:@"pDur"
160 fromObjectByKey:@"pTrk" eventClass:@"core" eventID:@"getd"
161 appPSN:[self iTunesPSN]];
162 long current = [[ITAppleEventCenter sharedCenter]
163 sendAEWithRequestedKeyForNumber:@"pPos"
164 eventClass:@"core" eventID:@"getd"
165 appPSN:[self iTunesPSN]];
167 return [[NSNumber numberWithLong:duration - current] stringValue];
170 - (NSArray *)eqPresets;
173 int numPresets = [[self runScriptAndReturnResult:@"get number of EQ presets"] intValue];
174 NSMutableArray *presets = [[NSMutableArray alloc] init];
176 for (i = 0; i < numPresets; i++) {
177 [presets addObject:[self runScriptAndReturnResult:[NSString stringWithFormat:@"get name of EQ preset %i", i]]];
180 return [NSArray arrayWithArray:presets];
183 - (int)currentEQPresetIndex
186 result = [[ITAppleEventCenter sharedCenter]
187 sendTwoTierAEWithRequestedKeyForNumber:@"pidx"
188 fromObjectByKey:@"pEQP" eventClass:@"core" eventID:@"getd"
189 appPSN:[self iTunesPSN]];
195 [[ITAppleEventCenter sharedCenter] sendAEWithEventClass:@"hook" eventID:@"Play"
196 appPSN:[self iTunesPSN]];
202 [[ITAppleEventCenter sharedCenter] sendAEWithEventClass:@"hook" eventID:@"Paus"
203 appPSN:[self iTunesPSN]];
209 [[ITAppleEventCenter sharedCenter] sendAEWithEventClass:@"hook" eventID:@"Next"
210 appPSN:[self iTunesPSN]];
214 - (BOOL)goToPreviousSong
216 [[ITAppleEventCenter sharedCenter] sendAEWithEventClass:@"hook" eventID:@"Prev"
217 appPSN:[self iTunesPSN]];
223 [[ITAppleEventCenter sharedCenter] sendAEWithEventClass:@"hook" eventID:@"Fast"
224 appPSN:[self iTunesPSN]];
230 [[ITAppleEventCenter sharedCenter] sendAEWithEventClass:@"hook" eventID:@"Rwnd"
231 appPSN:[self iTunesPSN]];
236 - (BOOL)switchToPlaylistAtIndex:(int)index
238 [self runScriptAndReturnResult:[NSString stringWithFormat:
239 @"play playlist %i", index]];
243 - (BOOL)switchToSongAtIndex:(int)index
245 [self runScriptAndReturnResult:[NSString stringWithFormat:
246 @"play track %i of current playlist", index]];
250 - (BOOL)switchToEQAtIndex:(int)index
252 [self runScriptAndReturnResult:[NSString stringWithFormat:
253 @"set current EQ preset to EQ preset %i", index]];
254 [self runScriptAndReturnResult:@"set EQ enabled to 1"];
258 - (ProcessSerialNumber)iTunesPSN
260 NSArray *apps = [[NSWorkspace sharedWorkspace] launchedApplications];
261 ProcessSerialNumber number;
264 number.highLongOfPSN = kNoProcess;
266 for (i = 0; i < [apps count]; i++)
268 NSDictionary *curApp = [apps objectAtIndex:i];
270 if ([[curApp objectForKey:@"NSApplicationName"] isEqualToString:@"iTunes"])
272 number.highLongOfPSN = [[curApp objectForKey:@"NSApplicationProcessSerialNumberHigh"] intValue];
273 number.lowLongOfPSN = [[curApp objectForKey:@"NSApplicationProcessSerialNumberLow"] intValue];
279 - (NSString *)runScriptAndReturnResult:(NSString *)script
281 AEDesc scriptDesc, resultDesc;
286 script = [NSString stringWithFormat:@"tell application \"iTunes\"\n%@\nend tell", script];
288 AECreateDesc(typeChar, [script cString], [script cStringLength],
291 OSADoScript(asComponent, &scriptDesc, kOSANullScript, typeChar, kOSAModeCanInteract, &resultDesc);
293 length = AEGetDescDataSize(&resultDesc);
294 buffer = malloc(length);
296 AEGetDescData(&resultDesc, buffer, length);
297 AEDisposeDesc(&scriptDesc);
298 AEDisposeDesc(&resultDesc);
299 result = [NSString stringWithCString:buffer length:length];
300 if ( (! [result isEqualToString:@""]) &&
301 ([result characterAtIndex:0] == '\"') &&
302 ([result characterAtIndex:[result length] - 1] == '\"') ) {
303 result = [result substringWithRange:NSMakeRange(1, [result length] - 2)];