iTunes用スクリプト

本日の成果:iTunes用のスクリプトをいくつか作った

  私は音楽データはアルバム毎にサーバの特定のフォルダに入れて管理しています。さらにiPhoneとかも使っている関係上、iTunesも使わざるを得ないのですが、iTunesはiTunesで独自のライブラリ管理方式を採っているので、下手すると二重管理になってしまいます。CD買ってきてエンコードしてサーバに放り込んでも、それだけではiTunesひいてはiPhoneでは聴けないのです。

  そこでなるべく省力化するべく、(MacなのでAppleScriptで)自動でその辺をやってくれるスクリプトを作ることにしたのですが、これがまた大変でした・・・。

  まずはエンコードしてサーバに放り込んだあとの作業を自動化しよう。ということで、指定フォルダ内をサーチして、iTunesにまだ登録されていない曲だけを登録するスクリプトを作ってみたよ。
  単におおもとになるフォルダをドラッグ & ドロップで登録してやればいいのかもしれないけど、登録したいフォルダがいくつかあって、毎回忘れずに登録するのが面倒なのと、ついでに登録日のプレイリストを作って登録するということもやりたかったので頑張ってゴリゴリひとつひとつの処理を書いてみたよ。

  しかし結論としてはAppleScriptの文法と動きのクセに翻弄されてえらい苦労することになった。うーんこの言語、きっと登場当時はオブジェクト指向ぽくて複数オブジェクトの一括操作ができたりもして大変革新的に見えたのでしょうが、私が今回やってみた感想としてはいくつか違和感を感じる点もありました。
  例えば文法を英語的なものにした結果(それどころか昔は日本語風に書くこともできたらしいですね)、逆に他の言語に比べて何やってるか判り辛くなってると思います。複数単語でひとつのキーワードだったりして、どれが変数でどれがクラス名やプロパティでどれがキーワードなのかが判りづらいです。CやLISPみたいに記号だらけなのもアレですがAppleScriptは記号少なすぎだと思います。構文解析とか一体どうやってやってるんだろう・・・。構文木というより意味木みたいなものを構築しているのかしらん。でも、理解しやすいようにと英語っぽくする試みの失敗例を私は知っています。COBOLといいます(笑)。英語っぽいけど英語じゃないCOBOLという言語の文法を結局新たに憶える必要がありました。

  あと、参照の取り扱いにクセがあります。例えば、リストの要素を一つ一つ処理するためにrepeat withでループさせた場合、ループ1回毎にリストの要素がひとつづつ渡されるわけですが、例えばXという名前のA,B,C…という要素を持つリストでループを組んだとしますと、その時の渡され方が「XというリストのN番目の要素」という渡され方のようなのです。そのものずばり「Aへの参照」とか「Bへの参照」などではなく。そしてそれを実際に参照したときに、XというリストのN番目の要素を探しにいってその結果を返してきます。でこのループが10000回目ぐらいになると、Xというリストの10000番目の要素を律儀に探しに行っているのか、目に見えて遅くなります。わざわざリストに特化した文法を使うメリットがあまりなく効率的でないように思えます。それだけではありません。例えば3回目のループ(Cのループ)の途中でリストからBを削除したとします。さて「Cのループ」と言いましたが今注目しているのは実は「C」ではなくて「Xの3番目の要素」なのでその瞬間からループ変数はCではなくDを指すことになります。なんかホントにそんな仕様でいいんですかJobsさんと言いたくなるような動きで、実際私もこれで一晩ハマりました。

  処理速度にも悩まされました。とりあえずインタプリタであることを差し引いても全体的に遅いです。メモリも食います。特に、扱うリストのサイズが増えるとN^2オーダー(体感)で時間がかかります。また、上で述べたとおりオブジェクトへの参照の持ち方が特殊なこともあってか、書き方のちょっとした違いにより処理速度が大きく変わるのです。一旦ワーク変数に代入したら速くなったり、キャストすると速くなったり。えてしてスマートで簡潔な表記より、冗長な判りづらい表記の方が速かったりするのがストレスが溜まります。それからこれは環境依存なのだと思うのですが、OS付属のスクリプトエディタから実行すると、メモリが開放されません。いきおい、デバッグ作業で何度も実行するうちに、どんどんメモリを消費して、スワップ始めて、動作速度が亀のようになります。ところが、アプリケーション形式にして実行したり、(スクリプトエディタではなく)iTunesから実行したら普通のメモリ消費量で動きます。この件でも私はスクリプトの書き方の問題だと思ってなんとかならないかと無駄に高速化や省メモリ化を試みたりして一晩無駄に費やしましたよ。

  で、とりあえず一撃で未登録の曲ファイルを追加できるようにはなりました。なりましたのですが、ひとつ問題点が。というのは、いったんiTunesに登録した後で、ファイル名を変更したとかでiTunesから実体が参照できなくなっている曲。これが二重に追加されてしまいます。そこで、そのような、ファイルの実体が参照できなくなっている曲を探して削除候補のプレイリストに纏めるスクリプトを書こうとしたのですが、なんだかiTunesの仕様上、実体が参照できなくて「(!)マーク」がついてる曲は、プレイリストに入れることができないようで、仕方ないので一覧表示して確認したうえで削除することにしました。(削除だけはできる)

  ファイルの実体が見つからないデータがあると、削除するか尋ねる

  削除成功

  念の為もう一度実行すると、今度は紛失ファイルはない

  そしてもうひとつ。私はiTunesのプレイリスト機能はあまり使っていませんでした。ひとつづつ自分で作るのが面倒だったからです。今回、折角なのでついでに、アーティスト別/アルバム別にプレイリストを自動的に生成してくれるスクリプトを作ってみることにしました。ま、なんというか、それならプレイリストを作るまでもなく、画面右上の検索欄で検索すればほとんど同じことはできる話ではあるのですが、リストから選ぶ方式のほうがちょっとだけ簡単かなと。

  で、その結果、前述のとおり処理速度の遅さなどに泣かされる結果となったのですが、なんとか我慢できる速度にはなりました。それでも8千トラックを処理するのに数時間かかります・・・。アルバム別とはいっても、違うアーティストの同名アルバムが同じプレイリストに入ってしまっては嫌なので、その辺のチェックでさらに負荷かかってます・・・。

アーティスト別
アルバム別
登録日別 (ついでに対応)

投稿日

カテゴリー:

投稿者:

コメント

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です