Skip to content

Instantly share code, notes, and snippets.

@ubermajestix
Created April 17, 2013 19:57
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ubermajestix/5407257 to your computer and use it in GitHub Desktop.
Save ubermajestix/5407257 to your computer and use it in GitHub Desktop.
#! /usr/bin/env ruby
require 'rubygems'
require 'main'
require 'pathname'
require 'fileutils'
Main{
argument("youtube_url")
option("start-time",'s') do
argument_required
end
option("duration", "d") do
argument_required
end
option("blur")
def blur?
!!params['blur'].given?
end
option("stills")
def stills?
!!params['stills'].given?
end
option("force")
def force?
!!params['force'].given?
end
mode 'cleanup' do
def run
if force?
FileUtils.rm_rf("/tmp/giftube/**")
else
@youtube_url = params["youtube_url"].value
@youtube_id = @youtube_url.split("?").last.split("&").map{|d|d.split("=")}.detect{|d| d.first =="v"}.last
@working_dir = Pathname.new("/tmp/giftube/#{@youtube_id}")
FileUtils.rm_rf(@working_dir)
end
end
end
def run
parse_params
setup_dirs
download_video
setup_command
# Run it!
puts @cmd
system(@cmd)
puts "Check out your spiffy new gif: #{@gif_filename}"
end
def parse_params
@youtube_url = params["youtube_url"].value
@youtube_id = @youtube_url.split("?").last.split("&").map{|d|d.split("=")}.detect{|d| d.first =="v"}.last
@working_dir = Pathname.new("/tmp/giftube/#{@youtube_id}")
@stills_dir = Pathname.new("/tmp/giftube/#{@youtube_id}/stills")
@start_time = params['start-time'].value || "00:00:00.000"
format_start_time
@duration = params['duration'].value || "00:00:05.000"
@youtube_file = Pathname.new("#{@working_dir}/#{@youtube_id}.flv")
@gif_filename = "#{@youtube_id}-#{Time.now.to_i}.gif"
end
private
def setup_dirs
FileUtils.mkdir_p(@stills_dir)
end
def download_video
return if @youtube_file.exist?
system("youtube-dl #{@youtube_url} --max-quality flv -o #{@youtube_file}")
end
def setup_command
# Setup commands
remove_files = "rm -rf #{File.join(@stills_dir, "output*")}"
convert_video_to_stills = "ffmpeg -ss #{@start_time} -i #{@youtube_file} -r 10 -t #{@duration} -s 320x240 #{File.join(@stills_dir,"output%03d.jpeg")}"
giferize = "convert -delay 10 -loop 0 -layers OptimizeTransparency -colors 48 `ls #{File.join(@stills_dir,"*.jpeg")}` #{@gif_filename}"
# Build final command
if force?
cmd = [remove_files, convert_video_to_stills]
else
cmd = Dir.glob(File.join(@stills_dir, "output*")).empty? ? [convert_video_to_stills] : []
end
blur.each{|blur_cmd| cmd << blur_cmd } if blur?
cmd << giferize
cmd << "open #{@stills_dir}" if stills?
@cmd = cmd.join(" && ")
end
def blur
last_file = Dir.glob(File.join(@stills_dir,"*.jpeg")).last
new_last_blurry_file = File.basename(last_file).gsub(File.extname(last_file), "-1.jpeg")
blur_first_image = "touch #{new_last_blurry_file} && convert `ls #{File.join(@stills_dir,"*.jpeg")} | head -1` -channel RGBA -blur 0x2 `ls #{new_last_blurry_file} | head -1`"
blur_last_image = "convert `ls #{File.join(@stills_dir,"*.jpeg")} | tail -1` -channel RGBA -blur 0x2 `ls #{File.join(@stills_dir, "*.jpeg")} | tail -1`"
[blur_last_image, blur_first_image]
end
def format_start_time
if @start_time.to_s.match(/^\d+$/) # assume its in seconds
minutes, seconds = @start_time.to_i.divmod(60)
hours, minutes = minutes.divmod(60)
time = [hours, minutes, seconds]
time.map!{|part| part.to_s.size == 1 ? ("0%d"%part) : part.to_s }
@start_time = time.join(":") << ".000"
end
end
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment