Skip to content

Instantly share code, notes, and snippets.

@marcel
Created March 19, 2012 07:24
Show Gist options
  • Save marcel/2100703 to your computer and use it in GitHub Desktop.
Save marcel/2100703 to your computer and use it in GitHub Desktop.
giftube – Generates an animated gif from a YouTube url.
#!/usr/bin/env ruby
# giftube – Generates an animated gif from a YouTube url.
#
# Usage:
#
# giftube [youtube url] [minute:second] [duration]
#
# ex.
#
# giftube 'http://www.youtube.com/watch?v=LBRy4HfDuxc' 0:20 5
# Change these configuration options if you'd like
SCALE = '480:360'
FRAMES_PER_SECOND = '20'
END {
if __FILE__ == $0
USAGE = "giftube [youtube url] [minute:second] [duration]"
abort(USAGE) unless ARGV.size == 3
url, start_time, duration = *ARGV
generator = GifGenerator.generate(
:source_file => VideoDownloader.download(url).download_path,
:start_time => start_time,
:duration => duration
)
puts "Animated gif: #{generator.output_path}"
end
}
require 'uri'
class CommandLineUtility
class << self
def path
new.path
end
end
def initialize
install unless installed?
end
end
class YoutubeDLCommandLineUtility < CommandLineUtility
INSTALL_PATH = "/tmp/youtube-dl"
INSTALL_URL = 'https://raw.github.com/rg3/youtube-dl/2012.02.27/youtube-dl'
def installed?
File.exists?(INSTALL_PATH) || (%x|which youtube-dl| && $?.success?)
end
def path
if File.exists?(INSTALL_PATH)
INSTALL_PATH
else
%x|which youtube-dl|.chomp
end
end
def install
%x|curl '#{INSTALL_URL}' > #{INSTALL_PATH}|
%x|chmod +x #{INSTALL_PATH}|
end
end
class MplayerCommandLineUtility < CommandLineUtility
INSTALL_URL = 'http://mplayerosxext.googlecode.com/files/MPlayer-OSX-Extended_rev14.zip'
DOWNLOAD_PATH = '/tmp/mplayer.zip'
EXECUTABLE = "/tmp/MPlayer OSX Extended.app/Contents/" +
"Resources/Binaries/mpextended.mpBinaries/" +
"Contents/mpextended.mpBinaries/Contents/MacOS/mplayer"
def installed?
File.exists?(EXECUTABLE) || (%x|which mplayer| && $?.success?)
end
def path
if File.exists?(EXECUTABLE)
EXECUTABLE
else
%x|which mplayer|.chomp
end
end
def install
%x|curl '#{INSTALL_URL}' > #{DOWNLOAD_PATH}| unless File.exists?(DOWNLOAD_PATH)
Dir.chdir('/tmp') do
%x|unzip #{DOWNLOAD_PATH}|
end
end
end
class VideoDownloader
DOWNLOAD_PATH = '/tmp'
class << self
def download(url)
downloader = new(url)
downloader.download
downloader
end
end
attr_reader :url
def initialize(url)
@url = URI.parse(url)
ensure_url_is_valid
end
def id
@id ||= query_string['v']
end
def download
system("#{youtube_dl} -o #{download_path} '#{url}'")
end
def youtube_dl
YoutubeDLCommandLineUtility.path
end
def download_path
File.join(DOWNLOAD_PATH, target_file_name)
end
private
def target_file_name
"#{id}.flv"
end
def ensure_url_is_valid
if id.nil?
raise ArgumentError, "YouTube url '#{url}' doesn't include video identifier"
end
end
def query_string
@query_string ||= url.query.split('&').inject({}) do |params, param|
key, value = param.split('=')
params[key] = value
params
end
end
end
class GifGenerator
class << self
def generate(configuration)
generator = new(configuration)
generator.generate
generator
end
end
attr_reader :source_file, :start_time, :duration
def initialize(configuration)
@source_file = configuration[:source_file]
@start_time = configuration[:start_time]
@duration = configuration[:duration]
end
def generate
%x{'#{mplayer}' #{source_file} -nosound -vo gif89a:fps=#{FRAMES_PER_SECOND}:output=#{output_path} -vf scale=#{SCALE} -ss #{start_time} -endpos #{duration}}
end
def mplayer
MplayerCommandLineUtility.path
end
def output_path
File.basename(source_file, '.*') + '.gif'
end
def to_s
output_path
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment