Created
April 6, 2015 20:01
-
-
Save Konstantinusz/0a436f57de5236265f9e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/ruby | |
require "optparse" | |
require "time" | |
require "tmpdir" | |
abr=96 | |
size=495 | |
input_file="" | |
output_file="" | |
gamma =1.0 | |
colour_sat=1.0 | |
preset="veryslow" | |
resize_width=640 | |
OptionParser.new do |opts| | |
# Default banner is "Usage: #{opts.program_name} [options]". | |
# Argument must match a regular expression. | |
opts.on("-s", "--size SIZE",/[0-9]+/ ,"video size with audio in megabytes (1024*1024)") {|arg| size = arg.to_i} | |
opts.on("-a", "--audio-bitrate ABR",/[0-9]+/, "audio bitrate in kbps") {|arg| abr = arg.to_i} | |
opts.on("-i", "--input INPUT_VIDEO_FILENAME",/.+/i,"video filename to process") {|arg| input_file = arg} | |
opts.on("-o", "--output OUTPUT_VIDEO_FILENAME",/.+/i,"video filename to write output") {|arg| output_file = arg} | |
opts.on("-g", "--gamma GAMMA",/[0-9]+(?:\.[0-9]+)?/,"gamma to apply") {|arg| gamma = arg} | |
opts.on("-c", "--colour-saturation SAT",/[0-9]+(?:\.[0-9]+)?/,"colour saturation to apply") {|arg| colour_sat = arg} | |
opts.on("-p", "--encoding-preset PRESET",["fast","medium","slow","veryslow"],"AVC encoding preset") {|arg| preset = arg} | |
opts.on("-r", "--resize-width WIDTH",/[0-9]+/,"resize width to new WIDTH") {|arg| resize_width = arg.to_i} | |
opts.on_tail("-h", "--help", "Show this message") do | |
STDERR.puts opts | |
exit | |
end | |
begin | |
# Parse and remove options from ARGV. | |
opts.parse! | |
rescue OptionParser::ParseError => error | |
# Without this rescue, Ruby would print the stack trace | |
# of the error. Instead, we want to show the error message, | |
# suggest -h or --help, and exit 1. | |
$stderr.puts error | |
$stderr.puts "(-h or --help will show valid options)" | |
exit 1 | |
end | |
end | |
script_path=File.dirname(__FILE__) | |
working_dir=Dir.mktmpdir | |
system "ln -s #{script_path}/ffms2.dll #{working_dir}/ffms2.dll" | |
system "ln -s #{script_path}/MaskTools.dll #{working_dir}/MaskTools.dll" | |
system "ln -s #{script_path}/ylevels.avsi #{working_dir}/ylevels.avsi" | |
system "ln -s \"#{File.expand_path(input_file)}\" \"#{working_dir}/#{input_file}\"" | |
ret=%x{ffmpeg -i \"#{input_file}\" 2>&1} | |
d=Time.parse(ret.scan(/Duration\:(.*?)\,/).flatten[0]) | |
width_height=ret.scan(/,\s*([0-9]+)x([0-9]+)/).flatten.map{|z| z.to_i} | |
width=width_height[0] | |
height=width_height[1] | |
ar=width.fdiv height | |
a=(resize_width.fdiv ar).round | |
resize_height=(a % 4)<=1 ? a - (a % 4) : a + 4 - (a % 4) | |
duration_in_sec=3600*d.hour+60*d.min+d.sec | |
target_bytes = size * 1024 * 1024 | |
audio_bytes = ((abr * 1000) / 8) * duration_in_sec | |
bitrate=(((target_bytes - audio_bytes) / duration_in_sec * 8).fdiv 1000).round | |
avs_content=<<END | |
loadplugin("ffms2.dll") | |
loadplugin("MaskTools.dll") | |
import("ylevels.avsi") | |
ffvideosource("#{input_file}") | |
lanczos4resize(#{resize_width},#{resize_height}) | |
ylevels(gamma=#{gamma}) | |
tweak(0,#{colour_sat},0,1) | |
END | |
input_file_avs="#{input_file}.avs" | |
File.write("#{working_dir}/#{input_file_avs}",avs_content) | |
pass_1_preset=preset | |
pass_1_bit_rate=bitrate | |
pass_2_preset=preset | |
pass_2_bit_rate=bitrate | |
command=%Q{wine #{script_path}/avs2yuv.exe \"#{working_dir}/#{input_file_avs}\" - | ffmpeg -y -f yuv4mpegpipe -i - -an -pass 1 -vcodec libx264 -preset #{pass_1_preset} -pass 1 -b:v #{pass_1_bit_rate}k -movflags +faststart -threads 0 -wpredp 2 -f mp4 pass1.mp4 && wine "#{script_path}/avs2yuv.exe" "#{working_dir}/#{input_file_avs}" - | ffmpeg -y -f yuv4mpegpipe -i - -i #{input_file} -map 0:v -map 1:a -c:v libx264 -preset #{pass_2_preset} -b:v #{pass_2_bit_rate}k -ac 2 -c:a libvorbis -b:a #{abr.to_s}k -strict -2 -pass 2 -movflags +faststart -threads 0 -wpredp 2 -y \"#{output_file}\"} | |
puts command | |
binding.local_variables.each{|z| puts "#{z} -> #{temp=eval(z.to_s).to_s.gsub("\n","\\n");temp.size>70 ? temp[0..69]+"..." : temp}"} | |
system command | |
FileUtils.remove_entry_secure working_dir |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment