youtube-downloader 1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +60 -0
- data/bin/youtube-downloader +97 -0
- data/etc/youtube-downloader.conf +10 -0
- data/lib/youtube-downloader/youtube.rb +55 -0
- data/youtube-downloader.gemspec +19 -0
- metadata +79 -0
data/README
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
Using some, for unix based systems, common tools to download movies
|
2
|
+
and optionally ripping the audio from them.
|
3
|
+
|
4
|
+
USAGE:
|
5
|
+
youtube-downloader <youtube-url> [command]
|
6
|
+
|
7
|
+
COMMANDS:
|
8
|
+
- audio
|
9
|
+
Downloads the video to a fifo-pipe, rips the audio and removes the video.
|
10
|
+
If the file has already been downloaded the audio will be ripped but the
|
11
|
+
file will be not be removed.
|
12
|
+
- rip or all
|
13
|
+
Downloads the video and rips the audio
|
14
|
+
|
15
|
+
With no command set it will download the video.
|
16
|
+
|
17
|
+
EDITING FILENAME:
|
18
|
+
This script is set to use the Ruby Readline library, I've not found a way to
|
19
|
+
add a default value to the line to be read in.
|
20
|
+
|
21
|
+
But I've added the default title toe Readline history buffer so press the
|
22
|
+
up arrow key on your keyboard to get it filled in so you can change it.
|
23
|
+
|
24
|
+
DEPENDENCIES:
|
25
|
+
- cURL, fetch or wget. We try to be smart and choose a good one
|
26
|
+
depending on the running system so this shouldn't be to big a deal.
|
27
|
+
- ffmpeg, for ripping the audio
|
28
|
+
- hpricot gem, if you install through rubygems it will be installed automatically
|
29
|
+
- htmlentities gem
|
30
|
+
|
31
|
+
INSTALLATION:
|
32
|
+
Make sure you can download gems from gemcutter.org and then
|
33
|
+
And then:
|
34
|
+
# gem install youtube-downloader
|
35
|
+
|
36
|
+
CONFIGURATION:
|
37
|
+
In your home directory create a file named .youtube-downloader
|
38
|
+
with these values:
|
39
|
+
|
40
|
+
---
|
41
|
+
# To download the files to the current directory set to .
|
42
|
+
:download_dir: .
|
43
|
+
:music_dir: .
|
44
|
+
:temp_dir: /tmp
|
45
|
+
:file_extension: flv
|
46
|
+
|
47
|
+
# If we want the timestamp on the files to be time of download instead
|
48
|
+
# of time of the file
|
49
|
+
:touch: true
|
50
|
+
|
51
|
+
CHANGES
|
52
|
+
1.1
|
53
|
+
* Switched over to using hpricot for finding the parts of the document were
|
54
|
+
the data I need to download the video are
|
55
|
+
* Added the HTML Entities library to uncode the various HTML parts in
|
56
|
+
the title of the video
|
57
|
+
|
58
|
+
TODO
|
59
|
+
2.0
|
60
|
+
* Add support for downloading different qualities of a video. 360p, 720p, 1080p etc
|
@@ -0,0 +1,97 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$KCODE='u'
|
3
|
+
|
4
|
+
require 'open-uri'
|
5
|
+
require 'ftools'
|
6
|
+
require 'yaml'
|
7
|
+
require 'readline'
|
8
|
+
require 'shellwords'
|
9
|
+
|
10
|
+
require 'youtube-downloader/youtube'
|
11
|
+
|
12
|
+
begin
|
13
|
+
ConfigYT = YAML::load_file(File.join(ENV['HOME'], '.youtube-downloader'))
|
14
|
+
rescue Errno::ENOENT
|
15
|
+
STDERR.puts "No configuration file found, please copy one."
|
16
|
+
STDERR.puts " cp #{File.dirname(__FILE__)}/../etc/youtube-downloader.conf ~/.youtube-downloader"
|
17
|
+
exit 1
|
18
|
+
end
|
19
|
+
|
20
|
+
if ARGV.empty? or ARGV[0].match(/\A(-h)|((--)?help)\Z/i)
|
21
|
+
puts "Usage: #{$0.split(/\//)[-1]} <youtube url> [command]"
|
22
|
+
puts "Where command is one of the following:"
|
23
|
+
puts "\t audio - download video, rip audio, remove movie"
|
24
|
+
puts "\t all / rip - download video and rip audio"
|
25
|
+
puts "\t download - prints the download url and title, separated with a tab"
|
26
|
+
puts "\t url - prints the download url"
|
27
|
+
puts "\t no command given will download the video"
|
28
|
+
puts ''
|
29
|
+
exit 0
|
30
|
+
elsif not ARGV[0].match(/youtube/)
|
31
|
+
puts "No valid youtube url supplied"
|
32
|
+
exit 1
|
33
|
+
end
|
34
|
+
|
35
|
+
the_vid = Youtube::Video.new(ARGV[0])
|
36
|
+
|
37
|
+
# Extend the_vid with some helper functions
|
38
|
+
class << the_vid
|
39
|
+
def path(type = :download_dir)
|
40
|
+
File.join(File.expand_path(ConfigYT[type]), "#{title}.#{type != :download_dir ? 'mp3' : ConfigYT[:file_extension]}")
|
41
|
+
end
|
42
|
+
|
43
|
+
def escaped_path(type = :download_dir)
|
44
|
+
path(type).shellescape
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
case ARGV[1]
|
49
|
+
when /url/i
|
50
|
+
puts the_vid.url
|
51
|
+
exit 0
|
52
|
+
when /download/i
|
53
|
+
puts "#{the_vid.url}\t#{the_vid.title}"
|
54
|
+
exit 0
|
55
|
+
end
|
56
|
+
|
57
|
+
puts 'To edit filename press up arrow'
|
58
|
+
Readline::HISTORY.push the_vid.title
|
59
|
+
name = Readline::readline("Filename: [#{the_vid.title}] ")
|
60
|
+
if name.strip.empty?
|
61
|
+
the_vid.title
|
62
|
+
else
|
63
|
+
the_vid.title = name
|
64
|
+
end
|
65
|
+
|
66
|
+
download_command = case ENV['OSTYPE']
|
67
|
+
when 'darwin' # Mac OS X
|
68
|
+
"/usr/bin/env curl -L -C - -o #{the_vid.escaped_path} '#{the_vid.url}'"
|
69
|
+
when /BSD/i
|
70
|
+
"/usr/bin/env fetch -o #{the_vid.escaped_path} '#{the_vid.url}'"
|
71
|
+
else # Linux and whatever, most people got wget installed!
|
72
|
+
"/usr/bin/env wget '#{the_vid.url}' -c -O #{the_vid.escaped_path}"
|
73
|
+
end
|
74
|
+
|
75
|
+
def rip_audio(file)
|
76
|
+
`/usr/bin/env ffmpeg -i #{file.escaped_path} -b 168b #{file.escaped_path(:music_dir)}`
|
77
|
+
end
|
78
|
+
|
79
|
+
case ARGV[1]
|
80
|
+
when /audio/i # Just audio
|
81
|
+
unless File.exist? the_vid.path
|
82
|
+
`#{download_command}`
|
83
|
+
|
84
|
+
rip_audio(the_vid)
|
85
|
+
File.unlink(the_vid.path)
|
86
|
+
else
|
87
|
+
rip_audio(the_vid)
|
88
|
+
end
|
89
|
+
when /(all)|(rip)/i # Both audio and video
|
90
|
+
`#{download_command}` unless File.exists? the_vid.path
|
91
|
+
|
92
|
+
rip_audio(the_vid)
|
93
|
+
`/usr/bin/env touch #{the_vid.path}` if ConfigYT[:touch]
|
94
|
+
else
|
95
|
+
`#{download_command}` unless File.exist? the_vid.path
|
96
|
+
`/usr/bin/env touch #{the_vid.path}` if ConfigYT[:touch]
|
97
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
---
|
2
|
+
# To download the files to the current directory set to .
|
3
|
+
:download_dir: ~/Movies
|
4
|
+
:music_dir: ~/Music
|
5
|
+
:temp_dir: /tmp
|
6
|
+
:file_extension: flv
|
7
|
+
|
8
|
+
# If we want the timestamp on the files to be time of download instead
|
9
|
+
# of time of the file
|
10
|
+
:touch: true
|
@@ -0,0 +1,55 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
$KCODE = 'u'
|
4
|
+
|
5
|
+
require 'hpricot'
|
6
|
+
require 'htmlentities'
|
7
|
+
|
8
|
+
module Youtube
|
9
|
+
class Video
|
10
|
+
attr_accessor :title
|
11
|
+
attr_accessor :video_id
|
12
|
+
attr_accessor :id
|
13
|
+
|
14
|
+
def initialize(url)
|
15
|
+
get_download_url(url)
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_s
|
19
|
+
"http://youtube.com/get_video.php?t=#{id}&video_id=#{video_id}&fmt=18"
|
20
|
+
end
|
21
|
+
alias :url :to_s
|
22
|
+
|
23
|
+
def empty?
|
24
|
+
title.nil? and video_id.nil? and id.nil?
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
def get_download_url(url)
|
29
|
+
begin
|
30
|
+
doc = Hpricot(open(url))
|
31
|
+
doc.search('//head/script').each do |el|
|
32
|
+
l = el.inner_html
|
33
|
+
|
34
|
+
if x = l.match(/"t":\s+"([^"]+)/)
|
35
|
+
@id = x[1]
|
36
|
+
end
|
37
|
+
|
38
|
+
if x = l.match(/"video_id":\s+"([^"]+)/)
|
39
|
+
@video_id = x[1]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
@title = HTMLEntities.new.decode(doc.search('//title').inner_html.squeeze.match(/YouTube\s+-\s+(.*)/)[1])
|
44
|
+
|
45
|
+
if empty?
|
46
|
+
raise Exception, "Couldn't get the information to download this video, aborting..."
|
47
|
+
end
|
48
|
+
rescue Timeout::Error
|
49
|
+
STDERR.puts "Timeout while connecting to: #{ARGV[0]}"
|
50
|
+
STDERR.puts 'Retrying...'
|
51
|
+
retry
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- coding: utf-8; mode: ruby -*-
|
2
|
+
Gem::Specification.new do |s|
|
3
|
+
s.name = "youtube-downloader"
|
4
|
+
s.version = "1.1"
|
5
|
+
s.date = Time.now.strftime('%Y-%m-%d')
|
6
|
+
s.summary = "Downloads youtube videos and optionally rips audio"
|
7
|
+
s.email = "gaqzi@sanitarium.se"
|
8
|
+
s.homepage = "http://github.com/gaqzi/youtube-downloader"
|
9
|
+
s.description = "Downloads youtube videos to your local harddrive and optionally rips the audio from the video."
|
10
|
+
s.files = ['bin/youtube-downloader', 'etc/youtube-downloader.conf',
|
11
|
+
'README', 'youtube-downloader.gemspec', 'lib/youtube-downloader/youtube.rb']
|
12
|
+
s.bindir = 'bin'
|
13
|
+
s.executables = ['youtube-downloader']
|
14
|
+
s.has_rdoc = false
|
15
|
+
s.add_dependency('hpricot', '>= 0.8.2')
|
16
|
+
s.add_dependency('htmlentities')
|
17
|
+
s.requirements << 'cURL, fetch or wget. A program to download files'
|
18
|
+
s.requirements << 'ffmpeg, for ripping the audio'
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: youtube-downloader
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: "1.1"
|
5
|
+
platform: ruby
|
6
|
+
authors: []
|
7
|
+
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-01-23 00:00:00 +01:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: hpricot
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.8.2
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: htmlentities
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
version:
|
35
|
+
description: Downloads youtube videos to your local harddrive and optionally rips the audio from the video.
|
36
|
+
email: gaqzi@sanitarium.se
|
37
|
+
executables:
|
38
|
+
- youtube-downloader
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files: []
|
42
|
+
|
43
|
+
files:
|
44
|
+
- bin/youtube-downloader
|
45
|
+
- etc/youtube-downloader.conf
|
46
|
+
- README
|
47
|
+
- youtube-downloader.gemspec
|
48
|
+
- lib/youtube-downloader/youtube.rb
|
49
|
+
has_rdoc: true
|
50
|
+
homepage: http://github.com/gaqzi/youtube-downloader
|
51
|
+
licenses: []
|
52
|
+
|
53
|
+
post_install_message:
|
54
|
+
rdoc_options: []
|
55
|
+
|
56
|
+
require_paths:
|
57
|
+
- lib
|
58
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: "0"
|
63
|
+
version:
|
64
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: "0"
|
69
|
+
version:
|
70
|
+
requirements:
|
71
|
+
- cURL, fetch or wget. A program to download files
|
72
|
+
- ffmpeg, for ripping the audio
|
73
|
+
rubyforge_project:
|
74
|
+
rubygems_version: 1.3.5
|
75
|
+
signing_key:
|
76
|
+
specification_version: 3
|
77
|
+
summary: Downloads youtube videos and optionally rips audio
|
78
|
+
test_files: []
|
79
|
+
|