Skip to content

Instantly share code, notes, and snippets.

@brettchalupa
Last active February 4, 2022 18:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brettchalupa/edb5d954da3279fe17052981c21930b4 to your computer and use it in GitHub Desktop.
Save brettchalupa/edb5d954da3279fe17052981c21930b4 to your computer and use it in GitHub Desktop.
Organize MP3s Ruby Script
# Organize MP3s by Brett Chalupa
#
# Pre-reqs:
# 1. Ruby v2+
# 2. gem install id3tag
#
# This script loops through a directory of mp3 files, like a an archive
# download from YouTube Music, and organizes them into the following structure
# in the folder:
#
# ARTIST/ALBUM/00 - TITLE.mp3
#
# Use https://musicbrainz.org to fetch metadata en masse for files if it's
# lacking in your archive.
#
# Run the script in the directory of your mp3s with:
#
# ruby _organize_mp3s.rb
#
# If two files have the same name and MP3 metadata for artist, album, and track,
# they'll get overwritten, thus cleaning up duplicates.
#
# Problematic file and directory chars are also stripped out.
#
require "id3tag"
require "fileutils"
Dir.each_child(".") do |child|
next if File.directory?(child)
next unless child =~ /.+(.mp3)$/i
begin
file = File.open(child, 'rb')
tag = ID3Tag.read(file)
if tag.artist.nil? || tag.album.nil? || tag.title.nil?
puts "Skipping #{child}, missing metadata"
next
end
def char_scrub(str)
str.gsub(/\!|\(|\)|\'|\//,'_')
end
dir = "#{char_scrub(tag.artist)}/#{char_scrub(tag.album)}"
FileUtils.mkdir_p(dir)
name = ""
if tag.track_nr
name += "#{tag.track_nr.split("/").first.rjust(2, "0")} - "
end
name = "#{name}#{tag.title}.mp3"
FileUtils.mv(child, "#{dir}/#{char_scrub(name)}")
rescue => e
puts "🚨 rescued error"
puts e
next
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment