Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@mrrooijen
Created February 11, 2010 01:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrrooijen/301111 to your computer and use it in GitHub Desktop.
Save mrrooijen/301111 to your computer and use it in GitHub Desktop.
A simple class that enables you to directly download a video from YouTube by simply providing the full YouTube URL.
require 'rubygems'
require 'json'
require 'open-uri'
require 'progressbar'
# YouTube
# This class allows you to directly download videos straight from YouTube
# All you have to do is provide the full URL to a video on YouTube.com
# See the examples below!
class YouTube
BASE_URI = "http://www.youtube.com/"
def self.read_video_from(url, &block)
download_video(parse_video_url(url), &block)
end
def self.read_video_from_and_download_to(url, path = Dir.pwd)
full_path = File.expand_path(File.join(path, parse_video_title(url) + '.flv'))
read_video_from(url) do |youtube|
File.open(full_path, "w") do |video|
video.write(youtube.read)
end
end
end
def self.parse_video_title(url)
open(url) do |file|
file.each_line do |line|
return $1 if line =~ /<h1 >(.*)<\/h1>/
end
end
false
end
private
def self.parse_video_url(url)
url =~ /watch\?v=(.*)/
video_id = $1.split("&")[0]
video_url = nil
open("#{BASE_URI}watch\?v=#{video_id}") do |page|
page.each_line do |line|
if line =~ /.SWF_ARGS.:(.*),\n$/
params = JSON.parse($1)
video_url = "#{BASE_URI}get_video?video_id=#{params['video_id']}&t=#{params['t']}"
break
end
end
end
video_url || could_not_locate_video_file
end
def self.could_not_locate_video_file
puts "Could not locate video file for the given URL!"
exit
end
def self.download_video(url, &block)
puts "Downloading Video From YouTube..."
progress_bar = nil
open(url, :proxy => nil, :content_length_proc => lambda { |length|
if length && 0 < length
progress_bar = ProgressBar.new(url, length)
end
},
:progress_proc => lambda { |progress|
progress_bar.set(progress) if progress_bar
}, &block)
puts ""
puts "Finished downloading video!"
end
end
## EXAMPLES
## URL
# All you need is "a very awesome video"
url = 'http://www.youtube.com/watch?v=oHg5SJYRHA0'
## METHOD 1
# Then you can simply invoke the following "One Line Command" to download
# and directly save the video to the filesystem
YouTube::read_video_from_and_download_to(url, 'youtube')
## METHOD 2
# If you wish to do something else before writing the YouTube video you can
# also use the following method to read from YouTube and then later store it on the filesystem
# To manually fetch the "video title" from YouTube, use: YouTube::parse_video_title(url)
# be sure to append the ".flv" extension to it, as it of course isn't stored in the YouTube video title
YouTube::read_video_from(url) do |youtube|
File.open("/Users/Michael/Desktop/#{YouTube::parse_video_title(url)}.flv", "w") do |video|
video.write(youtube.read)
end
end
## METHOD 3
# Basically like method 2, except that we're not using the YouTube::parse_video_title(url) method here
# which means you have 100% control over what the output file must be called.
YouTube::read_video_from(url) do |youtube|
File.open("/Users/Michael/Desktop/my_video.flv", "w") do |video|
video.write(youtube.read)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment