2012-10-27 22 views
1

今天我发现,当我向iTunes添加专辑封面时,它实际上只是将它添加到每张专辑中的一些曲目中。所以我做了任何人都会做的事,并试图写一个脚本来纠正这一点。如何通过ScriptingBridge设置iTunes专辑封面?

这是第一次尝试,经过约3小时的修补。它假定你已经选择了一个专辑中的所有歌曲。

#! /usr/local/bin/macruby 
framework 'Foundation' 
framework 'ScriptingBridge' 

itunes = SBApplication.applicationWithBundleIdentifier("com.apple.itunes") 
tracks = itunes.selection.get 

# Find some track with artwork 
artwork = tracks.map { |track| track.artworks[0] }.find { |a| a } 
raise "No selected song has artwork" if artwork.nil? 

# I checked artwork.rawData and it is PNG wrapped in an NSConcreteData. 
pngData = artwork.rawData 

tracks.each do |track| 
    if track.artworks[0] 
    puts "[O] #{track.name}" 
    else 
    puts "[X] #{track.name}" 
    # Adding the same artwork object is apparently NG so we get the data from it 
    # and make a copy. 
    # There is probably a more straight-forward way to clone an object but 
    # artwork.copy raises an exception. 
    # I have tried using the keys 'data' and 'raw data' instead - same results. 
    dict = {rawData: pngData} 
    artwork_copy = itunes.classForScriptingClass('artwork').alloc.initWithProperties(dict) 

    track.artworks.addObject(artwork_copy) 

    raise "Didn't actually add the artwork" if track.artworks.empty? 
    end 
end 

到ADDOBJECT的调用不会引发异常,但我注意到,它并没有真正的艺术作品添加到轨道(因此下一行加快测试脚本的检查。)

我一直主要从ScriptingBridge的Objective-C例子开始工作,并且无法找到其他人做过这些的地方。很多获得艺术品但是令人惊讶几个设置它的例子...

我的确从四年前发现一个有趣的邮件列表线程哪里别人也有类似的问题,但他们从来没有落下了解决方案要么(或发现它,并没有发布到线程,这是更糟的,如果他们这样做,他们是一个坏人,应该感觉不好。)

回答

1

这是一个Objective-C代码为了我。 我不知道macruby

iTunesApplication *iTunesApp = [SBApplication applicationWithBundleIdentifier: @"com.apple.iTunes"]; 
SBElementArray *tracks = [[iTunesApp selection] get]; 
NSArray *trackWithArt = [tracks filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"artworks[SIZE] > 0"]]; 
if ([trackWithArt count] > 0) { 
    NSImage *tData = (NSImage*)[[[[trackWithArt objectAtIndex:0] artworks] objectAtIndex:0] data]; 
    for (iTunesTrack *tObj in [tracks filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"artworks[SIZE] = 0"]]) { 
     [[[[tObj artworks] objectAtIndex:0] propertyWithCode:'pPCT'] setTo:tData]; 
    } 
} 

这里是工作的另一种方法:上述两种的

iTunesArtwork *tArtw = [[tObj artworks] objectAtIndex:0]; 
tArtw.data = tData; // set the track's artwork 

MacRuby的等价物:

由以下替换行中循环(我使用后者的原因很明显):

# 0x70504354 = 'pPCT' 
    track.artworks.objectAtIndex(0).propertyWithCode(0x70504354).setTo(artwork.data) 
    # or, 
    track.artworks.objectAtIndex(0).data = artwork.data 

-

另一种方法:使用AppleScript很简单。

+0

是的,我最终放弃使用AppleScript作为解决方法,但现在我看到了秘密。 :) – Trejkaz

+0

看来,秘密是使用objectAtIndex(n)而不是[n] - 数组是不可变的,[n]将始终返回nil,但objectAtIndex似乎自动创建该对象。 (回想起来,我可能不应该在刚才的编辑中说“我”,哈哈。) – Trejkaz