2 from __future__
import unicode_literals
7 from .common
import InfoExtractor
19 class GloboIE(InfoExtractor
):
20 _VALID_URL
= 'https?://.+?\.globo\.com/(?P<id>.+)'
22 _API_URL_TEMPLATE
= 'http://api.globovideos.com/videos/%s/playlist'
23 _SECURITY_URL_TEMPLATE
= 'http://security.video.globo.com/videos/%s/hash?player=flash&version=17.0.0.132&resource_id=%s'
26 r
'\bdata-video-id="(\d+)"',
27 r
'\bdata-player-videosids="(\d+)"',
28 r
'<div[^>]+\bid="(\d+)"',
31 _RESIGN_EXPIRATION
= 86400
35 'url': 'http://globotv.globo.com/sportv/futebol-nacional/v/os-gols-de-atletico-mg-3-x-2-santos-pela-24a-rodada-do-brasileirao/3654973/',
36 'md5': '03ebf41cb7ade43581608b7d9b71fab0',
40 'title': 'Os gols de Atlético-MG 3 x 2 Santos pela 24ª rodada do Brasileirão',
48 'url': 'http://g1.globo.com/carros/autoesporte/videos/t/exclusivos-do-g1/v/mercedes-benz-gla-passa-por-teste-de-colisao-na-europa/3607726/',
49 'md5': 'b3ccc801f75cd04a914d51dadb83a78d',
53 'title': 'Mercedes-Benz GLA passa por teste de colisão na Europa',
55 'uploader': 'Globo.com',
61 'url': 'http://g1.globo.com/jornal-nacional/noticia/2014/09/novidade-na-fiscalizacao-de-bagagem-pela-receita-provoca-discussoes.html',
62 'md5': '307fdeae4390ccfe6ba1aa198cf6e72b',
66 'title': 'Receita Federal explica como vai fiscalizar bagagens de quem retorna ao Brasil de avião',
68 'uploader': 'Rede Globo',
74 'url': 'http://globotv.globo.com/canal-brasil/sangue-latino/t/todos-os-videos/v/ator-e-diretor-argentino-ricado-darin-fala-sobre-utopias-e-suas-perdas/3928201/',
75 'md5': 'c1defca721ce25b2354e927d3e4b3dec',
79 'title': 'Ator e diretor argentino, Ricado Darín fala sobre utopias e suas perdas',
81 'uploader': 'Canal Brasil',
89 HEX_FORMAT_LOWERCASE
= 0
90 HEX_FORMAT_UPPERCASE
= 1
91 BASE64_PAD_CHARACTER_DEFAULT_COMPLIANCE
= ''
92 BASE64_PAD_CHARACTER_RFC_COMPLIANCE
= '='
101 def __getitem__(self
, y
):
103 return list.__getitem
__(self
, y
)
107 def __setitem__(self
, i
, y
):
109 return list.__setitem
__(self
, i
, y
)
111 self
.extend([0] * (i
- len(self
) + 1))
115 def hex_md5(cls
, param1
):
116 return cls
.rstr2hex(cls
.rstr_md5(cls
.str2rstr_utf8(param1
)))
119 def b64_md5(cls
, param1
, param2
=None):
120 return cls
.rstr2b64(cls
.rstr_md5(cls
.str2rstr_utf8(param1
, param2
)))
123 def any_md5(cls
, param1
, param2
):
124 return cls
.rstr2any(cls
.rstr_md5(cls
.str2rstr_utf8(param1
)), param2
)
127 def rstr_md5(cls
, param1
):
128 return cls
.binl2rstr(cls
.binl_md5(cls
.rstr2binl(param1
), len(param1
) * 8))
131 def rstr2hex(cls
, param1
):
132 _loc_2
= '0123456789ABCDEF' if cls
.hexcase
else '0123456789abcdef'
134 for _loc_5
in range(0, len(param1
)):
135 _loc_4
= compat_ord(param1
[_loc_5
])
136 _loc_3
+= _loc_2
[_loc_4
>> 4 & 15] + _loc_2
[_loc_4
& 15]
140 def rstr2b64(cls
, param1
):
141 _loc_2
= 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'
144 for _loc_5
in range(0, _loc_4
, 3):
145 _loc_6_1
= compat_ord(param1
[_loc_5
]) << 16
146 _loc_6_2
= compat_ord(param1
[_loc_5
+ 1]) << 8 if _loc_5
+ 1 < _loc_4
else 0
147 _loc_6_3
= compat_ord(param1
[_loc_5
+ 2]) if _loc_5
+ 2 < _loc_4
else 0
148 _loc_6
= _loc_6_1 | _loc_6_2 | _loc_6_3
149 for _loc_7
in range(0, 4):
150 if _loc_5
* 8 + _loc_7
* 6 > len(param1
) * 8:
153 _loc_3
+= _loc_2
[_loc_6
>> 6 * (3 - _loc_7
) & 63]
157 def rstr2any(param1
, param2
):
160 _loc_9
= [0] * ((len(param1
) >> 2) + 1)
161 for _loc_5
in range(0, len(_loc_9
)):
162 _loc_9
[_loc_5
] = compat_ord(param1
[_loc_5
* 2]) << 8 |
compat_ord(param1
[_loc_5
* 2 + 1])
164 while len(_loc_9
) > 0:
167 for _loc_5
in range(0, len(_loc_9
)):
168 _loc_7
= (_loc_7
<< 16) + _loc_9
[_loc_5
]
169 _loc_6
= math
.floor(_loc_7
/ _loc_3
)
170 _loc_7
-= _loc_6
* _loc_3
171 if len(_loc_8
) > 0 or _loc_6
> 0:
172 _loc_8
[len(_loc_8
)] = _loc_6
174 _loc_4
[len(_loc_4
)] = _loc_7
178 _loc_5
= len(_loc_4
) - 1
180 _loc_10
+= param2
[_loc_4
[_loc_5
]]
186 def str2rstr_utf8(cls
, param1
, param2
=None):
191 param1
= param1
+ param2
[1:9]
194 if _loc_4
>= len(param1
):
196 _loc_5
= compat_ord(param1
[_loc_4
])
197 _loc_6
= compat_ord(param1
[_loc_4
+ 1]) if _loc_4
+ 1 < len(param1
) else 0
198 if 55296 <= _loc_5
<= 56319 and 56320 <= _loc_6
<= 57343:
199 _loc_5
= 65536 + ((_loc_5
& 1023) << 10) + (_loc_6
& 1023)
202 _loc_3
+= compat_chr(_loc_5
)
205 _loc_3
+= compat_chr(192 | _loc_5
>> 6 & 31) + compat_chr(128 | _loc_5
& 63)
208 _loc_3
+= compat_chr(224 | _loc_5
>> 12 & 15) + compat_chr(128 | _loc_5
>> 6 & 63) + compat_chr(
211 if _loc_5
<= 2097151:
212 _loc_3
+= compat_chr(240 | _loc_5
>> 18 & 7) + compat_chr(128 | _loc_5
>> 12 & 63) + compat_chr(
213 128 | _loc_5
>> 6 & 63) + compat_chr(128 | _loc_5
& 63)
217 def rstr2binl(param1
):
218 _loc_2
= [0] * ((len(param1
) >> 2) + 1)
219 for _loc_3
in range(0, len(_loc_2
)):
221 for _loc_3
in range(0, len(param1
) * 8, 8):
222 _loc_2
[_loc_3
>> 5] |
= (compat_ord(param1
[_loc_3
// 8]) & 255) << _loc_3
% 32
226 def binl2rstr(param1
):
228 for _loc_3
in range(0, len(param1
) * 32, 8):
229 _loc_2
+= compat_chr(param1
[_loc_3
>> 5] >> _loc_3
% 32 & 255)
233 def binl_md5(cls
, param1
, param2
):
234 param1
= cls
.JSArray(param1
)
235 param1
[param2
>> 5] |
= 128 << param2
% 32
236 param1
[(param2
+ 64 >> 9 << 4) + 14] = param2
241 for _loc_7
in range(0, len(param1
), 16):
246 _loc_3
= cls
.md5_ff(_loc_3
, _loc_4
, _loc_5
, _loc_6
, param1
[_loc_7
+ 0], 7, -680876936)
247 _loc_6
= cls
.md5_ff(_loc_6
, _loc_3
, _loc_4
, _loc_5
, param1
[_loc_7
+ 1], 12, -389564586)
248 _loc_5
= cls
.md5_ff(_loc_5
, _loc_6
, _loc_3
, _loc_4
, param1
[_loc_7
+ 2], 17, 606105819)
249 _loc_4
= cls
.md5_ff(_loc_4
, _loc_5
, _loc_6
, _loc_3
, param1
[_loc_7
+ 3], 22, -1044525330)
250 _loc_3
= cls
.md5_ff(_loc_3
, _loc_4
, _loc_5
, _loc_6
, param1
[_loc_7
+ 4], 7, -176418897)
251 _loc_6
= cls
.md5_ff(_loc_6
, _loc_3
, _loc_4
, _loc_5
, param1
[_loc_7
+ 5], 12, 1200080426)
252 _loc_5
= cls
.md5_ff(_loc_5
, _loc_6
, _loc_3
, _loc_4
, param1
[_loc_7
+ 6], 17, -1473231341)
253 _loc_4
= cls
.md5_ff(_loc_4
, _loc_5
, _loc_6
, _loc_3
, param1
[_loc_7
+ 7], 22, -45705983)
254 _loc_3
= cls
.md5_ff(_loc_3
, _loc_4
, _loc_5
, _loc_6
, param1
[_loc_7
+ 8], 7, 1770035416)
255 _loc_6
= cls
.md5_ff(_loc_6
, _loc_3
, _loc_4
, _loc_5
, param1
[_loc_7
+ 9], 12, -1958414417)
256 _loc_5
= cls
.md5_ff(_loc_5
, _loc_6
, _loc_3
, _loc_4
, param1
[_loc_7
+ 10], 17, -42063)
257 _loc_4
= cls
.md5_ff(_loc_4
, _loc_5
, _loc_6
, _loc_3
, param1
[_loc_7
+ 11], 22, -1990404162)
258 _loc_3
= cls
.md5_ff(_loc_3
, _loc_4
, _loc_5
, _loc_6
, param1
[_loc_7
+ 12], 7, 1804603682)
259 _loc_6
= cls
.md5_ff(_loc_6
, _loc_3
, _loc_4
, _loc_5
, param1
[_loc_7
+ 13], 12, -40341101)
260 _loc_5
= cls
.md5_ff(_loc_5
, _loc_6
, _loc_3
, _loc_4
, param1
[_loc_7
+ 14], 17, -1502002290)
261 _loc_4
= cls
.md5_ff(_loc_4
, _loc_5
, _loc_6
, _loc_3
, param1
[_loc_7
+ 15], 22, 1236535329)
262 _loc_3
= cls
.md5_gg(_loc_3
, _loc_4
, _loc_5
, _loc_6
, param1
[_loc_7
+ 1], 5, -165796510)
263 _loc_6
= cls
.md5_gg(_loc_6
, _loc_3
, _loc_4
, _loc_5
, param1
[_loc_7
+ 6], 9, -1069501632)
264 _loc_5
= cls
.md5_gg(_loc_5
, _loc_6
, _loc_3
, _loc_4
, param1
[_loc_7
+ 11], 14, 643717713)
265 _loc_4
= cls
.md5_gg(_loc_4
, _loc_5
, _loc_6
, _loc_3
, param1
[_loc_7
+ 0], 20, -373897302)
266 _loc_3
= cls
.md5_gg(_loc_3
, _loc_4
, _loc_5
, _loc_6
, param1
[_loc_7
+ 5], 5, -701558691)
267 _loc_6
= cls
.md5_gg(_loc_6
, _loc_3
, _loc_4
, _loc_5
, param1
[_loc_7
+ 10], 9, 38016083)
268 _loc_5
= cls
.md5_gg(_loc_5
, _loc_6
, _loc_3
, _loc_4
, param1
[_loc_7
+ 15], 14, -660478335)
269 _loc_4
= cls
.md5_gg(_loc_4
, _loc_5
, _loc_6
, _loc_3
, param1
[_loc_7
+ 4], 20, -405537848)
270 _loc_3
= cls
.md5_gg(_loc_3
, _loc_4
, _loc_5
, _loc_6
, param1
[_loc_7
+ 9], 5, 568446438)
271 _loc_6
= cls
.md5_gg(_loc_6
, _loc_3
, _loc_4
, _loc_5
, param1
[_loc_7
+ 14], 9, -1019803690)
272 _loc_5
= cls
.md5_gg(_loc_5
, _loc_6
, _loc_3
, _loc_4
, param1
[_loc_7
+ 3], 14, -187363961)
273 _loc_4
= cls
.md5_gg(_loc_4
, _loc_5
, _loc_6
, _loc_3
, param1
[_loc_7
+ 8], 20, 1163531501)
274 _loc_3
= cls
.md5_gg(_loc_3
, _loc_4
, _loc_5
, _loc_6
, param1
[_loc_7
+ 13], 5, -1444681467)
275 _loc_6
= cls
.md5_gg(_loc_6
, _loc_3
, _loc_4
, _loc_5
, param1
[_loc_7
+ 2], 9, -51403784)
276 _loc_5
= cls
.md5_gg(_loc_5
, _loc_6
, _loc_3
, _loc_4
, param1
[_loc_7
+ 7], 14, 1735328473)
277 _loc_4
= cls
.md5_gg(_loc_4
, _loc_5
, _loc_6
, _loc_3
, param1
[_loc_7
+ 12], 20, -1926607734)
278 _loc_3
= cls
.md5_hh(_loc_3
, _loc_4
, _loc_5
, _loc_6
, param1
[_loc_7
+ 5], 4, -378558)
279 _loc_6
= cls
.md5_hh(_loc_6
, _loc_3
, _loc_4
, _loc_5
, param1
[_loc_7
+ 8], 11, -2022574463)
280 _loc_5
= cls
.md5_hh(_loc_5
, _loc_6
, _loc_3
, _loc_4
, param1
[_loc_7
+ 11], 16, 1839030562)
281 _loc_4
= cls
.md5_hh(_loc_4
, _loc_5
, _loc_6
, _loc_3
, param1
[_loc_7
+ 14], 23, -35309556)
282 _loc_3
= cls
.md5_hh(_loc_3
, _loc_4
, _loc_5
, _loc_6
, param1
[_loc_7
+ 1], 4, -1530992060)
283 _loc_6
= cls
.md5_hh(_loc_6
, _loc_3
, _loc_4
, _loc_5
, param1
[_loc_7
+ 4], 11, 1272893353)
284 _loc_5
= cls
.md5_hh(_loc_5
, _loc_6
, _loc_3
, _loc_4
, param1
[_loc_7
+ 7], 16, -155497632)
285 _loc_4
= cls
.md5_hh(_loc_4
, _loc_5
, _loc_6
, _loc_3
, param1
[_loc_7
+ 10], 23, -1094730640)
286 _loc_3
= cls
.md5_hh(_loc_3
, _loc_4
, _loc_5
, _loc_6
, param1
[_loc_7
+ 13], 4, 681279174)
287 _loc_6
= cls
.md5_hh(_loc_6
, _loc_3
, _loc_4
, _loc_5
, param1
[_loc_7
+ 0], 11, -358537222)
288 _loc_5
= cls
.md5_hh(_loc_5
, _loc_6
, _loc_3
, _loc_4
, param1
[_loc_7
+ 3], 16, -722521979)
289 _loc_4
= cls
.md5_hh(_loc_4
, _loc_5
, _loc_6
, _loc_3
, param1
[_loc_7
+ 6], 23, 76029189)
290 _loc_3
= cls
.md5_hh(_loc_3
, _loc_4
, _loc_5
, _loc_6
, param1
[_loc_7
+ 9], 4, -640364487)
291 _loc_6
= cls
.md5_hh(_loc_6
, _loc_3
, _loc_4
, _loc_5
, param1
[_loc_7
+ 12], 11, -421815835)
292 _loc_5
= cls
.md5_hh(_loc_5
, _loc_6
, _loc_3
, _loc_4
, param1
[_loc_7
+ 15], 16, 530742520)
293 _loc_4
= cls
.md5_hh(_loc_4
, _loc_5
, _loc_6
, _loc_3
, param1
[_loc_7
+ 2], 23, -995338651)
294 _loc_3
= cls
.md5_ii(_loc_3
, _loc_4
, _loc_5
, _loc_6
, param1
[_loc_7
+ 0], 6, -198630844)
295 _loc_6
= cls
.md5_ii(_loc_6
, _loc_3
, _loc_4
, _loc_5
, param1
[_loc_7
+ 7], 10, 1126891415)
296 _loc_5
= cls
.md5_ii(_loc_5
, _loc_6
, _loc_3
, _loc_4
, param1
[_loc_7
+ 14], 15, -1416354905)
297 _loc_4
= cls
.md5_ii(_loc_4
, _loc_5
, _loc_6
, _loc_3
, param1
[_loc_7
+ 5], 21, -57434055)
298 _loc_3
= cls
.md5_ii(_loc_3
, _loc_4
, _loc_5
, _loc_6
, param1
[_loc_7
+ 12], 6, 1700485571)
299 _loc_6
= cls
.md5_ii(_loc_6
, _loc_3
, _loc_4
, _loc_5
, param1
[_loc_7
+ 3], 10, -1894986606)
300 _loc_5
= cls
.md5_ii(_loc_5
, _loc_6
, _loc_3
, _loc_4
, param1
[_loc_7
+ 10], 15, -1051523)
301 _loc_4
= cls
.md5_ii(_loc_4
, _loc_5
, _loc_6
, _loc_3
, param1
[_loc_7
+ 1], 21, -2054922799)
302 _loc_3
= cls
.md5_ii(_loc_3
, _loc_4
, _loc_5
, _loc_6
, param1
[_loc_7
+ 8], 6, 1873313359)
303 _loc_6
= cls
.md5_ii(_loc_6
, _loc_3
, _loc_4
, _loc_5
, param1
[_loc_7
+ 15], 10, -30611744)
304 _loc_5
= cls
.md5_ii(_loc_5
, _loc_6
, _loc_3
, _loc_4
, param1
[_loc_7
+ 6], 15, -1560198380)
305 _loc_4
= cls
.md5_ii(_loc_4
, _loc_5
, _loc_6
, _loc_3
, param1
[_loc_7
+ 13], 21, 1309151649)
306 _loc_3
= cls
.md5_ii(_loc_3
, _loc_4
, _loc_5
, _loc_6
, param1
[_loc_7
+ 4], 6, -145523070)
307 _loc_6
= cls
.md5_ii(_loc_6
, _loc_3
, _loc_4
, _loc_5
, param1
[_loc_7
+ 11], 10, -1120210379)
308 _loc_5
= cls
.md5_ii(_loc_5
, _loc_6
, _loc_3
, _loc_4
, param1
[_loc_7
+ 2], 15, 718787259)
309 _loc_4
= cls
.md5_ii(_loc_4
, _loc_5
, _loc_6
, _loc_3
, param1
[_loc_7
+ 9], 21, -343485551)
310 _loc_3
= cls
.safe_add(_loc_3
, _loc_8
)
311 _loc_4
= cls
.safe_add(_loc_4
, _loc_9
)
312 _loc_5
= cls
.safe_add(_loc_5
, _loc_10
)
313 _loc_6
= cls
.safe_add(_loc_6
, _loc_11
)
314 return [_loc_3
, _loc_4
, _loc_5
, _loc_6
]
317 def md5_cmn(cls
, param1
, param2
, param3
, param4
, param5
, param6
):
319 cls
.bit_rol(cls
.safe_add(cls
.safe_add(param2
, param1
), cls
.safe_add(param4
, param6
)), param5
), param3
)
322 def md5_ff(cls
, param1
, param2
, param3
, param4
, param5
, param6
, param7
):
323 return cls
.md5_cmn(param2
& param3 | ~param2
& param4
, param1
, param2
, param5
, param6
, param7
)
326 def md5_gg(cls
, param1
, param2
, param3
, param4
, param5
, param6
, param7
):
327 return cls
.md5_cmn(param2
& param4 | param3
& ~param4
, param1
, param2
, param5
, param6
, param7
)
330 def md5_hh(cls
, param1
, param2
, param3
, param4
, param5
, param6
, param7
):
331 return cls
.md5_cmn(param2 ^ param3 ^ param4
, param1
, param2
, param5
, param6
, param7
)
334 def md5_ii(cls
, param1
, param2
, param3
, param4
, param5
, param6
, param7
):
335 return cls
.md5_cmn(param3 ^
(param2 | ~param4
), param1
, param2
, param5
, param6
, param7
)
338 def safe_add(cls
, param1
, param2
):
339 _loc_3
= (param1
& 65535) + (param2
& 65535)
340 _loc_4
= (param1
>> 16) + (param2
>> 16) + (_loc_3
>> 16)
341 return cls
.lshift(_loc_4
, 16) | _loc_3
& 65535
344 def bit_rol(cls
, param1
, param2
):
345 return cls
.lshift(param1
, param2
) |
(param1
& 0xFFFFFFFF) >> (32 - param2
)
348 def lshift(value
, count
):
349 r
= (0xFFFFFFFF & value
) << count
350 return -(~
(r
- 1) & 0xFFFFFFFF) if r
> 0x7FFFFFFF else r
352 def _real_extract(self
, url
):
353 video_id
= self
._match
_id
(url
)
355 webpage
= self
._download
_webpage
(url
, video_id
)
356 video_id
= self
._search
_regex
(self
._VIDEOID
_REGEXES
, webpage
, 'video id')
358 video
= self
._download
_json
(
359 self
._API
_URL
_TEMPLATE
% video_id
, video_id
)['videos'][0]
361 title
= video
['title']
362 duration
= float_or_none(video
['duration'], 1000)
363 like_count
= video
['likes']
364 uploader
= video
['channel']
365 uploader_id
= video
['channel_id']
369 for resource
in video
['resources']:
370 resource_id
= resource
.get('_id')
374 security
= self
._download
_json
(
375 self
._SECURITY
_URL
_TEMPLATE
% (video_id
, resource_id
),
376 video_id
, 'Downloading security hash for %s' % resource_id
)
378 security_hash
= security
.get('hash')
379 if not security_hash
:
380 message
= security
.get('message')
382 raise ExtractorError(
383 '%s returned error: %s' % (self
.IE_NAME
, message
), expected
=True)
386 hash_code
= security_hash
[:2]
387 received_time
= int(security_hash
[2:12])
388 received_random
= security_hash
[12:22]
389 received_md5
= security_hash
[22:]
391 sign_time
= received_time
+ self
._RESIGN
_EXPIRATION
392 padding
= '%010d' % random
.randint(1, 10000000000)
394 signed_md5
= self
.MD5
.b64_md5(received_md5
+ compat_str(sign_time
) + padding
)
395 signed_hash
= hash_code
+ compat_str(received_time
) + received_random
+ compat_str(sign_time
) + padding
+ signed_md5
397 resource_url
= resource
['url']
398 signed_url
= '%s?h=%s&k=%s' % (resource_url
, signed_hash
, 'flash')
399 if resource_id
.endswith('m3u8') or resource_url
.endswith('.m3u8'):
400 formats
.extend(self
._extract
_m
3u8_formats
(signed_url
, resource_id
, 'mp4'))
404 'format_id': resource_id
,
405 'height': resource
.get('height'),
408 self
._sort
_formats
(formats
)
413 'duration': duration
,
414 'uploader': uploader
,
415 'uploader_id': uploader_id
,
416 'like_count': like_count
,