読者です 読者をやめる 読者になる 読者になる

ruby + win32ole で、iTunesのプレイリストを自動生成するプログラムを書いてみました

iTunesがプログラムから操作出来ることを知ったので、久しぶりに ruby + win32ole を使って作ってみました。
実行するとフォルダを自動的に作って、その下にプレイリストを作成するプログラムです。

  • ★ ... レート付きをピックアップ
  • ランダム100 ... ランダムで100曲選ぶ
  • 再生回数が多い100 ... 再生回数が多い順に並べ替えて、上位100曲をピックアップ
  • 最近一ヶ月で追加 ... 最近一ヶ月以内に追加した曲をピックアップ
  • 最近一ヶ月で聞いた ... 再生一ヶ月以内に聞いた曲をピックアップ
  • 未再生 ... 一度も再生していない曲をピックアップ

・・・作ってみると、未再生な曲が400曲もあったりしてびっくり。
写真は再生回数が多い100です。

飽きなければ、アーティストごとやアルバムごとに再生回数を合計して、
多い順にピックアップでもしてみようかと思います。


以下、ソースコードです。

実行する際、お使いのiTunesに'【今I】今日のiTunes'という名前のフォルダがあると上書きしてしまうので注意してください。

#! ruby

require 'win32ole'
require 'parsedate'

class TodaysITunes
  module ITunes
  end

  # コンストラクタ
  def initialize
    message("初期化中です...")
    
    @itunes = WIN32OLE.new("iTunes.application")
    WIN32OLE.const_load(@itunes,ITunes)

    # 不要なジャンルを除外する
    @tracks = []
    @itunes.LibraryPlaylist.Tracks.each do |track|
      @tracks << track if (validTrack(track))
    end

    # 今の時間
    @now = Time::now
  end

  # 全て作成
  def createAll
    createFolder
    createRandom100
    createPlayCount
    createHighRate
    createPlay0
    createRecentAdd
    createPlayedDate
  end

  private

  # 含めるべきトラックか?
  def validTrack(track)
    case track.Genre
    when 'Books & Spoken', 'Podcast', 'Movies'
      return false
    end

    if (track.Kind != 1)        # ITTrackKindFile
      return false
    end

    return true
  end

  # トラック数を得る
  def trackNum()
    @itunes.LibraryPlaylist.Tracks.Count
  end

  # デバッグメッセージ
  def message(msg)
    puts msg
    STDOUT.flush
  end

  # フォルダ作成
  def createFolder
    message("フォルダ作成...")

    folderName = '【今I】今日のiTunes'
    
    # 古いフォルダがあったら削除
    playlist = @itunes.LibrarySource.Playlists.ItemByName(folderName)
    playlist.Delete if (playlist)

    # フォルダ作成
    @folder = @itunes.CreateFolder(folderName)
  end

  # プレイリスト作成
  def createPlayList(name)
    message("'#{name}'を作成中...")
    playlist = @itunes.CreatePlaylist('【今I】' + name)
    playlist.Parent = @folder
    playlist
  end

  # ランダムプレイリストを作成
  def createRandom100
    playlist = createPlayList('ランダム100')

    (1..100).each do
      playlist.AddTrack(@tracks[rand(@tracks.size)])
    end
  end

  # 再生回数を利用したプレイリストを作成
  def createPlayCount
    playlist = createPlayList('再生回数が多い100')

    sorted = @tracks.sort_by do |track|
      track.PlayedCount
    end

    sorted.reverse!

    (1..100).each do |i|
      playlist.AddTrack(sorted[i])
    end
  end

  # レートの高いものを取得
  def createHighRate
    playlist = createPlayList('')

    @tracks.each do |track|
      playlist.AddTrack(track) if (track.Rating > 0)
    end
  end

  # 未再生
  def createPlay0
    playlist = createPlayList('未再生')

    @tracks.each do |track|
      playlist.AddTrack(track) if (track.PlayedCount == 0)
    end
  end

  # 最近一ヶ月で追加
  def createRecentAdd
    playlist = createPlayList('最近一ヶ月で追加')

    @tracks.each do |track|
      dateAdded = Time::local(*ParseDate::parsedate(track.DateAdded)[0..-3])
      playlist.AddTrack(track) if (@now - dateAdded < 60 * 60 * 24 * 30)
    end
  end

  # 最近一ヶ月で聞いた
  def createPlayedDate
    playlist = createPlayList('最近一ヶ月で聞いた')

    @tracks.each do |track|
      if (track.PlayedCount > 0)
        dateAdded = Time::local(*ParseDate::parsedate(track.PlayedDate)[0..-3])
        playlist.AddTrack(track) if (@now - dateAdded < 60 * 60 * 24 * 30)
      end
    end
  end

  # ipodの更新
  def update_iPod
    ipod = @itunes.Sources.Item(2)
    ipod.UpdateIPod
  end
end

obj = TodaysITunes.new
obj.createAll