Quantcast
Channel: 迷い家の白猫 Blog
Viewing all articles
Browse latest Browse all 107

[Ruby] iTunes - ディレクトリ構成から、MP3タグを更新

$
0
0
転んでもただでは起きないよw


2012年05月16日水曜日 に音楽ファイルが消えてしまったけど、復元はできた。 
復元できたファイルは、曲名が復元できなかったので整理は後回し。 

MP3タグを付けてない音楽ファイルは別のHDDに入っていたので無事だったので、 
消えた音楽ファイルの場所にファイルを同期。 
ファイル名は元通り。ただMP3タグは付いてない。。。

MP3タグ付けは気の遠くなる作業で、さらに気が遠くなる。。。それを考えると・・・orz
そうだ!自動化だ! と思い、昨日1日調査と実装してました。 

因みに言語は、Rubyです。 

取りあえず、完成しました。 

以下で動作確認済みです。
・Windows 7 Professional 64bit
・Ruby 1.9.3p194
・iTunes 10.6.1.7

曲名、トラック番号、アルバム名、グループのタグ付けをファイルパスからMP3タグを付けるようなプログラムを作りました。 
こんなディレクトリ構成しているのは、きっと珍しいから、たぶんこのコードは使えないと思います。

一応、参考になればと思い、コードを以下に公開しておきます。

※2012/05/22更新
iTunes_mp3tag_update.rb
# -*- encoding: utf-8 -*-
# -------------------------------------------------------------------------------
# iTunes_mp3tag_update.rb
# iTunes - ディレクトリ構成によって、MP3タグを更新。
# 更新するMP3タグ : 曲名、トラック番号、アルバム名、グループ名
# (c) 2012 shiro
#
# 動作確認済み:
# Windows 7 Professional 64bit
# Ruby 1.9.3p194
# iTunes 10.6.1.7
#
# ex) 以下のようなディレクトリ構成で有効です。
# Music/
# ├ グループ名2
# ├ 01.アルバム名1
# | ├ 01.曲名1.mp3
# | └ 02.曲名2.mp3
# └ 02.アルバム名2
# ├ DISC-1
# | ├ 01.曲名3.mp3
# | └ 02.曲名4.mp3
# └ DISC-2
# ├ 01.曲名5.mp3
# └ 02.曲名6.mp3
# -------------------------------------------------------------------------------

require 'win32ole'
require 'pathname'

class String
# 半角記号だとフォルダ名、ファイル名に使用できない文字を半角文字に変換
def normalize
self.tr("&%}{#|><”?*:/","&%}{#|><\"?*:/").tr("¥","\\")
end
end

# 音楽ファイル
ITTrackKindFile = 1
# 変更された曲数
modify_count = 0
# 例外数
exception_count = 0
exception_text = []
# 削除数
deleted_tracks = 0

# iTunes 初期化
itunes_app = WIN32OLE.new("iTunes.Application")
# メインライブラリ
playlist = itunes_app.LibraryPlayList
# 特定のプレイリスト
#playlist = itunes_app.LibrarySource.Playlists.ItemByName("無題のプレイリスト")
start_time = Time.now

begin
# プレイリスト内のトラックを取得
tracks = playlist.Tracks

if playlist
#プレイリスト中の曲数
num_tracks = tracks.Count

num_tracks.downto(1) do |i|
track = tracks.Item(i)
begin
if track.Kind == ITTrackKindFile
if track.Location == ""
# デッドリンク削除
track.Delete()
deleted_tracks += 1
else
# 変更フラグ
modify_flag = false

# 曲名取得
track_name = track.Name
# ファイル場所取得
path = Pathname.new(track.Location)

# 曲名更新
file_name = path.basename(".mp3").to_s
song_name = file_name.gsub(/^\d\d(|\d)\./,"").encode("utf-8").normalize

if /^\d\d(|\d)\./ =~ track_name && file_name == track_name || track_name.encode("utf-8") != song_name
p "Before Name : #{track.Name}"
p "After Name : #{song_name}"
# iTunesの自動補完機能対応
track.Name = "#{song_name}_dummy".upcase
# 曲名を変更
track.Name = song_name
modify_flag = true
p "Name Updated."
end

# トラック番号更新
file_name =~ /^\d\d(|\d)\./
track_number = $&.to_i
tn = track.TrackNumber
if tn == 0 || tn != track_number
# トラック番号を変更
track.TrackNumber = track_number
modify_flag = true
p "TrackNumber Updated."
end

album_name = ""
album_path = nil
if /^[Dd][Ii][Ss][Cc]-\d(|\d)/ =~ path.dirname.basename.to_s
# 複数ディスクの場合
disc_path = path.dirname
album_disc = disc_path.basename.to_s.upcase
album_path = disc_path.dirname
album_name = "#{album_path.basename.to_s.gsub(/^\d\d\./,"")} #{album_disc}".encode("utf-8").normalize
else
# 複数ディスクでない場合
album_path = path.dirname
album_name = album_path.basename.to_s.gsub(/^\d\d\./,"").encode("utf-8").normalize
end

# アルバム更新
album = track.Album
if album == "" || album.encode("utf-8") != album_name
# iTunesの自動補完機能対応
track.Album = "#{album_name}_dummy".upcase
track.Album = album_name
modify_flag = true
p "Album Updated."
end

# グループ更新
circle = track.Grouping
circle_name = album_path.parent.basename.to_s.encode("utf-8").normalize
if circle == "" || circle.encode("utf-8") != circle_name
# iTunesの自動補完機能対応
track.Grouping = "#{circle_name}_dummy".upcase
track.Grouping = circle_name
modify_flag = true
p "Grouping Updated."
end

# 更新した場合は、曲のファイルパスをコンソールに出力
if modify_flag
modify_count += 1
p "#{path.to_s} updated!"
# File.open('updated.log','a'){|f|
# f.write "#{path.to_s}\n"
# }
end
end
end
rescue => e
exception_count += 1
exception_text << "#{track.Location} : #{e}"
end
end
end
p "#{modify_count} updated!"
if exception_count > 0
exception_text.each do |exception|
p exception
end
p "#{exception_count} exceptions."
end
if deleted_tracks > 1
p "#{deleted_tracks} files deleted."
elsif deleted_tracks == 1
p "1 file deleted."
end
p "Processing has been completed!"
rescue NoMethodError => e
p e
p "No playlist!"
rescue WIN32OLERuntimeError => e
p e
p "WIN32OLERuntimeError"
ensure
finish_time = Time.now
p "start time : #{ start_time }"
p "finish time : #{ finish_time }"
p "#{finish_time - start_time} sec."
end

参考URL


Viewing all articles
Browse latest Browse all 107

Trending Articles