viddl-rb 0.65 → 0.66
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.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:
|