Export iTunes playlist songs to an external location (SD Card)
The majority of the time I use my iPhone to play music in my car via USB or Bluetooth. Recently I decided to utilize the SD card slot as well and fill one with MP3s. I soon realized iTunes does not have an easy way of exporting music to an SD card, so I wrote a simple Ruby script to do so.
I created a smart playlist based on my genres and ratings called “Jeep”. I then exported this playlist as plain text via:
File > Library > Export Playlist...
- Save as: Jeep.txt
- Format: Plain Text
I created a Yaml configuration file (config.yml):
---
playlist_path: ./Jeep.txt
export_path: /Volumes/ERLJEPMUSIC
output_parts:
- Artist
- Album
- Track Number
- Name
output_delimiter: " - "
I created the following Ruby script to load the config.yml file, parse the exported playlist as plain text, create an export path for each file, and then copy the files to the destination.
#!/usr/bin/env ruby
require 'set'
require 'yaml'
class ItunesFileExporter
def initialize
@songs = Set.new
@headers = nil
load_config
playlist_to_hash
end
def run
copy_files
end
private
def load_config(config_path = './config.yml')
@config = YAML.load_file(config_path)
end
def playlist_to_hash
File.readlines(@config['playlist_path'], "\r").each do |line|
cols = line.strip.split("\t")
if @headers.nil?
@headers = cols
else
@songs << song_data(cols)
end
end
end
def song_data(cols)
hsh = Hash[@headers.zip(cols)]
file_extension = hsh['Location'].split(/\./).last
hsh['Location'] = hsh['Location'].tr(':', '/').gsub(/^Macintosh HD/, '')
file_parts_joined = @config['output_parts']
.each_with_object([]) { |part, arr| arr << hsh[part] }
.join(@config['output_delimiter'])
.tr('/', '_')
hsh['_output_path'] = "#{@config['export_path']}/#{file_parts_joined}.#{file_extension}"
hsh
end
def copy_files
@songs.each do |song|
puts "Copying: #{song['_output_path']}"
if File.exist?(song['_output_path'])
puts 'File already exists.'
next
end
FileUtils.cp(song['Location'], song['_output_path'])
end
end
end
ItunesFileExporter.new.run