使用ScriptingBridge获取当前歌曲的iTunes作品

时间:2011-08-12 03:39:48

标签: objective-c itunes scripting-bridge artwork

我一直试图弄清楚如何使用脚本桥获取当前播放歌曲的iTunes艺术作品。我已经达到了适用于某些歌曲的程度,但对于其他人来说,我得到了一个SIGABRT。我不确定问题是什么,所以任何帮助都将不胜感激。以下是我到目前为止的情况:

iTunesApplication * iTunes = [SBApplication applicationWithBundleIdentifier:@"com.apple.iTunes"];
NSImage *songArtwork;
iTunesTrack *current = [iTunes currentTrack];
iTunesArtwork *artwork = (iTunesArtwork *)[[[current artworks] get] lastObject];
if(artwork != nil)
  songArtwork = [artwork data];
else
  songArtwork = [NSImage imageNamed:@"Image.tiff"];

NSMenuItem *artworkMenuItem = [[NSMenuItem alloc] initWithTitle:@"" action:NULL keyEquivalent:@""];
[songArtwork setSize:NSMakeSize(128, 128)];
[artworkMenuItem setImage:songArtwork];
[Menu insertItem:artworkMenuItem atIndex:0];

我可以使用一些歌曲,并在菜单项中很好地展示艺术作品,但对于其他人我会在线上获得一个SIGABRT:

[songArtwork setSize:NSMakeSize(128, 128)];

控制台的输出如下:

2011-08-12 23:13:20.094 SongViewer[2146:707] -[NSAppleEventDescriptor setSize:]:     unrecognized selector sent to instance 0x102827f70
2011-08-12 23:13:20.095 SongViewer[2146:707] An uncaught exception was raised
2011-08-12 23:13:20.096 SongViewer[2146:707] -[NSAppleEventDescriptor setSize:]: unrecognized selector sent to instance 0x102827f70
2011-08-12 23:13:20.097 SongViewer[2146:707] (
0   CoreFoundation                      0x00007fff86f11986 __exceptionPreprocess + 198
1   libobjc.A.dylib                     0x00007fff8b04cd5e objc_exception_throw + 43
2   CoreFoundation                      0x00007fff86f9d5ae -[NSObject doesNotRecognizeSelector:] + 190
3   CoreFoundation                      0x00007fff86efe803 ___forwarding___ + 371
4   CoreFoundation                      0x00007fff86efe618 _CF_forwarding_prep_0 + 232
5   SongViewer                          0x0000000100002a83 -[IPMenulet awakeFromNib] + 4483
6   CoreFoundation                      0x00007fff86f089e1 -[NSObject performSelector:] + 49
7   CoreFoundation                      0x00007fff86f08962 -[NSSet makeObjectsPerformSelector:] + 274
8   AppKit                              0x00007fff8d9d9c27 -[NSIBObjectData nibInstantiateWithOwner:topLevelObjects:] + 1245
9   AppKit                              0x00007fff8d9d01b9 loadNib + 322
10  AppKit                              0x00007fff8d9cf6b6 +[NSBundle(NSNibLoading) _loadNibFile:nameTable:withZone:ownerBundle:] + 217
11  AppKit                              0x00007fff8d9cf5d1 +[NSBundle(NSNibLoading) loadNibFile:externalNameTable:withZone:] + 141
12  AppKit                              0x00007fff8d9cf514 +[NSBundle(NSNibLoading) loadNibNamed:owner:] + 364
13  AppKit                              0x00007fff8dc42355 NSApplicationMain + 398
14  SongViewer                          0x0000000100001882 main + 34
15  SongViewer                          0x0000000100001854 start + 52
)
2011-08-12 23:13:20.098 SongViewer[2146:707] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSAppleEventDescriptor setSize:]: unrecognized selector sent to instance 0x102827f70'
*** First throw call stack:
(
0   CoreFoundation                      0x00007fff86f11986 __exceptionPreprocess + 198
1   libobjc.A.dylib                     0x00007fff8b04cd5e objc_exception_throw + 43
2   CoreFoundation                      0x00007fff86f9d5ae -[NSObject doesNotRecognizeSelector:] + 190
3   CoreFoundation                      0x00007fff86efe803 ___forwarding___ + 371
4   CoreFoundation                      0x00007fff86efe618 _CF_forwarding_prep_0 + 232
5   SongViewer                          0x0000000100002a83 -[IPMenulet awakeFromNib] + 4483
6   CoreFoundation                      0x00007fff86f089e1 -[NSObject performSelector:] + 49
7   CoreFoundation                      0x00007fff86f08962 -[NSSet makeObjectsPerformSelector:] + 274
8   AppKit                              0x00007fff8d9d9c27 -[NSIBObjectData nibInstantiateWithOwner:topLevelObjects:] + 1245
9   AppKit                              0x00007fff8d9d01b9 loadNib + 322
10  AppKit                              0x00007fff8d9cf6b6 +[NSBundle(NSNibLoading) _loadNibFile:nameTable:withZone:ownerBundle:] + 217
11  AppKit                              0x00007fff8d9cf5d1 +[NSBundle(NSNibLoading) loadNibFile:externalNameTable:withZone:] + 141
12  AppKit                              0x00007fff8d9cf514 +[NSBundle(NSNibLoading) loadNibNamed:owner:] + 364
13  AppKit                              0x00007fff8dc42355 NSApplicationMain + 398
14  SongViewer                          0x0000000100001882 main + 34
15  SongViewer                          0x0000000100001854 start + 52
)
terminate called throwing an exception(gdb) 

如果有人知道可能出现的问题,请告诉我!!

2 个答案:

答案 0 :(得分:12)

好的,我明白了。解决方案是使用API​​提供的NSData原始数据而不是NSImage。所以我用过:

NSImage *songArtwork = [[NSImage alloc] initWithData:[artwork rawData]];

而不是

songArtwork = [artwork data];

答案 1 :(得分:0)

我必须从iTunes中获取批量的曲目艺术品并使用'rawData'。 但这种方式效率低下。 我找到了一种更好的方法(实际上它减少'获取'时间大约2倍,使用'valueForKey:'根据«Improving the Performance of Scripting Bridge Code»获取许多曲目的艺术品时非常重要。)

所以我决定了解iTunesArtwork'data'属性的错误。 我们希望得到一个NSImage对象(根据iTunes.h),但真实对象有点'NSAppleEventDescriptor'。而且很容易猜到,这个对象包含了我们的图像。所以我们可以使用'data'属性来获取图像数据。这比从iTunesArtwork获取'rawData'要快得多。 但有时iTunes会返回NSImage对象,而不是NSAppleEventDescriptor。这是一种奇怪的行为,但它仍然比使用rawData更快。