ruby script for my phone to help me crop and trim video
#!/usr/bin/env ruby
INPUTDIR = "./storage/dcim/OpenCamera"
OUTPUTDIR = "./storage/movies"
# clear the screen
puts `clear`
# do the needed dirs exists?
raise "input directory must exist" unless Dir.exist? INPUTDIR
raise "output directory must exist" unless Dir.exist? OUTPUTDIR
# has a file been passed in?
targetVid = File.expand_path(ARGV[0]) if ARGV[0]
# start building the final command as an array
cmdArray = ["ffmpeg -y -noautorotate"]
# get latest video path as a string unless the target vid exists
unless targetVid
vids = Dir.glob("VID*", base: INPUTDIR)
maxTime = nil
newestFile = nil
vids.each do |f|
target = File.join(INPUTDIR, f)
modTime = File.mtime(target)
if maxTime.nil? or modTime > maxTime
newestFile = target
maxTime = modTime
end
end
puts newestFile
targetVid = newestFile
end
input = targetVid.chomp()
# get the width and height and rotation
dataString = `ffprobe -show_streams #{input} 2>&1`
# get the width and height
matches = /^width=([0-9]*)/.match(dataString)
if matches
vidWidth =matches[1].to_i
else
errorMessage "width not found"
end
matches = /^height=([0-9]*)/.match(dataString)
if matches
vidHeight =matches[1].to_i
else
errorMessage "error height not found"
end
matches = /^rotation=([-0-9]*)/.match(dataString)
if matches
vidRotation =matches[1].to_i
else
# no rotation detected
vidRotation=0
end
puts "width: #{vidWidth}"
puts "height: #{vidHeight}"
puts "rotation: #{vidRotation}"
# add the input to the cmd array
cmdArray << "-i #{input}"
# make the video pinner?
puts "scale to 480px? (y/N)"
i = STDIN.gets.strip()
if i=='y'
videoScale = 480
vBrate = 800
aBrate = 64
frameRate = 15
else
videoScale = 600
vBrate = 1500
aBrate = 96
frameRate = 24
end
# set the rates
cmdArray << "-b:a #{aBrate}k -b:v #{vBrate}k -r #{frameRate}"
# get some info about the video
durString =`ffmpeg -i #{input} 2>&1 | grep Duration:`
# duration is "Duration: (HH:MM:SS), ..."
matches = /.*Duration: ([0-9:\.]*),/.match(durString)
if matches
INPUT_DURATION = matches[1]
else
errorMessage "Duration not detected"
end
# set the scaling for the video filter
if vidRotation == -90
scale = "#{videoScale}:-2"
else
scale = "-2:#{videoScale}"
end
# begin building the video filter
videoFilter="-filter:v scale=#{scale}:force_original_aspect_ratio=decrease"
# split the string to get the vid name
pathParts = input.split("/")
# the last part is the filename
fName = pathParts[-1]
puts "Resizing #{fName}"
# define output file
output = OUTPUTDIR+"/"+fName
puts "Crop? (y/N)"
i = STDIN.gets.downcase.strip()
if i == "y"
# begin building the crop string
cropString =",crop=#{videoScale}:#{videoScale}"
puts "crop from:\n a : top\n b : center\n c : bottom"
x = STDIN.gets.strip()
crop = case x
when 'a'
cropString+=":0:0"
when 'b'
#center crop?
when 'c'
cropString+=":iw-#{videoScale}:ih-#{videoScale}"
end
# add the crop to the video filter
videoFilter+=cropString
end
# add the video filter
cmdArray << videoFilter
# trim...
puts "Trim? (y/N)"
i = STDIN.gets.downcase.strip()
if i == 'y'
# get the trim start
puts "trim start time in MM:SS format. Leave blank to trim from start of video"
trimStart = STDIN.gets.strip()
trimStart = "00:00" if trimStart.empty?
cmdArray << "-ss #{trimStart}"
# get the trim end
puts "trim end time in MM:SS format. Leave blank to trim to end of video"
trimEnd = STDIN.gets.strip()
trimEnd = INPUT_DURATION if trimEnd.empty?
cmdArray << "-to #{trimEnd}"
end
# append the output
cmdArray << "#{output}"
# what is the actual command?
cmd = cmdArray.join(" ")
puts "Run #{cmd}? (Y/n)"
i=STDIN.gets.strip
puts `#{cmd}` unless i=='Y'