rubytube 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,173 +1,173 @@
1
- module RubyTube
2
- class Client
3
- attr_accessor :video_id, :watch_url, :embed_url, :stream_monostate
4
-
5
- def initialize(url)
6
- self.video_id = Extractor.video_id(url)
7
-
8
- self.watch_url = "https://youtube.com/watch?v=#{video_id}"
9
- self.embed_url = "https://www.youtube.com/embed/#{video_id}"
10
-
11
- self.stream_monostate = Monostate.new
12
- end
13
-
14
- def watch_html
15
- return @watch_html if @watch_html
16
-
17
- @watch_html = Request.get(watch_url)
18
- @watch_html
19
- end
20
-
21
- def js
22
- return @js if @js
23
-
24
- @js = Request.get(js_url)
25
- @js
26
- end
27
-
28
- def js_url
29
- return @js_url if @js_url
30
-
31
- @js_url = Extractor.js_url(watch_html)
32
- @js_url
33
- end
34
-
35
- def streaming_data
36
- return vid_info['streamingData'] if vid_info && vid_info.key?('streamingData')
37
-
38
- bypass_age_gate
39
- vid_info['streamingData']
40
- end
41
-
42
- def fmt_streams
43
- check_availability
44
- return @fmt_streams if @fmt_streams
45
-
46
- @fmt_streams = []
47
- stream_manifest = Extractor.apply_descrambler(streaming_data)
48
-
49
- begin
50
- Extractor.apply_signature(stream_manifest, vid_info, js)
51
- rescue ExtractError
52
- js = nil
53
- js_url = nil
54
- Extractor.apply_signature(stream_manifest, vid_info, js)
55
- end
56
-
57
- for stream in stream_manifest
58
- @fmt_streams << Stream.new(stream, stream_monostate)
59
- end
60
-
61
- stream_monostate.title = title
62
- stream_monostate.duration = length
63
-
64
- @fmt_streams
65
- end
66
-
67
- def check_availability
68
- status, messages = Extractor.playability_status(watch_html)
69
-
70
- messages.each do |reason|
71
- case status
72
- when 'UNPLAYABLE'
73
- case reason
74
- when 'Join this channel to get access to members-only content like this video, and other exclusive perks.'
75
- raise MembersOnly.new(video_id)
76
- when 'This live stream recording is not available.'
77
- raise RecordingUnavailable.new(video_id)
78
- else
79
- raise VideoUnavailable.new(video_id)
80
- end
81
- when 'LOGIN_REQUIRED'
82
- if reason == 'This is a private video. Please sign in to verify that you may see it.'
83
- raise VideoPrivate.new(video_id)
84
- end
85
- when 'ERROR'
86
- if reason == 'Video unavailable'
87
- raise VideoUnavailable.new(video_id)
88
- end
89
- when 'LIVE_STREAM'
90
- raise LiveStreamError.new(video_id)
91
- end
92
- end
93
- end
94
-
95
- def streams
96
- return @streams if @streams
97
-
98
- check_availability
99
- @streams = StreamQuery.new(fmt_streams)
100
- end
101
-
102
- def thumbnail_url
103
- thumbs = vid_info.fetch('videoDetails', {}).fetch('thumbnail', {}).fetch('thumbnails', [])
104
-
105
- return thumbs[-1]['url'] if thumbs.size > 0
106
-
107
- "https://img.youtube.com/vi/#{ideo_id}/maxresdefault.jpg"
108
- end
109
-
110
- def vid_info
111
- return @vid_info if @vid_info
112
-
113
- it = InnerTube.new
114
- @vid_info = it.player(video_id)
115
-
116
- @vid_info
117
- end
118
-
119
- def bypass_age_gate
120
- it = InnerTube.new(client: 'ANDROID_EMBED')
121
- resp = it.player(video_id)
122
-
123
- status = resp['playabilityStatus']['status']
124
- if status == 'UNPLAYABLE'
125
- raise VideoUnavailable.new(video_id)
126
- end
127
-
128
- @vid_info = resp
129
- end
130
-
131
- def title
132
- return @title if @title
133
-
134
- @title = vid_info['videoDetails']['title']
135
- @title
136
- end
137
-
138
- def length
139
- return @length if @length
140
-
141
- @length = vid_info['videoDetails']['lengthSeconds'].to_i
142
- @length
143
- end
144
-
145
- def views
146
- return @views if @views
147
-
148
- @views = vid_info['videoDetails']['viewCount'].to_i
149
- @views
150
- end
151
-
152
- def author
153
- return @author if @author
154
-
155
- @author = vid_info['videoDetails']['author']
156
- @author
157
- end
158
-
159
- def keywords
160
- return @keywords if @keywords
161
-
162
- @keywords = vid_info['videoDetails']['keywords']
163
- @keywords
164
- end
165
-
166
- def channel_id
167
- return @channel_id if @channel_id
168
-
169
- @channel_id = vid_info['videoDetails']['channelId']
170
- @channel_id
171
- end
172
- end
173
- end
1
+ module RubyTube
2
+ class Client
3
+ attr_accessor :video_id, :watch_url, :embed_url, :stream_monostate
4
+
5
+ def initialize(url)
6
+ self.video_id = Extractor.video_id(url)
7
+
8
+ self.watch_url = "https://youtube.com/watch?v=#{video_id}"
9
+ self.embed_url = "https://www.youtube.com/embed/#{video_id}"
10
+
11
+ self.stream_monostate = Monostate.new
12
+ end
13
+
14
+ def watch_html
15
+ return @watch_html if @watch_html
16
+
17
+ @watch_html = Request.get(watch_url)
18
+ @watch_html
19
+ end
20
+
21
+ def js
22
+ return @js if @js
23
+
24
+ @js = Request.get(js_url)
25
+ @js
26
+ end
27
+
28
+ def js_url
29
+ return @js_url if @js_url
30
+
31
+ @js_url = Extractor.js_url(watch_html)
32
+ @js_url
33
+ end
34
+
35
+ def streaming_data
36
+ return vid_info['streamingData'] if vid_info && vid_info.key?('streamingData')
37
+
38
+ bypass_age_gate
39
+ vid_info['streamingData']
40
+ end
41
+
42
+ def fmt_streams
43
+ check_availability
44
+ return @fmt_streams if @fmt_streams
45
+
46
+ @fmt_streams = []
47
+ stream_manifest = Extractor.apply_descrambler(streaming_data)
48
+
49
+ begin
50
+ Extractor.apply_signature(stream_manifest, vid_info, js)
51
+ rescue ExtractError
52
+ js = nil
53
+ js_url = nil
54
+ Extractor.apply_signature(stream_manifest, vid_info, js)
55
+ end
56
+
57
+ for stream in stream_manifest
58
+ @fmt_streams << Stream.new(stream, stream_monostate)
59
+ end
60
+
61
+ stream_monostate.title = title
62
+ stream_monostate.duration = length
63
+
64
+ @fmt_streams
65
+ end
66
+
67
+ def check_availability
68
+ status, messages = Extractor.playability_status(watch_html)
69
+
70
+ messages.each do |reason|
71
+ case status
72
+ when 'UNPLAYABLE'
73
+ case reason
74
+ when 'Join this channel to get access to members-only content like this video, and other exclusive perks.'
75
+ raise MembersOnly.new(video_id)
76
+ when 'This live stream recording is not available.'
77
+ raise RecordingUnavailable.new(video_id)
78
+ else
79
+ raise VideoUnavailable.new(video_id)
80
+ end
81
+ when 'LOGIN_REQUIRED'
82
+ if reason == 'This is a private video. Please sign in to verify that you may see it.'
83
+ raise VideoPrivate.new(video_id)
84
+ end
85
+ when 'ERROR'
86
+ if reason == 'Video unavailable'
87
+ raise VideoUnavailable.new(video_id)
88
+ end
89
+ when 'LIVE_STREAM'
90
+ raise LiveStreamError.new(video_id)
91
+ end
92
+ end
93
+ end
94
+
95
+ def streams
96
+ return @streams if @streams
97
+
98
+ check_availability
99
+ @streams = StreamQuery.new(fmt_streams)
100
+ end
101
+
102
+ def thumbnail_url
103
+ thumbs = vid_info.fetch('videoDetails', {}).fetch('thumbnail', {}).fetch('thumbnails', [])
104
+
105
+ return thumbs[-1]['url'] if thumbs.size > 0
106
+
107
+ "https://img.youtube.com/vi/#{ideo_id}/maxresdefault.jpg"
108
+ end
109
+
110
+ def vid_info
111
+ return @vid_info if @vid_info
112
+
113
+ it = InnerTube.new
114
+ @vid_info = it.player(video_id)
115
+
116
+ @vid_info
117
+ end
118
+
119
+ def bypass_age_gate
120
+ it = InnerTube.new(client: 'ANDROID_EMBED')
121
+ resp = it.player(video_id)
122
+
123
+ status = resp['playabilityStatus']['status']
124
+ if status == 'UNPLAYABLE'
125
+ raise VideoUnavailable.new(video_id)
126
+ end
127
+
128
+ @vid_info = resp
129
+ end
130
+
131
+ def title
132
+ return @title if @title
133
+
134
+ @title = vid_info['videoDetails']['title']
135
+ @title
136
+ end
137
+
138
+ def length
139
+ return @length if @length
140
+
141
+ @length = vid_info['videoDetails']['lengthSeconds'].to_i
142
+ @length
143
+ end
144
+
145
+ def views
146
+ return @views if @views
147
+
148
+ @views = vid_info['videoDetails']['viewCount'].to_i
149
+ @views
150
+ end
151
+
152
+ def author
153
+ return @author if @author
154
+
155
+ @author = vid_info['videoDetails']['author']
156
+ @author
157
+ end
158
+
159
+ def keywords
160
+ return @keywords if @keywords
161
+
162
+ @keywords = vid_info['videoDetails']['keywords']
163
+ @keywords
164
+ end
165
+
166
+ def channel_id
167
+ return @channel_id if @channel_id
168
+
169
+ @channel_id = vid_info['videoDetails']['channelId']
170
+ @channel_id
171
+ end
172
+ end
173
+ end