youtube_utils 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/bin/youtube_utils +1 -0
  2. data/lib/youtube_utils.rb +38 -37
  3. metadata +18 -44
data/bin/youtube_utils CHANGED
@@ -45,6 +45,7 @@ end
45
45
 
46
46
  def run url
47
47
  videos = YoutubeUtils.new.get_videos url
48
+ return if videos.empty?
48
49
  index = ask_user_which_one_to_download(videos).to_i
49
50
  download videos[index]['url'], build_filename(url, videos[index]['type'])
50
51
  end
data/lib/youtube_utils.rb CHANGED
@@ -1,37 +1,28 @@
1
1
  require 'net/http'
2
- require 'yajl'
3
2
  require 'uri'
4
3
 
5
4
  #http://unlockforus.blogspot.com/2010/04/downloading-youtube-videos-not-working.html
6
5
  #http://board.jdownloader.org/showthread.php?t=18520
6
+ #http://userscripts.org/topics/83095?page=1#posts-372119
7
7
  class YoutubeUtils
8
+
9
+ def initialize(debug = false)
10
+ @debug = debug
11
+ end
12
+
8
13
  def get_videos youtube_watch_url
9
14
  res = get_webpage(youtube_watch_url);
10
15
  unless res.code == '200'
11
- puts res.code
12
- return []
13
- end
14
-
15
- hash = json_to_hash(get_PLAYER_CONFIG(res.body))
16
- unless hash
17
- puts "no PLAYER_CONFIG"
18
- return []
19
- end
20
-
21
- args = hash['args']
22
- unless args
23
- puts "no args"
24
- return []
16
+ raise res.code
25
17
  end
26
18
 
27
19
  result = []
28
20
 
29
- html5_fmt_map = args['html5_fmt_map']
30
- result.concat(convert_html5_fmt_map(html5_fmt_map)) if html5_fmt_map
31
-
32
- fmt_stream_map = args['fmt_stream_map']
33
- fmt_list = args['fmt_list']
34
- result.concat(convert_fmt_stream_map(fmt_stream_map, fmt_list)) if fmt_list&&fmt_stream_map
21
+ fmt_stream_map = get_url_encoded_fmt_stream_map(res.body)
22
+ fmt_list = get_fmt_list(res.body)
23
+ puts fmt_stream_map, fmt_list if @debug
24
+
25
+ result.concat(parse_fmt_stream_map(fmt_stream_map, fmt_list)) if fmt_list&&fmt_stream_map
35
26
 
36
27
  return result
37
28
  end
@@ -60,7 +51,7 @@ class YoutubeUtils
60
51
  def convert_itag_to_type itag
61
52
  case itag.to_i
62
53
  when 0, 6
63
- return "video/flv; codecs=\" h263, mp3 mono\""
54
+ return "video/flv; codecs=\"h263, mp3 mono\""
64
55
  when 5
65
56
  return "video/flv; codecs=\"h263, mp3 stereo\""
66
57
  when 34, 35
@@ -72,35 +63,36 @@ class YoutubeUtils
72
63
  when 18, 22, 37, 38, 78
73
64
  return "video/mp4; codecs=\"h264, aac stereo\""
74
65
  when 43, 45
75
- return "video/webm; codecs=\"vp8.0, vorbis stereo\""
66
+ return "video/webm; codecs=\"vp8, vorbis stereo\""
76
67
  else
77
68
  return "unknown #{itag}"
78
69
  end
79
70
  end
80
-
81
- #{"url"=>"http://v5.lscache8.c.youtube.com/videoplayback?...", "type"=>"video/webm; codecs=\"vp8.0, vorbis\"", "itag"=>43, "quality"=>"medium"}
82
- def convert_html5_fmt_map a
83
- result = []
84
- a.each {|x|
85
- result << {'url' => x['url'], 'type' => x['type'], 'quality' => x['quality']}
71
+
72
+ def querystring_2_hash s
73
+ h = {}
74
+ s.split("\\u0026").each { |x|
75
+ a = x.split("=")
76
+ h[a[0]] = a[1]
86
77
  }
87
- return result
78
+ h
88
79
  end
89
80
 
81
+ #url=http://o-o.preferred.comcast-iad1.v2.lscache7.c.youtube.com/videoplayback?sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Csource%2Calgorithm%2Cburst%2Cfactor%2Ccp&fexp=907508%2C903945%2C912602&algorithm=throttle-factor&itag=5&ip=69.0.0.0&burst=40&sver=3&signature=188F0E975207AB14B86050D0D21CFFFEFBCE4B00.D4BF3A75D2670F58B4FF4FF3AFADD1174A9EE574&source=youtube&expire=1324417594&key=yt1&ipbits=8&factor=1.25&cp=U0hRSVRMVV9OTkNOMV9MRllGOjdZSVc4aUgtZUFB&id=ef388a3d0169fd70\u0026quality=small\u0026fallback_host=tc.v2.cache7.c.youtube.com\u0026type=video/x-flv\u0026itag=5
90
82
  #22/1280x720/9/0/115
91
- def convert_fmt_stream_map fmt_stream_map, fmt_list
83
+ def parse_fmt_stream_map fmt_stream_map, fmt_list
92
84
  result = []
93
85
  a1 = fmt_stream_map.split(',')
94
86
  a2 = fmt_list.split(',')
95
87
  i = 0
96
88
  a1.each {|x|
97
- a11 = x.split('|')
98
- itag = a11[0]
99
- url = a11[1]
89
+ h = querystring_2_hash(x)
90
+ itag = h['itag']
91
+ url = h['url']
100
92
 
101
93
  a21 = a2[i].split('/')
102
94
  resolution = a21[1]
103
- result << {'url' => url, 'type' => convert_itag_to_type(itag), 'quality' => resolution2quality(resolution)}
95
+ result << {'url' => URI.unescape(url), 'type' => convert_itag_to_type(itag), 'quality' => resolution2quality(resolution)}
104
96
  i += 1;
105
97
  }
106
98
  return result
@@ -143,9 +135,18 @@ class YoutubeUtils
143
135
  end
144
136
  end
145
137
 
146
- def get_PLAYER_CONFIG body
147
- body[/\'PLAYER_CONFIG\':(.*)\}\)\;\n/]
138
+ def get_fmt_list body
139
+ body[/\"fmt_list\":\s?\"(.+?)\"/]
140
+ return $1
141
+ end
142
+
143
+ def get_url_encoded_fmt_stream_map body
144
+ body[/\"url_encoded_fmt_stream_map\":\s?\"(.+?)\"/]
148
145
  return $1
149
146
  end
150
147
  end
151
148
 
149
+ if __FILE__ == $0
150
+ p YoutubeUtils.new(true).get_videos "http://www.youtube.com/watch?v=7ziKPQFp_XA"
151
+ end
152
+
metadata CHANGED
@@ -1,50 +1,30 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: youtube_utils
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
5
- prerelease: false
6
- segments:
7
- - 0
8
- - 1
9
- - 0
10
- version: 0.1.0
4
+ prerelease:
5
+ version: 0.1.1
11
6
  platform: ruby
12
7
  authors:
13
- - Xue Yong Zhi
8
+ - Xue Yong Zhi
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
12
 
18
- date: 2011-04-28 00:00:00 -04:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
22
- name: yajl-ruby
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
25
- none: false
26
- requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- hash: 3
30
- segments:
31
- - 0
32
- version: "0"
33
- type: :runtime
34
- version_requirements: *id001
13
+ date: 2011-04-28 00:00:00 Z
14
+ dependencies: []
15
+
35
16
  description:
36
17
  email:
37
- - yong@intridea.com
18
+ - yong@intridea.com
38
19
  executables:
39
- - youtube_utils
20
+ - youtube_utils
40
21
  extensions: []
41
22
 
42
23
  extra_rdoc_files: []
43
24
 
44
25
  files:
45
- - lib/youtube_utils.rb
46
- - bin/youtube_utils
47
- has_rdoc: true
26
+ - lib/youtube_utils.rb
27
+ - bin/youtube_utils
48
28
  homepage: http://github.com/yong/youtube_utils
49
29
  licenses: []
50
30
 
@@ -52,29 +32,23 @@ post_install_message:
52
32
  rdoc_options: []
53
33
 
54
34
  require_paths:
55
- - lib
35
+ - lib
56
36
  required_ruby_version: !ruby/object:Gem::Requirement
57
37
  none: false
58
38
  requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- hash: 3
62
- segments:
63
- - 0
64
- version: "0"
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: "0"
65
42
  required_rubygems_version: !ruby/object:Gem::Requirement
66
43
  none: false
67
44
  requirements:
68
- - - ">="
69
- - !ruby/object:Gem::Version
70
- hash: 3
71
- segments:
72
- - 0
73
- version: "0"
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: "0"
74
48
  requirements: []
75
49
 
76
50
  rubyforge_project:
77
- rubygems_version: 1.3.7
51
+ rubygems_version: 1.8.9
78
52
  signing_key:
79
53
  specification_version: 3
80
54
  summary: youtube downloader