]>
Raphaƫl G. Git Repositories - youtubedl/blob - youtube_dl/extractor/vvvvid.py
   2 from __future__ 
import unicode_literals
 
   6 from .common 
import InfoExtractor
 
  14 class VVVVIDIE(InfoExtractor
): 
  15     _VALID_URL 
= r
'https?://(?:www\.)?vvvvid\.it/(?:#!)?(?:show|anime|film|series)/(?P<show_id>\d+)/[^/]+/(?P<season_id>\d+)/(?P<id>[0-9]+)' 
  17         # video_type == 'video/vvvvid' 
  18         'url': 'https://www.vvvvid.it/#!show/434/perche-dovrei-guardarlo-di-dario-moccia/437/489048/ping-pong', 
  19         'md5': 'b8d3cecc2e981adc3835adf07f6df91b', 
  26             'skip_download': True, 
  29         # video_type == 'video/rcs' 
  30         'url': 'https://www.vvvvid.it/#!show/376/death-note-live-action/377/482493/episodio-01', 
  31         'md5': '33e0edfba720ad73a8782157fdebc648', 
  35             'title': 'Episodio 01', 
  38             'skip_download': True, 
  43     def _real_initialize(self
): 
  44         self
._conn
_id 
= self
._download
_json
( 
  45             'https://www.vvvvid.it/user/login', 
  46             None, headers
=self
.geo_verification_headers())['data']['conn_id'] 
  48     def _real_extract(self
, url
): 
  49         show_id
, season_id
, video_id 
= re
.match(self
._VALID
_URL
, url
).groups() 
  50         response 
= self
._download
_json
( 
  51             'https://www.vvvvid.it/vvvvid/ondemand/%s/season/%s' % (show_id
, season_id
), 
  52             video_id
, headers
=self
.geo_verification_headers(), query
={ 
  53                 'conn_id': self
._conn
_id
, 
  55         if response
['result'] == 'error': 
  56             raise ExtractorError('%s said: %s' % ( 
  57                 self
.IE_NAME
, response
['message']), expected
=True) 
  60         video_data 
= list(filter( 
  61             lambda episode
: episode
.get('video_id') == vid
, response
['data']))[0] 
  64         # vvvvid embed_info decryption algorithm is reverse engineered from function $ds(h) at vvvvid.js 
  66             g 
= "MNOPIJKL89+/4567UVWXQRSTEFGHABCDcdefYZabstuvopqr0123wxyzklmnghij" 
  73                 while ((not b
) and o 
< m_len
): 
  82                             k 
= (m
[o 
- 1] << 4) & 255 
  86                                 j 
= (m
[o 
- 1] << 6) & 255 
 107             for e 
in range(c_len 
* 2 - 1, -1, -1): 
 108                 a 
= c
[e 
% c_len
] ^ c
[(e 
+ 1) % c_len
] 
 118         for quality 
in ('_sd', ''): 
 119             embed_code 
= video_data
.get('embed_info' + quality
) 
 122             embed_code 
= ds(embed_code
) 
 123             video_type 
= video_data
.get('video_type') 
 124             if video_type 
in ('video/rcs', 'video/kenc'): 
 125                 embed_code 
= re
.sub(r
'https?://([^/]+)/z/', r
'https://\1/i/', embed_code
).replace('/manifest.f4m', '/master.m3u8') 
 126                 if video_type 
== 'video/kenc': 
 127                     kenc 
= self
._download
_json
( 
 128                         'https://www.vvvvid.it/kenc', video_id
, query
={ 
 130                             'conn_id': self
._conn
_id
, 
 132                         }, fatal
=False) or {} 
 133                     kenc_message 
= kenc
.get('message') 
 135                         embed_code 
+= '?' + ds(kenc_message
) 
 136                 formats
.extend(self
._extract
_m
3u8_formats
( 
 137                     embed_code
, video_id
, 'mp4', 
 138                     m3u8_id
='hls', fatal
=False)) 
 140                 formats
.extend(self
._extract
_wowza
_formats
( 
 141                     'http://sb.top-ix.org/videomg/_definst_/mp4:%s/playlist.m3u8' % embed_code
, video_id
)) 
 142         self
._sort
_formats
(formats
) 
 146             'title': video_data
['title'], 
 148             'thumbnail': video_data
.get('thumbnail'), 
 149             'duration': int_or_none(video_data
.get('length')), 
 150             'series': video_data
.get('show_title'), 
 151             'season_id': season_id
, 
 152             'season_number': video_data
.get('season_number'), 
 153             'episode_id': str_or_none(video_data
.get('id')), 
 154             'episode_number': int_or_none(video_data
.get('number')), 
 155             'episode_title': video_data
['title'], 
 156             'view_count': int_or_none(video_data
.get('views')), 
 157             'like_count': int_or_none(video_data
.get('video_likes')),