7

我一直在试图弄清楚如何使用脚本桥获取当前正在播放的歌曲的 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) 

如果有人知道可能出了什么问题,请告诉我!!

4

2 回答 2

12

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

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

而不是

songArtwork = [artwork data];
于 2011-08-16T12:01:04.347 回答
0

我必须从 iTunes 中获取一批曲目作品并使用“rawData”。但这种方式效率低下。我找到了一个更好的方法(实际上它减少了大约 2 倍的 'fetch' 时间,这在使用 'valueForKey:' 根据«提高脚本桥代码的性能»为许多曲目获取艺术品时非常重要)。

所以我决定了解 iTunesArtwork 的“数据”属性有什么问题。我们希望得到一个 NSImage 对象(根据 iTunes.h ),但真正的对象是 '<a href="https://developer.apple.com/library/mac/documentation/cocoa/Reference/Foundation/Classes /NSAppleEventDescriptor_Class/Reference/Reference.html" rel="nofollow">NSAppleEventDescriptor'。很容易猜到,这个对象包含我们的图像。所以我们可以只使用'data'属性来获取图像数据。这比从 iTunesArtwork 获取“原始数据”要快得多。但有时 iTunes 返回 NSImage 对象而不是 NSAppleEventDescriptor。这是一个奇怪的行为,但它仍然比使用 rawData 更快。

于 2014-02-03T07:11:38.127 回答