Skip to content

Instantly share code, notes, and snippets.

@drhuffman12
Last active August 29, 2015 14:08
Show Gist options
  • Save drhuffman12/f262fb7846d3ed18e930 to your computer and use it in GitHub Desktop.
Save drhuffman12/f262fb7846d3ed18e930 to your computer and use it in GitHub Desktop.
Convert and split an audio/video file into 5 minute intervals of the specified target format and compression quality.
#!/usr/bin/ruby
# FILENAME: av_splitter.rb
#
# DESCRIPTION: Convert and split an audio/video file into 5 minute intervals of the specified target format and compression quality.
#
# USAGE:
# Put your audio/video files into the "in" sub-folder, then run the 'audio_splitter.rb' ruby script w/syntax:
# ruby -s audio_splitter.rb <format_out> '<bit_rate_info>' <debug_level>
#
# e.g.:
# ruby -s audio_splitter.rb aac '-ab 160k' 1 > audio_splitter.aac.160k.log
# ruby -s audio_splitter.rb aac '-ab 80k' 5 > audio_splitter.aac.80k.log
# ruby -s audio_splitter.rb ogg '-ab 160k' 1 > audio_splitter.ogg.160k.log
# ruby -s audio_splitter.rb mp3 '-ab 80k' 5 > audio_splitter.mp3.80k.log
# ruby -s audio_splitter.rb mp3 '-ab 80k' 5 61 > audio_splitter.mp3.80k.log # 61 second intervals.. just to be odd
# ruby -s audio_splitter.rb > audio_splitter.log
#
# DEPENDANCIES:
# * apps: ffmpeg (to be replaced by avconv eventually), ruby/jruby
# * gems: active_support, fileutils
require 'active_support'
require 'fileutils'
@debug_level = 0
# my_logger lvl msg
def my_logger(lvl,msg='')
puts msg.to_s if (@debug_level >= lvl.to_i)
end
def file_out_from(file_in)
file_ext=File.extname(file_in)
file_base=File.basename(file_in,file_ext)
file_base.split(/[^a-zA-Z0-9]/).collect {|f| f.downcase.capitalize}.join('')
end
def convert_and_split(folder_in,folder_out,file_in,file_out,format_out,dur_clip,bit_rate_info)
my_logger 1
my_logger 1, "="*160
my_logger 3
my_logger 2, "folder_in: [#{folder_in}]"
my_logger 1, "folder_out: [#{folder_out}]"
my_logger 2, "file_in: [#{file_in}]"
my_logger 1, "file_out: [#{file_out}]"
my_logger 2, "format_out: [#{format_out}]"
my_logger 2, "dur_clip: [#{dur_clip}]"
my_logger 3
cmd_str="ffmpeg -i \"#{folder_in}/#{file_in}\" 2>&1 | grep \"Duration\"| cut -d ' ' -f 4 | sed s/,// | sed 's@\\..*@@g' | awk '{ split($1, A, \":\"); split(A[3], B, \".\"); print 3600*A[1] + 60*A[2] + B[1] }'"
my_logger 3, cmd_str
my_logger 3, "cmd_str: [#{cmd_str}]"
dur_all=(`#{cmd_str}`).to_i
my_logger 3
my_logger 3, "dur_all: #{dur_all}"
my_logger 3
i=0
aac_exp_flag=(['aac'].include?(format_out)) ? '-strict experimental' : ''
my_logger 3, "aac_exp_flag: #{aac_exp_flag}"
(0..dur_all).step(dur_clip.to_i) do |start_pos|
i+=1
my_logger 3, "start_pos: [#{start_pos}]"
# cmd_str = "avconv -y #{aac_exp_flag} -i \"#{folder_in}/#{file_in}\" -ss #{start_pos} -t #{dur_clip} #{bit_rate_info} \"#{folder_out}/#{file_out}.#{i}.#{format_out}\""
cmd_str = "ffmpeg -y -i \"#{folder_in}/#{file_in}\" -ss #{start_pos} -t #{dur_clip} #{bit_rate_info} \"#{folder_out}/#{file_out}.#{i.to_s.rjust(3, '0')}.#{format_out}\""
my_logger 3
my_logger 3, "cmd_str: [#{cmd_str}]"
my_logger 3
`#{cmd_str}`
end
my_logger 1
end
def run(folder_in,folder_out,format_out,dur_clip,bit_rate_info)
bit_rate_folder=bit_rate_info.gsub(/[^a-zA-Z0-9.]/,'')
folder_out_formatted="out/#{format_out}/#{bit_rate_folder}"
FileUtils::mkdir_p(folder_out_formatted) unless File.directory?(folder_out_formatted)
(Dir.entries('in')-['.','..']).each do |file_in|
file_out=file_out_from(file_in)
convert_and_split(folder_in,folder_out_formatted,file_in,file_out,format_out,dur_clip,bit_rate_info)
end
end
format_out = (ARGV[0] || 'aac') # 'oog' # 'aac'
bit_rate_info = ARGV[1] || '-ab 160k' # '-aq 5' # '-ab 160k'
@debug_level = ARGV[2].to_i
@debug_level = (@debug_level < 0 ? 0 : @debug_level)
folder_in = 'in'
folder_out = 'out'
# dur_clip=300 # aka 5 mins * 60 seconds
dur_clip = ARGV[3].to_i
dur_clip = (dur_clip < 60 ? 60 : dur_clip) # i.e.: minimum of 60 seconds
run(folder_in,folder_out,format_out,dur_clip,bit_rate_info)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment