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 - (NSArray *)playlists
48 int numPresets = [[self runScriptAndReturnResult:@"get number of playlists"] intValue];
49 NSMutableArray *presets = [[NSMutableArray alloc] init];
51 for (i = 0; i < numPresets; i++) {
52 [presets addObject:[self runScriptAndReturnResult:[NSString stringWithFormat:@"get name of playlist %i", i]]];
55 return [NSArray arrayWithArray:presets];
58 - (int)numberOfSongsInPlaylistAtIndex:(int)index
60 NSString *result = [self runScriptAndReturnResult:[NSString stringWithFormat:@"get number of tracks in playlist %i", index]];
61 return [result intValue];
64 - (NSString *)classOfPlaylistAtIndex:(int)index
66 //Not working yet. It returns the 4 character code instead of a name.
68 result = [[ITAppleEventCenter sharedCenter]
69 sendTwoTierAEWithRequestedKey:@"pcls"
70 fromObjectByKey:@"pPla" eventClass:@"core" eventID:@"getd"
71 appPSN:[self iTunesPSN]];*/
72 NSString *result = [self runScriptAndReturnResult:[NSString stringWithFormat:@"get class of playlist %i", index]];
76 - (int)currentPlaylistIndex
79 result = [[ITAppleEventCenter sharedCenter]
80 sendTwoTierAEWithRequestedKeyForNumber:@"pidx"
81 fromObjectByKey:@"pPla" eventClass:@"core" eventID:@"getd"
82 appPSN:[self iTunesPSN]];
86 - (NSString *)songTitleAtIndex:(int)index
88 NSString *result = [self runScriptAndReturnResult:[NSString stringWithFormat:@"get name of track %i of current playlist", index]];
92 - (int)currentSongIndex
95 result = [[ITAppleEventCenter sharedCenter]
96 sendTwoTierAEWithRequestedKeyForNumber:@"pidx"
97 fromObjectByKey:@"pTrk" eventClass:@"core" eventID:@"getd"
98 appPSN:[self iTunesPSN]];
102 - (NSString *)currentSongTitle
104 return [[ITAppleEventCenter sharedCenter] sendTwoTierAEWithRequestedKey:@"pnam"
105 fromObjectByKey:@"pTrk" eventClass:@"core" eventID:@"getd"
106 appPSN:[self iTunesPSN]];
109 - (NSString *)currentSongArtist
111 return [[ITAppleEventCenter sharedCenter] sendTwoTierAEWithRequestedKey:@"pArt"
112 fromObjectByKey:@"pTrk" eventClass:@"core" eventID:@"getd"
113 appPSN:[self iTunesPSN]];
116 - (NSString *)currentSongAlbum
118 return [[ITAppleEventCenter sharedCenter] sendTwoTierAEWithRequestedKey:@"pAlb"
119 fromObjectByKey:@"pTrk" eventClass:@"core" eventID:@"getd"
120 appPSN:[self iTunesPSN]];
123 - (NSString *)currentSongGenre
125 return [[ITAppleEventCenter sharedCenter] sendTwoTierAEWithRequestedKey:@"pGen"
126 fromObjectByKey:@"pTrk" eventClass:@"core" eventID:@"getd"
127 appPSN:[self iTunesPSN]];
130 - (NSString *)currentSongLength
132 return [[ITAppleEventCenter sharedCenter] sendTwoTierAEWithRequestedKey:@"pTim"
133 fromObjectByKey:@"pTrk" eventClass:@"core" eventID:@"getd"
134 appPSN:[self iTunesPSN]];
137 - (NSString *)currentSongRemaining
139 long duration = [[ITAppleEventCenter sharedCenter]
140 sendTwoTierAEWithRequestedKeyForNumber:@"pDur"
141 fromObjectByKey:@"pTrk" eventClass:@"core" eventID:@"getd"
142 appPSN:[self iTunesPSN]];
143 long current = [[ITAppleEventCenter sharedCenter]
144 sendAEWithRequestedKeyForNumber:@"pPos"
145 eventClass:@"core" eventID:@"getd"
146 appPSN:[self iTunesPSN]];
148 return [[NSNumber numberWithLong:duration - current] stringValue];
151 - (NSArray *)eqPresets;
154 int numPresets = [[self runScriptAndReturnResult:@"get number of EQ presets"] intValue];
155 NSMutableArray *presets = [[NSMutableArray alloc] init];
157 for (i = 0; i < numPresets; i++) {
158 [presets addObject:[self runScriptAndReturnResult:[NSString stringWithFormat:@"get name of EQ preset %i", i]]];
161 return [NSArray arrayWithArray:presets];
164 - (int)currentEQPresetIndex
167 result = [[ITAppleEventCenter sharedCenter]
168 sendTwoTierAEWithRequestedKeyForNumber:@"pidx"
169 fromObjectByKey:@"pEQP" eventClass:@"core" eventID:@"getd"
170 appPSN:[self iTunesPSN]];
176 [[ITAppleEventCenter sharedCenter] sendAEWithEventClass:@"hook" eventID:@"Play"
177 appPSN:[self iTunesPSN]];
183 [[ITAppleEventCenter sharedCenter] sendAEWithEventClass:@"hook" eventID:@"Paus"
184 appPSN:[self iTunesPSN]];
190 [[ITAppleEventCenter sharedCenter] sendAEWithEventClass:@"hook" eventID:@"Next"
191 appPSN:[self iTunesPSN]];
195 - (BOOL)goToPreviousSong
197 [[ITAppleEventCenter sharedCenter] sendAEWithEventClass:@"hook" eventID:@"Prev"
198 appPSN:[self iTunesPSN]];
202 - (BOOL)switchToPlaylistAtIndex:(int)index
204 [self runScriptAndReturnResult:[NSString stringWithFormat:
205 @"play playlist %i", index]];
209 - (BOOL)switchToSongAtIndex:(int)index
211 [self runScriptAndReturnResult:[NSString stringWithFormat:
212 @"play track %i of current playlist", index]];
216 - (BOOL)switchToEQAtIndex:(int)index
218 [self runScriptAndReturnResult:[NSString stringWithFormat:
219 @"set current EQ preset to EQ preset %i", index]];
220 [self runScriptAndReturnResult:@"set EQ enabled to 1"];
224 - (ProcessSerialNumber)iTunesPSN
226 NSArray *apps = [[NSWorkspace sharedWorkspace] launchedApplications];
227 ProcessSerialNumber number;
230 number.highLongOfPSN = kNoProcess;
232 for (i = 0; i < [apps count]; i++)
234 NSDictionary *curApp = [apps objectAtIndex:i];
236 if ([[curApp objectForKey:@"NSApplicationName"] isEqualToString:@"iTunes"])
238 number.highLongOfPSN = [[curApp objectForKey:@"NSApplicationProcessSerialNumberHigh"] intValue];
239 number.lowLongOfPSN = [[curApp objectForKey:@"NSApplicationProcessSerialNumberLow"] intValue];
245 - (NSString *)runScriptAndReturnResult:(NSString *)script
247 AEDesc scriptDesc, resultDesc;
252 script = [NSString stringWithFormat:@"tell application \"iTunes\"\n%@\nend tell", script];
254 AECreateDesc(typeChar, [script cString], [script cStringLength],
257 OSADoScript(asComponent, &scriptDesc, kOSANullScript, typeChar, kOSAModeCanInteract, &resultDesc);
259 length = AEGetDescDataSize(&resultDesc);
260 buffer = malloc(length);
262 AEGetDescData(&resultDesc, buffer, length);
263 AEDisposeDesc(&scriptDesc);
264 AEDisposeDesc(&resultDesc);
265 result = [NSString stringWithCString:buffer length:length];
266 if ( (! [result isEqualToString:@""]) &&
267 ([result characterAtIndex:0] == '\"') &&
268 ([result characterAtIndex:[result length] - 1] == '\"') ) {
269 result = [result substringWithRange:NSMakeRange(1, [result length] - 2)];