viddl-rb 0.65 → 0.66
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +11 -2
- data/bin/viddl-rb +1 -0
- data/plugins/vimeo.rb +38 -24
- data/plugins/youtube.rb +27 -7
- metadata +22 -8
data/README.md
CHANGED
@@ -18,16 +18,25 @@ Download a video and extract the audio:
|
|
18
18
|
|
19
19
|
In both cases we'll name the output file according to the video title.
|
20
20
|
|
21
|
-
|
21
|
+
__Youtube plugin specifics:__
|
22
|
+
|
23
|
+
Download all videos on a playlist:
|
22
24
|
viddl-rb http://www.youtube.com/playlist?list=PL7E8DA0A515924126
|
23
25
|
|
24
|
-
Download all videos from a
|
26
|
+
Download all videos from a user:
|
25
27
|
viddl-rb http://www.youtube.com/user/tedtalksdirector
|
26
28
|
|
29
|
+
Filter videos to download from a user/playlist:
|
30
|
+
viddl-rb http://www.youtube.com/user/tedtalksdirector --filter=internet/i
|
31
|
+
|
32
|
+
The --filter argument accepts a regular expression and will only download videos where the title matches the regex.
|
33
|
+
The /i option does a case-insensitive search.
|
34
|
+
|
27
35
|
__Requirements:__
|
28
36
|
|
29
37
|
* curl/wget or the [progress bar](http://github.com/nex3/ruby-progressbar/) gem
|
30
38
|
* [Nokogiri](http://nokogiri.org/)
|
39
|
+
* [Mechanize](http://mechanize.rubyforge.org/)
|
31
40
|
* ffmpeg if you want to extract audio tracks from the videos
|
32
41
|
|
33
42
|
|
data/bin/viddl-rb
CHANGED
data/plugins/vimeo.rb
CHANGED
@@ -1,25 +1,39 @@
|
|
1
|
+
|
1
2
|
class Vimeo < PluginBase
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
3
|
+
#this will be called by the main app to check whether this plugin is responsible for the url passed
|
4
|
+
def self.matches_provider?(url)
|
5
|
+
url.include?("vimeo.com")
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.get_urls_and_filenames(url)
|
9
|
+
#the vimeo ID consists of 7 decimal numbers in the URL
|
10
|
+
vimeo_id = url[/\d{7,8}/]
|
11
|
+
|
12
|
+
agent = Mechanize.new #use Mechanize for the automatic cookie handeling
|
13
|
+
agent.redirect_ok = false #don't follow redirects so we do not download the video when we get it's url
|
14
|
+
|
15
|
+
video_page = agent.get("http://vimeo.com/#{vimeo_id}")
|
16
|
+
page_html = video_page.root.inner_html
|
17
|
+
|
18
|
+
title = page_html[/<meta\s+property="og:title"\s+content="(.+?)"/, 1]
|
19
|
+
puts "[VIMEO] Title: #{title}"
|
20
|
+
|
21
|
+
#the timestamp and sig info is in the embedded player javascript in the video page
|
22
|
+
timestamp = page_html[/"timestamp":(\d+),/, 1]
|
23
|
+
signature = page_html[/"signature":"([\d\w]+)",/, 1]
|
24
|
+
|
25
|
+
# The quality and codecs are listed in order of preference in the url. If HD is not availabe SD will be download for example.
|
26
|
+
redirect_url = "http://player.vimeo.com/play_redirect?clip_id=#{vimeo_id}&sig=#{signature}&time=#{timestamp}&quality=hd,sd&codecs=H264,VP8,VP6"
|
27
|
+
|
28
|
+
#the download url is the value of the location (redirect) header
|
29
|
+
download_url = agent.get(redirect_url).header["location"]
|
30
|
+
|
31
|
+
file_name = make_filename(title)
|
32
|
+
|
33
|
+
[{:url => download_url, :name => file_name}]
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.make_filename(title)
|
37
|
+
title.delete("\"'").gsub(/[^\d\w]/, '_') + ".mp4"
|
38
|
+
end
|
39
|
+
end
|
data/plugins/youtube.rb
CHANGED
@@ -7,23 +7,43 @@ class Youtube < PluginBase
|
|
7
7
|
|
8
8
|
#get all videos and return their urls in an array
|
9
9
|
def self.get_video_urls(feed_url)
|
10
|
-
|
10
|
+
puts "[YOUTUBE] Retrieving videos..."
|
11
|
+
urls_titles = Hash.new
|
11
12
|
result_feed = Nokogiri::HTML(open(feed_url))
|
12
|
-
|
13
|
+
urls_titles.merge!(grab_ut(result_feed))
|
13
14
|
|
14
15
|
#as long as the feed has a next link we follow it and add the resulting video urls
|
15
16
|
loop do
|
16
17
|
next_link = result_feed.search("//feed/link[@rel='next']").first
|
17
18
|
break if next_link.nil?
|
18
19
|
result_feed = Nokogiri::HTML(open(next_link["href"]))
|
19
|
-
|
20
|
+
urls_titles.merge!(grab_ut(result_feed))
|
21
|
+
end
|
22
|
+
|
23
|
+
self.filter_urls(urls_titles)
|
24
|
+
end
|
25
|
+
|
26
|
+
#returns only the urls that match the --filter argument regex (if present)
|
27
|
+
def self.filter_urls(url_hash)
|
28
|
+
#get the --filter arg or "" if it is not present (because nil would break the next line)
|
29
|
+
filter = ARGV.find( proc {""} ) { |arg| arg =~ /--filter=/ }
|
30
|
+
regex = filter[/--filter=(.+?)(?:\/|$)/, 1]
|
31
|
+
if regex
|
32
|
+
puts "[YOUTUBE] Using filter: #{regex}"
|
33
|
+
ignore_case = filter.include?("/i")
|
34
|
+
filtered = url_hash.select { |url, title| title =~ Regexp.new(regex, ignore_case) }
|
35
|
+
filtered.keys
|
36
|
+
else
|
37
|
+
url_hash.keys
|
20
38
|
end
|
21
|
-
urls.flatten
|
22
39
|
end
|
23
40
|
|
24
|
-
#extract all video urls
|
25
|
-
def self.
|
26
|
-
feed.
|
41
|
+
#extract all video urls and their titles from a feed and return in a hash
|
42
|
+
def self.grab_ut(feed)
|
43
|
+
feed.remove_namespaces! #so that we can get to the titles easily
|
44
|
+
urls = feed.search("//entry/link[@rel='alternate']").map { |link| link["href"] }
|
45
|
+
titles = feed.search("//entry/group/title").map { |title| title.text }
|
46
|
+
Hash[urls.zip(titles)] #hash like this: url => title
|
27
47
|
end
|
28
48
|
|
29
49
|
def self.parse_playlist(url)
|
metadata
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: viddl-rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 143
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: "0.
|
8
|
+
- 66
|
9
|
+
version: "0.66"
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Marc Seeger
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2012-
|
17
|
+
date: 2012-06-03 00:00:00 Z
|
18
18
|
dependencies:
|
19
19
|
- !ruby/object:Gem::Dependency
|
20
20
|
name: nokogiri
|
@@ -31,7 +31,7 @@ dependencies:
|
|
31
31
|
type: :runtime
|
32
32
|
version_requirements: *id001
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
|
-
name:
|
34
|
+
name: mechanize
|
35
35
|
prerelease: false
|
36
36
|
requirement: &id002 !ruby/object:Gem::Requirement
|
37
37
|
none: false
|
@@ -42,10 +42,10 @@ dependencies:
|
|
42
42
|
segments:
|
43
43
|
- 0
|
44
44
|
version: "0"
|
45
|
-
type: :
|
45
|
+
type: :runtime
|
46
46
|
version_requirements: *id002
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
|
-
name:
|
48
|
+
name: rake
|
49
49
|
prerelease: false
|
50
50
|
requirement: &id003 !ruby/object:Gem::Requirement
|
51
51
|
none: false
|
@@ -59,7 +59,7 @@ dependencies:
|
|
59
59
|
type: :development
|
60
60
|
version_requirements: *id003
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
|
-
name:
|
62
|
+
name: minitest
|
63
63
|
prerelease: false
|
64
64
|
requirement: &id004 !ruby/object:Gem::Requirement
|
65
65
|
none: false
|
@@ -72,6 +72,20 @@ dependencies:
|
|
72
72
|
version: "0"
|
73
73
|
type: :development
|
74
74
|
version_requirements: *id004
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: rest-client
|
77
|
+
prerelease: false
|
78
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
79
|
+
none: false
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
hash: 3
|
84
|
+
segments:
|
85
|
+
- 0
|
86
|
+
version: "0"
|
87
|
+
type: :development
|
88
|
+
version_requirements: *id005
|
75
89
|
description: An extendable commandline video downloader for flash video sites. Includes plugins for vimeo, youtube and megavideo
|
76
90
|
email: mail@marc-seeger.de
|
77
91
|
executables:
|