Archive for the 'ITLibrary' Category

2017/01/07 iTunesライブラリの曲のアーティスト名を集計

iTunesライブラリ中に入っている「曲」(song)のアーティスト名を集計するAppleScriptです。

iTunesLibraryフレームワークを用いてライブラリにアクセスしているので、iTunes.appが起動している必要はありません。

アーティスト名については、ライブラリ中にかなりイレギュラーなデータが存在しているため、対策が必要でした。

・初期のiTunesで、CDからリッピングしたものの、CDDBに登録がなかったため、アーティスト名などが登録されていない→ エラートラップで対処

・アーティスト名で姓(last name)と名(first name)の間に空白が入っていたりいなかったりするなど、表記ゆらぎが存在していたため、ゆらぎを吸収

もう少し高速に実行できてもよさそうですが、ライブラリ中のtrackが8,100程度のときに、10回実行時の平均は2.8秒程度です(MacBook Pro Retina 2012)。

AppleScript名:iTunesライブラリの曲のアーティスト名を集計
– Created 2017-01-07 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “iTunesLibrary”
–http://piyocast.com/as/archives/4379

set library to current application’s ITLibrary’s libraryWithAPIVersion:“1.0″ |error|:(missing value)
if library is equal to missing value then return

set allTracks to library’s allMediaItems()
set allCount to allTracks’s |count|()

set anEnu to allTracks’s objectEnumerator()
set newArray to current application’s NSMutableArray’s alloc()’s init()

repeat
  set aPL to anEnu’s nextObject()
  
if aPL = missing value then exit repeat
  
try
    set aKind to (aPL’s mediaKind) as integer
    
    
if (aKind as integer) is equal to 2 then –Music, Song
      set plName to aPL’s artist’s |name| as string
      
set pl2Name to (my changeThis:” “ toThat:“” inString:plName) –日本語アーティスト名で姓と名の間にスペースが入っているものがある(表記ゆらぎ)ので対策
      
newArray’s addObject:(pl2Name)
    end if
  on error
    set aLoc to (aPL’s location’s |path|()) as string
    
log aLoc
  end try
end repeat

set aRes to countItemsByItsAppearance(newArray) of me
–>  {{theName:”浜田省吾”, numberOfTimes:442}, {theName:”B’z”, numberOfTimes:379}, {theName:”渡辺岳夫・松山祐士”, numberOfTimes:199}, {theName:”VariousArtists”, numberOfTimes:192}, {theName:”菅野よう子”, numberOfTimes:108}, {theName:”布袋寅泰”, numberOfTimes:100}, {theName:”三枝成彰”, numberOfTimes:95}, {theName:”宇多田ヒカル”, numberOfTimes:94}, {theName:”宮川泰”, numberOfTimes:81}, {theName:”MichaelJackson”, numberOfTimes:78}, {theName:”稲葉浩志”, numberOfTimes:73}, …

–出現回数で集計
on countItemsByItsAppearance(aList)
  set aSet to current application’s NSCountedSet’s alloc()’s initWithArray:aList
  
set bArray to current application’s NSMutableArray’s array()
  
set theEnumerator to aSet’s objectEnumerator()
  
  
repeat
    set aValue to theEnumerator’s nextObject()
    
if aValue is missing value then exit repeat
    
bArray’s addObject:(current application’s NSDictionary’s dictionaryWithObjects:{aValue, (aSet’s countForObject:aValue)} forKeys:{“theName”, “numberOfTimes”})
  end repeat
  
  
–出現回数(numberOfTimes)で降順ソート
  
set theDesc to current application’s NSSortDescriptor’s sortDescriptorWithKey:“numberOfTimes” ascending:false
  
bArray’s sortUsingDescriptors:{theDesc}
  
  
return bArray as list
end countItemsByItsAppearance

on changeThis:findString toThat:repString inString:someText
  set theString to current application’s NSString’s stringWithString:someText
  
set theString to theString’s stringByReplacingOccurrencesOfString:findString withString:repString options:(current application’s NSRegularExpressionSearch) range:{location:0, |length|:length of someText}
  
return theString as text
end changeThis:toThat:inString:

★Click Here to Open This Script 

2016/11/02 iTunesライブラリ中の楽曲のジャンルを集計して多い順にソートして出力

iTunesライブラリ中の楽曲のジャンルを集計して多い順にソートして返すAppleScriptです。

集計部分をCocoaで行っているので、集計部分自体が相当に高速なのですが、手元のMacBook Pro Retina 2012(Core i7 2.6GHz)で音声データが6,861件iTunesに登録されている環境で処理したところ、

  アプリケーション(iTunes)を直接呼び出し:3.5秒
  すべてフレームワーク経由で処理:0.03秒

と、アプリケーションを直接操作しないでフレームワーク経由で楽曲の情報を取得して処理するとアプリケーションへの問い合わせを行うよりも100倍以上高速です。

iTunes Music Library.xmlを読み取って処理してもだいたいフレームワーク経由の処理と同じかやや高速なぐらいに落ち着くと思われます。
補足:XML経由の処理はAppleScriptだと(Cocoaの機能を使っても)ムチャクチャ時間がかかりました。参考までに

ただ、処理結果が方法によってほんの微妙に変わるのはジャンル判定処理が異なるためでしょうか。やや、気になります。

GUIアプリ経由で情報を取得するのと、フレームワークを呼び出して情報を取得するのと、XMLを自力で解析するのとでは、提供してくれる機能が違うので、用途に応じて適切なものを取捨選択することになります。「現在再生中の曲」「曲リスト中で選択中のもの」といった情報が必要な場合にはGUIアプリ(iTunes)に問い合わせるのが正解です。

AppleScript名:iTunesライブラリ中の楽曲のジャンルを集計して多い順にソートして出力(アプリケーション呼び出し)
– Created 2016-10-30 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4301

tell application “iTunes”
  –set aList to genre of (every file track whose media kind is equal to song and genre is not equal to “”)
  
set aList to genre of every file track
end tell

set aRes to countItemsByItsAppearance(aList) of me
return aRes
–> {{theName:”サウンドトラック”, numberOfTimes:1721}, {theName:”ロック”, numberOfTimes:942}, {theName:”クラシック”, numberOfTimes:539},

–ジャンルのリストを出現回数で集計
on countItemsByItsAppearance(aList)
  set aSet to current application’s NSCountedSet’s alloc()’s initWithArray:aList
  
set bArray to current application’s NSMutableArray’s array()
  
set theEnumerator to aSet’s objectEnumerator()
  
  
repeat
    set aValue to theEnumerator’s nextObject()
    
if aValue is missing value then exit repeat
    
bArray’s addObject:(current application’s NSDictionary’s dictionaryWithObjects:{aValue, (aSet’s countForObject:aValue)} forKeys:{“theName”, “numberOfTimes”})
  end repeat
  
  
–出現回数(numberOfTimes)で降順ソート
  
set theDesc to current application’s NSSortDescriptor’s sortDescriptorWithKey:“numberOfTimes” ascending:false
  
bArray’s sortUsingDescriptors:{theDesc}
  
  
return bArray as list
end countItemsByItsAppearance

★Click Here to Open This Script 

AppleScript名:iTunesライブラリ中の楽曲のジャンルを集計して多い順にソートして出力(フレームワーク呼び出し)
– Created 2016-11-02 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “iTunesLibrary”
–http://piyocast.com/as/archives/4301

set library to current application’s ITLibrary’s libraryWithAPIVersion:“1.0″ |error|:(missing value)
if library is equal to missing value then return

set playLists to library’s allPlaylists()
set gArray to library’s allMediaItems()’s genre
set aRes to countItemsByItsAppearance(gArray) of me
–> {{theName:”サウンドトラック”, numberOfTimes:1722}, {theName:”ロック”, numberOfTimes:956}, {theName:”Podcast”, numberOfTimes:755},

–ジャンルのリストを出現回数で集計
on countItemsByItsAppearance(aList)
  set aSet to current application’s NSCountedSet’s alloc()’s initWithArray:aList
  
set bArray to current application’s NSMutableArray’s array()
  
set theEnumerator to aSet’s objectEnumerator()
  
  
repeat
    set aValue to theEnumerator’s nextObject()
    
if aValue is missing value then exit repeat
    
bArray’s addObject:(current application’s NSDictionary’s dictionaryWithObjects:{aValue, (aSet’s countForObject:aValue)} forKeys:{“theName”, “numberOfTimes”})
  end repeat
  
  
–出現回数(numberOfTimes)で降順ソート
  
set theDesc to current application’s NSSortDescriptor’s sortDescriptorWithKey:“numberOfTimes” ascending:false
  
bArray’s sortUsingDescriptors:{theDesc}
  
  
return bArray as list
end countItemsByItsAppearance

★Click Here to Open This Script 

2016/02/10 iTunesライブラリ内のメディアへのアクセス

iTunesのライブラリにアクセスして情報を取得するAppleScriptです。

AppleScriptでは一般的にiTunesに対して直接命令を実行して、選択中のトラックの情報を取得したり、さまざまな処理を行います。これが最も一般的です。

ただし、これだとスピードを稼げないため、外部にXML形式で保存されているiTunes Library(iTunes Music Library.xml)ファイルに直接アクセスして、一般的なXMLを扱うように処理する方法も存在しています。これも実際にASOCで試してみました。

iTunes 11以降がインストールされた環境では、iTunes Libraryへのアクセスフレームワーク「iTunesLibrary.framework」が利用でき、これを経由して間接的にiTunes Music Library.xmlにアクセスして情報の取得が行えます。本AppleScriptはこの方法を試してみたものです。

たいてい、AppleScriptでiTunesにアクセスして遅いのなんのと言われている場合には,力辰任△蝓iTunes登場直後から外部にXMLベースのライブラリ情報が書き出されていたことからも、大量のデータ取得には△諒法が推奨されてきたことが伺い知れます。それにもかかわらず、「わざわざ遅い方法を使って大量のデータを取得すると時間がかかる」というのは至極当然のことです。

ユーザーが選択したトラックの情報を取得するのであれば,鮖箸Δ里得策ですが、スピードを重視するのであれば△筬が、iTunes上でCD取り込みやMusic Storeからの楽曲購入に伴うデータ更新を考慮するのであればが適しているのではないかと思うものです。

AppleScript名:iTunesライブラリ内のメディアへのアクセス
– Created 2016-02-10 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “iTunesLibrary”

set library to current application’s ITLibrary’s libraryWithAPIVersion:“1.0″ |error|:(missing value)
if library is equal to missing value then return

set playLists to library’s allPlaylists()
set tracks to library’s allMediaItems()

set tracksTotal to tracks’s |count|()
log tracksTotal

repeat with i in tracks
  set j to contents of i
  
  set aTitle to j’s title()
  
set anArtist to j’s playCount()
  
end repeat

★Click Here to Open This Script