Menu

Skip to content
AppleScriptの穴
  • Home
  • Products
  • Books
  • Docs
  • Events
  • Forum
  • About This Blog
  • License
  • 仕事依頼

AppleScriptの穴

Useful & Practical AppleScript archive. Click '★Click Here to Open This Script' Link to download each AppleScript

iTunes Libraryの再生回数をジャンルごとに集計、ジャンル名名寄せ付き

Posted on 12月 2, 2019 by Takaaki Naganoya

iTunesLibrary.framework経由でiTunes/Music.appのライブラリのジャンルごとの再生回数を集計するAppleScriptです。

7,000曲程度入っているライブラリで、ジャンル名の名寄せも含め、開発環境(MacBook Pro Retina 2012, Core i7 2.66GHz@macOS 10.14.6)で0.7秒程度で終了します。2,500曲程度入っているMac mini 2014 Core i5 2.6GHz@macOS 10.15.1で0.6秒程度です。

macOS 10.14まで(iTunes.app)と、macOS 10.15以降(Music.app)でも同様にiTunesLibrary.framework経由でライブラリへのアクセスが行えます。

AppleScript名:iTunes Libraryの再生回数をジャンルごとに集計、ジャンル名名寄せ付き
— Created 2019-11-10 by Takaaki Naganoya
— 2019 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "iTunesLibrary"
–https://developer.apple.com/reference/ituneslibrary/itlibmediaitem?language=objc

property NSArray : a reference to current application’s NSArray
property NSString : a reference to current application’s NSString
property NSScanner : a reference to current application’s NSScanner
property NSPredicate : a reference to current application’s NSPredicate
property NSDictionary : a reference to current application’s NSDictionary
property NSCountedSet : a reference to current application’s NSCountedSet
property NSMutableArray : a reference to current application’s NSMutableArray
property NSSortDescriptor : a reference to current application’s NSSortDescriptor
property NSMutableCharacterSet : a reference to current application’s NSMutableCharacterSet

–ジャンル名寄せリスト(2要素から構成される2D List)
set genreNayoseList to {{"World", "ワールド"}, {"Anime", "アニメ"}, {"Electronic", "エレクトロニック"}, {"R&B/ソウル", "R&B/ソウル"}, {"Kayokyoku", "歌謡曲"}, {"Electronic", "エレクトロニック"}, {"Vocal", "ヴォーカル"}, {"Classical", "クラシック"}, {"Dance", "ダンス"}, {"Soundtrack", "サウンドトラック"}, {"Rock", "ロック"}}

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

set aRes1 to (library’s applicationVersion()) as string –>  "12.10.1.37" @ macOS 10.15
set aRes2 to (library’s apiMinorVersion()) –> 1
set aRes3 to (library’s apiMajorVersion()) –> 1

set playLists to library’s allPlaylists()
set gArray to library’s allMediaItems()’s genre
set aRes to countItemsByItsAppearance(gArray) of me

set bRes to genreNayoseAndUnify(aRes, genreNayoseList) of me
–> {{genreName:"サウンドトラック", numberOfTimes:1965}, {numberOfTimes:1209, genreName:"Podcast"}, {genreName:"ロック", numberOfTimes:1128}, {genreName:"クラシック", numberOfTimes:705}, {numberOfTimes:517, genreName:"ポップ"}, {genreName:"アニメ", numberOfTimes:533}, {numberOfTimes:383, genreName:"J-Pop"}, {numberOfTimes:292, genreName:"Pop"}, {numberOfTimes:279, genreName:"社会/文化"}, {numberOfTimes:252, genreName:missing value}, {genreName:"ワールド", numberOfTimes:246}, {numberOfTimes:187, genreName:"ジャズ"}, {genreName:"エレクトロニック", numberOfTimes:168}, {numberOfTimes:125, genreName:"R&B"}, {numberOfTimes:104, genreName:"ニューエイジ"}, {numberOfTimes:81, genreName:"Unclassifiable"}, {genreName:"歌謡曲", numberOfTimes:60}, {numberOfTimes:57, genreName:"Children’s"}, {numberOfTimes:54, genreName:"オルタナティブ"}, {numberOfTimes:38, genreName:"Holiday"}, {numberOfTimes:32, genreName:"Data"}, {numberOfTimes:31, genreName:"イージーリスニング"}, {genreName:"ヴォーカル", numberOfTimes:31}, {numberOfTimes:19, genreName:"iTunes U"}, {numberOfTimes:17, genreName:"フォーク"}, {numberOfTimes:15, genreName:"ブルース"}, {numberOfTimes:15, genreName:"ディズニー"}, {numberOfTimes:15, genreName:"シンガーソングライター"}, {numberOfTimes:14, genreName:"Easy Listening"}, {numberOfTimes:14, genreName:"ラテン"}, {numberOfTimes:14, genreName:"Electronica/Dance"}, {numberOfTimes:14, genreName:"個人ジャーナル"}, {genreName:"ダンス", numberOfTimes:12}, {numberOfTimes:10, genreName:"アクション/アドベンチャー"}, {numberOfTimes:9, genreName:"J-POP"}, {numberOfTimes:9, genreName:"New Age"}, {numberOfTimes:7, genreName:"演歌"}, {numberOfTimes:6, genreName:"少年"}, {numberOfTimes:6, genreName:"青年"}, {numberOfTimes:6, genreName:"キッズ/ファミリー"}, {numberOfTimes:5, genreName:"Video"}, {numberOfTimes:5, genreName:"プログラミング"}, {numberOfTimes:4, genreName:"ホリデー"}, {numberOfTimes:4, genreName:"カントリー"}, {numberOfTimes:4, genreName:"科学/医学"}, {numberOfTimes:3, genreName:"ビジネス"}, {numberOfTimes:3, genreName:"コメディ"}, {numberOfTimes:3, genreName:"Game Music"}, {numberOfTimes:3, genreName:"Latin"}, {genreName:"R&B/ソウル", numberOfTimes:5}, {numberOfTimes:2, genreName:"#NIPPONSEI @ IRC.MIRCX.COM"}, {numberOfTimes:2, genreName:"Technology"}, {numberOfTimes:2, genreName:"ヒップホップ/ ラップ"}, {numberOfTimes:2, genreName:"ヒップホップ/ラップ"}, {numberOfTimes:2, genreName:"日本"}, {numberOfTimes:2, genreName:"ドラマ"}, {numberOfTimes:1, genreName:"社会科学"}, {numberOfTimes:1, genreName:"コンピュータ/テクノロジー"}, {numberOfTimes:1, genreName:"Tech ニュース"}, {numberOfTimes:1, genreName:"科学/自然"}, {numberOfTimes:1, genreName:"その他"}, {numberOfTimes:1, genreName:"児童書フィクション"}, {numberOfTimes:1, genreName:"レゲエ"}, {numberOfTimes:1, genreName:"Lifestyle & Home"}, {numberOfTimes:1, genreName:"ホリデーミュージック"}, {numberOfTimes:1, genreName:"マネジメント/リーダーシップ"}, {numberOfTimes:1, genreName:"インストゥルメンタル"}, {numberOfTimes:1, genreName:"SF/ファンタジー"}, {numberOfTimes:1, genreName:"146"}, {numberOfTimes:1, genreName:"健康/フィットネス"}, {numberOfTimes:1, genreName:"148"}, {numberOfTimes:1, genreName:"NHK FM(東京)"}, {numberOfTimes:1, genreName:"Seattle Pacific University – Latin"}, {numberOfTimes:1, genreName:"チルドレン・ミュージック"}, {numberOfTimes:1, genreName:"名作"}, {numberOfTimes:1, genreName:"Folk"}}

–ジャンルのリストを出現回数で集計
on countItemsByItsAppearance(aList)
  set aSet to NSCountedSet’s alloc()’s initWithArray:aList
  
set bArray to 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:(NSDictionary’s dictionaryWithObjects:{aValue, (aSet’s countForObject:aValue)} forKeys:{"genreName", "numberOfTimes"})
  end repeat
  
  
–出現回数(numberOfTimes)で降順ソート
  
set theDesc to NSSortDescriptor’s sortDescriptorWithKey:"numberOfTimes" ascending:false
  
bArray’s sortUsingDescriptors:{theDesc}
  
  
return bArray as list
end countItemsByItsAppearance

on genreNayoseAndUnify(aList as list, genreNayoseList as list)
  set gList to FlattenList(genreNayoseList) of me
  
  
set didProc to {}
  
  
set a2List to {}
  
  
repeat with i in aList
    set aGenre to genreName of i
    
    
if (aGenre is in gList) and (aGenre is not in didProc) then
      
      
repeat with ii in genreNayoseList
        set jj to contents of ii
        
        
if aGenre is in jj then
          copy jj to {g1, g2}
          
          
          
if chkAlphabet(g1) of me = true then
            set targG to g2
            
set targG2 to g1
          else
            set targG to g1
            
set targG2 to g2
          end if
          
          
          
set s1Res to searchByGenreName(aList, targG) of me
          
set s2Res to searchByGenreName(aList, targG2) of me
          
          
          
set s3Res to addMutipleLists({s1Res, s2Res}) of me
          
          
set tmpClass to class of s3Res
          
if tmpClass = list then
            set s3Res to contents of first item of s3Res
          end if
          
          
set outRec to {genreName:targG, numberOfTimes:s3Res}
          
set the end of didProc to g1
          
set the end of didProc to g2
          
          
exit repeat
        end if
        
      end repeat
      
      
set the end of a2List to outRec
    else
      if (aGenre is not in didProc) then
        set the end of a2List to contents of i
      end if
    end if
  end repeat
  
  
return a2List
end genreNayoseAndUnify

on searchByGenreName(aList as list, aGenreName as string)
  set predicatesStr to "genreName == ’" & aGenreName & "’"
  
set anArray to (NSArray’s arrayWithArray:aList)
  
set aPred to (NSPredicate’s predicateWithFormat:predicatesStr)
  
set bRes to (anArray’s filteredArrayUsingPredicate:aPred)
  
if (bRes as list) = {} then return {}
  
  
set bbRes to first item of bRes
  
return (numberOfTimes of bbRes) as list
end searchByGenreName

on addMutipleLists(s1List)
  script spdAdd
    property s1List : {}
    
property s3List : {}
  end script
  
  
copy s1List to (s1List of spdAdd) –init
  
  
set s1Len to length of first item of (s1List of spdAdd)
  
set (s3List of spdAdd) to makeZero1DList(s1Len, 0) of me
  
  
repeat with i in (s1List of spdAdd)
    set tmpLen to length of i
    
if tmpLen is not equal to s1Len then return false
    
    
repeat with ii from 1 to s1Len
      set tmp1 to contents of item ii of (s3List of spdAdd)
      
set tmp2 to contents of item ii of i
      
      
set item ii of (s3List of spdAdd) to (tmp1 + tmp2)
    end repeat
  end repeat
  
  
return (s3List of spdAdd)
end addMutipleLists

–指定要素を指定回数追加したリストを作成する
on makeZero1DList(itemMax, itemElem)
  set allData to {}
  
repeat itemMax times
    set the end of allData to itemElem
  end repeat
  
return allData
end makeZero1DList

–By Paul Berkowitz
–2009年1月27日 2:24:08:JST
–Re: Flattening Nested Lists
on FlattenList(aList)
  set oldDelims to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to {"????"}
  
set aString to aList as text
  
set aList to text items of aString
  
set AppleScript’s text item delimiters to oldDelims
  
return aList
end FlattenList

— アルファベットのみか調べて返す
on chkAlphabet(checkString)
  set aStr to NSString’s stringWithString:checkString
  
set allCharSet to NSMutableCharacterSet’s alloc()’s init()
  
allCharSet’s addCharactersInRange:(current application’s NSMakeRange(ASCII number of "a", 26))
  
allCharSet’s addCharactersInRange:(current application’s NSMakeRange(ASCII number of "A", 26))
  
set aBool to my chkCompareString:aStr baseString:allCharSet
  
return aBool as boolean
end chkAlphabet

on chkCompareString:checkString baseString:baseString
  set aScanner to NSScanner’s localizedScannerWithString:checkString
  
aScanner’s setCharactersToBeSkipped:(missing value)
  
aScanner’s scanCharactersFromSet:baseString intoString:(missing value)
  
return (aScanner’s isAtEnd()) as boolean
end chkCompareString:baseString:

★Click Here to Open This Script 

More from my site

  • ジャンル名名寄せ v2ジャンル名名寄せ v2
  • iTunesライブラリ中の楽曲のみしぼりこんでアルバム名と曲名を出力 v2iTunesライブラリ中の楽曲のみしぼりこんでアルバム名と曲名を出力 v2
  • iTunesライブラリ中の楽曲のみしぼりこんでアルバムのtitle一覧を取得iTunesライブラリ中の楽曲のみしぼりこんでアルバムのtitle一覧を取得
  • iTunesライブラリ中の楽曲のみしぼりこんでtitle取得iTunesライブラリ中の楽曲のみしぼりこんでtitle取得
  • iTunesライブラリ中の各trackの種別を集計(media種別)iTunesライブラリ中の各trackの種別を集計(media種別)
  • iTunesライブラリ中のアートワークをすべてJPEGで書き出し v2iTunesライブラリ中のアートワークをすべてJPEGで書き出し v2
(Visited 68 times, 1 visits today)
Posted in list | Tagged 10.12savvy 10.13savvy 10.14savvy 10.15savvy NSArray NSCountedSet NSDictionary NSMutableArray NSMutableCharacterSet NSPredicate NSScanner NSSortDescriptor NSString | Leave a comment

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

電子書籍(PDF)をオンラインストアで販売中!

Google Search

Popular posts

  • macOS 13, Ventura(継続更新)
  • アラートダイアログ上にWebViewで3Dコンテンツを表示(WebGL+three.js)v3
  • UI Browserがgithub上でソース公開され、オープンソースに
  • Xcode 14.2でAppleScript App Templateを復活させる
  • macOS 13 TTS Voice環境に変更
  • 2022年に書いた価値あるAppleScript
  • ChatGPTで文章のベクトル化(Embedding)
  • 新発売:AppleScriptからSiriを呼び出そう!
  • iWork 12.2がリリースされた
  • 従来と異なるmacOS 13の性格?
  • 新発売:CotEditor Scripting Book with AppleScript
  • macOS 13対応アップデート:AppleScript実践的テクニック集(1)GUI Scripting
  • AS関連データの取り扱いを容易にする(はずの)privateDataTypeLib
  • macOS 12.5.1、11.6.8でFinderのselectionでスクリーンショット画像をopenできない問題
  • macOS 13でNSNotFoundバグふたたび
  • ChatGPTでchatに対する応答文を取得
  • 新発売:iWork Scripting Book with AppleScript
  • Finderの隠し命令openVirtualLocationが発見される
  • macOS 13.1アップデートでスクリプトエディタの挙動がようやくまともに
  • あのコン過去ログビューワー(暫定版)

Tags

10.11savvy (1101) 10.12savvy (1242) 10.13savvy (1390) 10.14savvy (586) 10.15savvy (434) 11.0savvy (277) 12.0savvy (185) 13.0savvy (55) CotEditor (60) Finder (47) iTunes (19) Keynote (98) NSAlert (60) NSArray (51) NSBezierPath (18) NSBitmapImageRep (20) NSBundle (20) NSButton (34) NSColor (51) NSDictionary (27) NSFileManager (23) NSFont (18) NSImage (41) NSJSONSerialization (21) NSMutableArray (62) NSMutableDictionary (21) NSPredicate (36) NSRunningApplication (56) NSScreen (30) NSScrollView (22) NSString (117) NSURL (97) NSURLRequest (23) NSUTF8StringEncoding (30) NSView (33) NSWorkspace (20) Numbers (56) Pages (37) Safari (41) Script Editor (20) WKUserContentController (21) WKUserScript (20) WKUserScriptInjectionTimeAtDocumentEnd (18) WKWebView (23) WKWebViewConfiguration (22)

カテゴリー

  • 2D Bin Packing
  • 3D
  • AirDrop
  • AirPlay
  • Animation
  • AppleScript Application on Xcode
  • beta
  • Bluetooth
  • Books
  • boolean
  • bounds
  • Bug
  • Calendar
  • call by reference
  • Clipboard
  • Code Sign
  • Color
  • Custom Class
  • dialog
  • drive
  • exif
  • file
  • File path
  • filter
  • folder
  • Font
  • Font
  • GAME
  • geolocation
  • GUI
  • GUI Scripting
  • Hex
  • History
  • How To
  • iCloud
  • Icon
  • Image
  • Input Method
  • Internet
  • iOS App
  • JavaScript
  • JSON
  • JXA
  • Keychain
  • Keychain
  • Language
  • Library
  • list
  • Locale
  • Machine Learning
  • Map
  • Markdown
  • Menu
  • Metadata
  • MIDI
  • MIME
  • Natural Language Processing
  • Network
  • news
  • Noification
  • Notarization
  • Number
  • Object control
  • OCR
  • OSA
  • PDF
  • Peripheral
  • PRODUCTS
  • QR Code
  • Raw AppleEvent Code
  • Record
  • rectangle
  • recursive call
  • regexp
  • Release
  • Remote Control
  • Require Control-Command-R to run
  • REST API
  • Review
  • RTF
  • Sandbox
  • Screen Saver
  • Script Libraries
  • sdef
  • search
  • Security
  • selection
  • shell script
  • Shortcuts Workflow
  • Sort
  • Sound
  • Spellchecker
  • Spotlight
  • SVG
  • System
  • Tag
  • Telephony
  • Text
  • Text to Speech
  • timezone
  • Tools
  • Update
  • URL
  • UTI
  • Web Contents Control
  • WiFi
  • XML
  • XML-RPC
  • イベント(Event)
  • 未分類

アーカイブ

  • 2023年9月
  • 2023年8月
  • 2023年7月
  • 2023年6月
  • 2023年5月
  • 2023年4月
  • 2023年3月
  • 2023年2月
  • 2023年1月
  • 2022年12月
  • 2022年11月
  • 2022年10月
  • 2022年9月
  • 2022年8月
  • 2022年7月
  • 2022年6月
  • 2022年5月
  • 2022年4月
  • 2022年3月
  • 2022年2月
  • 2022年1月
  • 2021年12月
  • 2021年11月
  • 2021年10月
  • 2021年9月
  • 2021年8月
  • 2021年7月
  • 2021年6月
  • 2021年5月
  • 2021年4月
  • 2021年3月
  • 2021年2月
  • 2021年1月
  • 2020年12月
  • 2020年11月
  • 2020年10月
  • 2020年9月
  • 2020年8月
  • 2020年7月
  • 2020年6月
  • 2020年5月
  • 2020年4月
  • 2020年3月
  • 2020年2月
  • 2020年1月
  • 2019年12月
  • 2019年11月
  • 2019年10月
  • 2019年9月
  • 2019年8月
  • 2019年7月
  • 2019年6月
  • 2019年5月
  • 2019年4月
  • 2019年3月
  • 2019年2月
  • 2019年1月
  • 2018年12月
  • 2018年11月
  • 2018年10月
  • 2018年9月
  • 2018年8月
  • 2018年7月
  • 2018年6月
  • 2018年5月
  • 2018年4月
  • 2018年3月
  • 2018年2月

https://piyomarusoft.booth.pm/items/301502

メタ情報

  • ログイン
  • 投稿フィード
  • コメントフィード
  • WordPress.org

Forum Posts

  • 人気のトピック
  • 返信がないトピック

メタ情報

  • ログイン
  • 投稿フィード
  • コメントフィード
  • WordPress.org
Proudly powered by WordPress
Theme: Flint by Star Verte LLC