2012-10-27 66 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