Automatisch Lieder-Erkennen

Ich digitalisiere gerade meine Kassettensammlung. Da hilft es, sich das aufwändige Titeleingeben zu automatisieren.

Voila: mein Lieder-Erkenn-Skript (basierend auf songrec)

Setup: Install gem „zaru“ first!

require 'zaru'

TIMEOUT = 12 #seconds

semaphore = Mutex.new
rename_jobs = []
threads = []

# setup parallel threads to recognize songs - only for not renamed files
files = Dir["**/*"].select{|e|[".flac",".opus",".wav",".ogg",".mp3",".aac"].include?(File.extname(e).downcase)} # only audio files
files.each_with_index do |f, i|  
  rename_jobs << []
  threads << Thread.new do
    new_name = File.dirname(f)+"/"
    new_name = File.join(File.dirname(f), $1) if f =~ /^([abcd]?\d+)/i
    new_name = File.join(File.dirname(f), $1) if f =~ /^(track\s*\d+)/i
    name = `songrec recognize \"#{f}\"`.strip
    new_name += " - #{Zaru.sanitize!(name)}#{File.extname(f)}"
    semaphore.synchronize { rename_jobs[i] = [f, new_name] }
  end
end

# wait smart and timeout when number of recognized songs doesn't go up
old_num = 0
timeout = 0
while(true) do
  break unless rename_jobs.include?([])
  break if timeout > TIMEOUT
  sleep 1
  num_recog = rename_jobs.select{|e|e!=[]}.size
  if num_recog != old_num
    timeout = 0
    old_num = num_recog
  else
    timeout += 1
  end
  puts "#{num_recog} of #{rename_jobs.size} songs recognized yet."
end
threads.each{|t|t.exit unless t.status} # end remaining searches

puts "Preview:"
rename_jobs.sort.each {|e| p e}
puts "\nEnter y to continue"
s = gets.strip

if s == 'y'
  # finally do the renaming
  c = 0
  rename_jobs.each do |r|
    if r != []
      File.rename(r[0], r[1])
      c += 1
    end
  end

  puts "#{c} files renamed."
end