【问题标题】:How can I set iTunes album artwork via ScriptingBridge?如何通过 ScriptingBridge 设置 iTunes 专辑插图?
【发布时间】:2012-10-27 02:31:58
【问题描述】:

今天我发现,当我将专辑插图添加到 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 示例开始工作,也找不到其他人做过的任何事情。 获得艺术品的例子很多,但令人惊讶的是,设置它的例子很少......

我确实发现了四年前的一个有趣的邮件列表线程,其他人也遇到了类似的问题,但他们也从未找到解决方案(或者找到它但没有将其发布到线程,这更糟糕,如果他们这样做了,他们是一个坏人,应该感到难过。)

【问题讨论】:

    标签: ruby itunes osx-mountain-lion scripting-bridge


    【解决方案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 非常简单。

    【讨论】:

    • 是的,一旦我最终放弃,我最终使用 AppleScript 作为解决方法,但现在我看到了秘密。 :)
    • 似乎秘密是使用 objectAtIndex(n) 而不是 [n] - 数组是不可变的, [n] 将始终返回 nil,但 objectAtIndex 似乎会自动创建对象。 (回想起来,我可能不应该在刚才那个编辑中说“我”,哈哈。)
    • 从当前的 iTunes (12) 版本开始,此版本不适用于没有艺术作品的曲目项目,替换现有艺术作品可以正常工作,但似乎任何对不存在项目 0 的引用都不会创建新的艺术品项目(不再),尝试了多种方法来添加一个新项目,它们似乎都不起作用(无论是来自苹果脚本还是来自objectiveC)你们中的任何人都知道一个可行的解决方案吗?
    • 更准确地说,它不适用于云存储的曲目(例如您在 iTunes Match 中拥有的曲目),对于仅本地存储的项目,它仍然可以正常工作
    猜你喜欢
    • 1970-01-01
    • 2014-07-22
    • 2016-10-25
    • 1970-01-01
    • 2010-11-28
    • 2016-09-24
    • 2011-08-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多