|
#!/usr/bin/env ruby -rubygems |
|
# |
|
# Author: Riyad Preukschas <riyad@informatik.uni-bremen.de> |
|
# License: Mozilla Public License 2.0 |
|
# |
|
# Transcode any file VLC can play to mp3. |
|
|
|
require 'optparse' |
|
require 'mkmf' |
|
require 'shellwords' |
|
|
|
|
|
# |
|
# helpers |
|
# |
|
|
|
def puts_error(message) |
|
puts "Error: #{message}" |
|
end |
|
|
|
def puts_warning(message) |
|
puts "Warning: #{message}" |
|
end |
|
|
|
|
|
# |
|
# parse options |
|
# |
|
|
|
options = { |
|
:bit_rate => 192, |
|
:sampling_rate => 44100, |
|
} |
|
begin |
|
OptionParser.new do |opts| |
|
opts.banner = "Usage: convert2mp3 [options] FILE [<FILE ...>]" |
|
|
|
opts.separator "" |
|
opts.separator "Conversion Options:" |
|
|
|
opts.on("-f", "--[no-]force", "Overwrite mp3 file if it exists already") do |f| |
|
options[:force_overwrite] = f |
|
end |
|
opts.on("-o", "--output-directoy [DIRECTORY]", "Save converted files to this directory") do |out_dir| |
|
unless File.directory?(out_dir) |
|
puts_error %Q(Wrong output directory. "#{out_dir}" is not a directory.) |
|
exit 1 |
|
end |
|
options[:output_dir] = out_dir |
|
end |
|
|
|
opts.separator "" |
|
opts.separator "mp3 Options:" |
|
|
|
opts.on("-b", "--bit-rate [RATE]", Integer, "Bit rate in kbit/s (default: #{options[:bit_rate]})") do |b| |
|
options[:bit_rate] = b |
|
end |
|
opts.on("-s", "--sampling-rate [RATE]", Integer, "Sampling rate in Hz (default: #{options[:sampling_rate]})") do |s| |
|
options[:sampling_rate] = s |
|
end |
|
|
|
opts.separator "" |
|
opts.separator "General Options:" |
|
|
|
opts.on_tail("-h", "--help", "Show this message") do |
|
puts opts |
|
exit 0 |
|
end |
|
opts.on_tail("-v", "--[no-]verbose", "Be more verbose") do |v| |
|
options[:verbose] = v |
|
end |
|
end.parse! |
|
rescue OptionParser::InvalidOption => e |
|
puts_error e.message |
|
exit 1 |
|
end |
|
|
|
|
|
# |
|
# gather source files |
|
# |
|
|
|
if ARGV.empty? |
|
puts_error "No files given." |
|
exit 1 |
|
end |
|
source_files = [] |
|
while !ARGV.empty? |
|
source_path = ARGV.shift |
|
unless File.exists?(source_path) |
|
puts_warning %Q(Skipping "#{source_path}". It doesn't exist.) |
|
next |
|
end |
|
unless File.file?(source_path) |
|
puts_warning %Q(Skipping "#{source_path}". It's not a file.) |
|
next |
|
end |
|
source_files << source_path |
|
end |
|
|
|
|
|
# |
|
# VLC command line options |
|
# |
|
|
|
# using find_executable() will create a mkmf.log file :( |
|
vlc_paths = [ |
|
'vlc', |
|
'/Applications/VLC.app/Contents/MacOS/VLC', |
|
File.expand_path('~/Applications/VLC.app/Contents/MacOS/VLC'), |
|
] |
|
VLC = vlc_paths.find { |path| find_executable0(path) } |
|
INTERFACE = '-I dummy' |
|
PLAYBACK = '--no-loop --no-repeat --play-and-exit' |
|
TRANSCODING = '--sout="#transcode{vcodec=dummy,acodec=mp3,ab=BIT_RATE,channels=2,samplerate=SAMPLING_RATE}:standard{access=file,mux=raw,dst=\'DESTINATION\'}"'. |
|
gsub('BIT_RATE', options[:bit_rate].to_s). |
|
gsub('SAMPLING_RATE', options[:sampling_rate].to_s) |
|
VERBOSITY = options[:verbose] ? '' : '-q 2>/dev/null 1>/dev/null' |
|
|
|
if VLC.nil? |
|
puts_error "Couldn't find VLC." |
|
exit 1 |
|
end |
|
|
|
source_files.each do |source_file| |
|
source_dir = File.dirname(source_file) |
|
output_dir = options[:output_dir] || source_dir |
|
output_file = File.join(output_dir, "#{File.basename(source_file, ".*")}.mp3") |
|
if File.exist?(output_file) |
|
if options[:force_overwrite] |
|
puts_warning %Q(Output file exists. "#{output_file}" will be overwritten.) if options[:verbose] |
|
else |
|
puts_warning %Q(Output file exists already. Skipping "#{output_file}".) |
|
next |
|
end |
|
end |
|
|
|
puts %Q(Converting "#{source_file}") |
|
|
|
unless system("#{VLC} #{PLAYBACK} #{INTERFACE} #{TRANSCODING.gsub('DESTINATION', output_file.gsub(/'/, ""))} #{source_file.shellescape} #{VERBOSITY}") |
|
puts_error "Conversion failed. Try using the -v option for more detailed output." |
|
end |
|
puts if options[:verbose] |
|
end |