]>
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         # video_type == 'video/rcs' 
  27         'url': 'https://www.vvvvid.it/#!show/376/death-note-live-action/377/482493/episodio-01', 
  28         'md5': '33e0edfba720ad73a8782157fdebc648', 
  32             'title': 'Episodio 01', 
  37     def _real_initialize(self
): 
  38         self
._conn
_id 
= self
._download
_json
( 
  39             'https://www.vvvvid.it/user/login', 
  40             None, headers
=self
.geo_verification_headers())['data']['conn_id'] 
  42     def _real_extract(self
, url
): 
  43         show_id
, season_id
, video_id 
= re
.match(self
._VALID
_URL
, url
).groups() 
  44         response 
= self
._download
_json
( 
  45             'https://www.vvvvid.it/vvvvid/ondemand/%s/season/%s' % (show_id
, season_id
), 
  46             video_id
, headers
=self
.geo_verification_headers(), query
={ 
  47                 'conn_id': self
._conn
_id
, 
  49         if response
['result'] == 'error': 
  50             raise ExtractorError('%s said: %s' % ( 
  51                 self
.IE_NAME
, response
['message']), expected
=True) 
  54         video_data 
= list(filter( 
  55             lambda episode
: episode
.get('video_id') == vid
, response
['data']))[0] 
  58         # vvvvid embed_info decryption algorithm is reverse engineered from function $ds(h) at vvvvid.js 
  60             g 
= "MNOPIJKL89+/4567UVWXQRSTEFGHABCDcdefYZabstuvopqr0123wxyzklmnghij" 
  67                 while ((not b
) and o 
< m_len
): 
  76                             k 
= (m
[o 
- 1] << 4) & 255 
  80                                 j 
= (m
[o 
- 1] << 6) & 255 
 101             for e 
in range(c_len 
* 2 - 1, -1, -1): 
 102                 a 
= c
[e 
% c_len
] ^ c
[(e 
+ 1) % c_len
] 
 112         for quality 
in ('_sd', ''): 
 113             embed_code 
= video_data
.get('embed_info' + quality
) 
 116             embed_code 
= ds(embed_code
) 
 117             video_type 
= video_data
.get('video_type') 
 118             if video_type 
in ('video/rcs', 'video/kenc'): 
 119                 formats
.extend(self
._extract
_akamai
_formats
( 
 120                     embed_code
, video_id
)) 
 122                 formats
.extend(self
._extract
_wowza
_formats
( 
 123                     'http://sb.top-ix.org/videomg/_definst_/mp4:%s/playlist.m3u8' % embed_code
, video_id
)) 
 124         self
._sort
_formats
(formats
) 
 128             'title': video_data
['title'], 
 130             'thumbnail': video_data
.get('thumbnail'), 
 131             'duration': int_or_none(video_data
.get('length')), 
 132             'series': video_data
.get('show_title'), 
 133             'season_id': season_id
, 
 134             'season_number': video_data
.get('season_number'), 
 135             'episode_id': str_or_none(video_data
.get('id')), 
 136             'episode_number': int_or_none(video_data
.get('number')), 
 137             'episode_title': video_data
['title'], 
 138             'view_count': int_or_none(video_data
.get('views')), 
 139             'like_count': int_or_none(video_data
.get('video_likes')),