21
21
parse_iso8601 ,
22
22
sanitized_Request ,
23
23
std_headers ,
24
+ try_get ,
24
25
)
25
26
26
27
@@ -30,7 +31,7 @@ class VikiBaseIE(InfoExtractor):
30
31
_API_URL_TEMPLATE = 'https://api.viki.io%s&sig=%s'
31
32
32
33
_APP = '100005a'
33
- _APP_VERSION = '2.2.5.1428709186 '
34
+ _APP_VERSION = '6.0.0 '
34
35
_APP_SECRET = 'MM_d*yP@`&1@]@!AVrXf_o-HVEnoTnm$O-ti4[G~$JDI/Dc-&piU&z&5.;:}95=Iad'
35
36
36
37
_GEO_BYPASS = False
@@ -41,7 +42,7 @@ class VikiBaseIE(InfoExtractor):
41
42
_ERRORS = {
42
43
'geo' : 'Sorry, this content is not available in your region.' ,
43
44
'upcoming' : 'Sorry, this content is not yet available.' ,
44
- # 'paywall': 'paywall ',
45
+ 'paywall' : 'Sorry, this content is only available to Viki Pass Plus subscribers ' ,
45
46
}
46
47
47
48
def _prepare_call (self , path , timestamp = None , post_data = None ):
@@ -62,7 +63,8 @@ def _prepare_call(self, path, timestamp=None, post_data=None):
62
63
63
64
def _call_api (self , path , video_id , note , timestamp = None , post_data = None ):
64
65
resp = self ._download_json (
65
- self ._prepare_call (path , timestamp , post_data ), video_id , note )
66
+ self ._prepare_call (path , timestamp , post_data ), video_id , note ,
67
+ headers = {'x-viki-app-ver' : self ._APP_VERSION })
66
68
67
69
error = resp .get ('error' )
68
70
if error :
@@ -82,11 +84,13 @@ def _raise_error(self, error):
82
84
expected = True )
83
85
84
86
def _check_errors (self , data ):
85
- for reason , status in data .get ('blocking' , {}).items ():
87
+ for reason , status in ( data .get ('blocking' ) or {}).items ():
86
88
if status and reason in self ._ERRORS :
87
89
message = self ._ERRORS [reason ]
88
90
if reason == 'geo' :
89
91
self .raise_geo_restricted (msg = message )
92
+ elif reason == 'paywall' :
93
+ self .raise_login_required (message )
90
94
raise ExtractorError ('%s said: %s' % (
91
95
self .IE_NAME , message ), expected = True )
92
96
@@ -131,13 +135,19 @@ class VikiIE(VikiBaseIE):
131
135
'info_dict' : {
132
136
'id' : '1023585v' ,
133
137
'ext' : 'mp4' ,
134
- 'title' : 'Heirs Episode 14' ,
135
- 'uploader' : 'SBS' ,
136
- 'description ' : 'md5:c4b17b9626dd4b143dcc4d855ba3474e' ,
138
+ 'title' : 'Heirs - Episode 14' ,
139
+ 'uploader' : 'SBS Contents Hub ' ,
140
+ 'timestamp ' : 1385047627 ,
137
141
'upload_date' : '20131121' ,
138
142
'age_limit' : 13 ,
143
+ 'duration' : 3570 ,
144
+ 'episode_number' : 14 ,
145
+ },
146
+ 'params' : {
147
+ 'format' : 'bestvideo' ,
139
148
},
140
149
'skip' : 'Blocked in the US' ,
150
+ 'expected_warnings' : ['Unknown MIME type image/jpeg in DASH manifest' ],
141
151
}, {
142
152
# clip
143
153
'url' : 'http://www.viki.com/videos/1067139v-the-avengers-age-of-ultron-press-conference' ,
@@ -153,7 +163,8 @@ class VikiIE(VikiBaseIE):
153
163
'uploader' : 'Arirang TV' ,
154
164
'like_count' : int ,
155
165
'age_limit' : 0 ,
156
- }
166
+ },
167
+ 'skip' : 'Sorry. There was an error loading this video' ,
157
168
}, {
158
169
'url' : 'http://www.viki.com/videos/1048879v-ankhon-dekhi' ,
159
170
'info_dict' : {
@@ -171,7 +182,7 @@ class VikiIE(VikiBaseIE):
171
182
}, {
172
183
# episode
173
184
'url' : 'http://www.viki.com/videos/44699v-boys-over-flowers-episode-1' ,
174
- 'md5' : '94e0e34fd58f169f40c184f232356cfe ' ,
185
+ 'md5' : '0a53dc252e6e690feccd756861495a8c ' ,
175
186
'info_dict' : {
176
187
'id' : '44699v' ,
177
188
'ext' : 'mp4' ,
@@ -183,6 +194,10 @@ class VikiIE(VikiBaseIE):
183
194
'uploader' : 'group8' ,
184
195
'like_count' : int ,
185
196
'age_limit' : 13 ,
197
+ 'episode_number' : 1 ,
198
+ },
199
+ 'params' : {
200
+ 'format' : 'bestvideo' ,
186
201
},
187
202
'expected_warnings' : ['Unknown MIME type image/jpeg in DASH manifest' ],
188
203
}, {
@@ -209,7 +224,7 @@ class VikiIE(VikiBaseIE):
209
224
}, {
210
225
# non-English description
211
226
'url' : 'http://www.viki.com/videos/158036v-love-in-magic' ,
212
- 'md5' : 'adf9e321a0ae5d0aace349efaaff7691 ' ,
227
+ 'md5' : '41faaba0de90483fb4848952af7c7d0d ' ,
213
228
'info_dict' : {
214
229
'id' : '158036v' ,
215
230
'ext' : 'mp4' ,
@@ -220,6 +235,10 @@ class VikiIE(VikiBaseIE):
220
235
'title' : 'Love In Magic' ,
221
236
'age_limit' : 13 ,
222
237
},
238
+ 'params' : {
239
+ 'format' : 'bestvideo' ,
240
+ },
241
+ 'expected_warnings' : ['Unknown MIME type image/jpeg in DASH manifest' ],
223
242
}]
224
243
225
244
def _real_extract (self , url ):
@@ -229,36 +248,33 @@ def _real_extract(self, url):
229
248
'https://www.viki.com/api/videos/' + video_id ,
230
249
video_id , 'Downloading video JSON' , headers = {
231
250
'x-client-user-agent' : std_headers ['User-Agent' ],
232
- 'x-viki-app-ver' : '4 .0.57 ' ,
251
+ 'x-viki-app-ver' : '3 .0.0 ' ,
233
252
})
234
253
video = resp ['video' ]
235
254
236
255
self ._check_errors (video )
237
256
238
257
title = self .dict_selection (video .get ('titles' , {}), 'en' , allow_fallback = False )
258
+ episode_number = int_or_none (video .get ('number' ))
239
259
if not title :
240
- title = 'Episode %d' % video . get ( 'number' ) if video .get ('type' ) == 'episode' else video .get ('id' ) or video_id
241
- container_titles = video . get ( 'container' , {}). get ( 'titles' , {})
260
+ title = 'Episode %d' % episode_number if video .get ('type' ) == 'episode' else video .get ('id' ) or video_id
261
+ container_titles = try_get ( video , lambda x : x [ 'container' ][ 'titles' ], dict ) or {}
242
262
container_title = self .dict_selection (container_titles , 'en' )
243
263
title = '%s - %s' % (container_title , title )
244
264
245
265
description = self .dict_selection (video .get ('descriptions' , {}), 'en' )
246
266
247
- duration = int_or_none (video .get ('duration' ))
248
- timestamp = parse_iso8601 (video .get ('created_at' ))
249
- uploader = video .get ('author' )
250
- like_count = int_or_none (video .get ('likes' , {}).get ('count' ))
251
- age_limit = parse_age_limit (video .get ('rating' ))
267
+ like_count = int_or_none (try_get (video , lambda x : x ['likes' ]['count' ]))
252
268
253
269
thumbnails = []
254
- for thumbnail_id , thumbnail in video .get ('images' , {}).items ():
270
+ for thumbnail_id , thumbnail in ( video .get ('images' ) or {}).items ():
255
271
thumbnails .append ({
256
272
'id' : thumbnail_id ,
257
273
'url' : thumbnail .get ('url' ),
258
274
})
259
275
260
276
subtitles = {}
261
- for subtitle_lang , _ in video .get ('subtitle_completions' , {}).items ():
277
+ for subtitle_lang , _ in ( video .get ('subtitle_completions' ) or {}).items ():
262
278
subtitles [subtitle_lang ] = [{
263
279
'ext' : subtitles_format ,
264
280
'url' : self ._prepare_call (
@@ -269,13 +285,15 @@ def _real_extract(self, url):
269
285
'id' : video_id ,
270
286
'title' : title ,
271
287
'description' : description ,
272
- 'duration' : duration ,
273
- 'timestamp' : timestamp ,
274
- 'uploader' : uploader ,
288
+ 'duration' : int_or_none (video .get ('duration' )),
289
+ 'timestamp' : parse_iso8601 (video .get ('created_at' )),
290
+ 'uploader' : video .get ('author' ),
291
+ 'uploader_url' : video .get ('author_url' ),
275
292
'like_count' : like_count ,
276
- 'age_limit' : age_limit ,
293
+ 'age_limit' : parse_age_limit ( video . get ( 'rating' )) ,
277
294
'thumbnails' : thumbnails ,
278
295
'subtitles' : subtitles ,
296
+ 'episode_number' : episode_number ,
279
297
}
280
298
281
299
formats = []
@@ -360,7 +378,7 @@ class VikiChannelIE(VikiBaseIE):
360
378
'info_dict' : {
361
379
'id' : '50c' ,
362
380
'title' : 'Boys Over Flowers' ,
363
- 'description' : 'md5:ecd3cff47967fe193cff37c0bec52790 ' ,
381
+ 'description' : 'md5:804ce6e7837e1fd527ad2f25420f4d59 ' ,
364
382
},
365
383
'playlist_mincount' : 71 ,
366
384
}, {
@@ -371,6 +389,7 @@ class VikiChannelIE(VikiBaseIE):
371
389
'description' : 'md5:05bf5471385aa8b21c18ad450e350525' ,
372
390
},
373
391
'playlist_count' : 127 ,
392
+ 'skip' : 'Page not found' ,
374
393
}, {
375
394
'url' : 'http://www.viki.com/news/24569c-showbiz-korea' ,
376
395
'only_matching' : True ,
0 commit comments