Как настроить обложку альбома 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 не вызывает исключения, но я заметил, что на самом деле он не добавляет обложку в трек (отсюда проверка на следующей строке, чтобы ускорить тестирование скрипта.)
Я работал в основном с примерами Objective-C ScriptingBridge и не могу найти ни одного, где другие люди сделали это тоже. Множество примеров получения художественных работ, но удивительно мало для их установки...
Четыре года назад я нашел интересную ветку списка рассылки, где у кого-то еще была похожая проблема, но они так и не нашли решения (или нашли его и не опубликовали в ветке, что еще хуже, и если они это сделали) они плохой человек и должны чувствовать себя плохо.)
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.