]>
Raphaël G. Git Repositories - youtubedl/blob - youtube_dl/extractor/dplay.py
   2 from __future__ 
import unicode_literals
 
   6 from .common 
import InfoExtractor
 
   7 from ..compat 
import compat_HTTPError
 
  17 class DPlayIE(InfoExtractor
): 
  18     _VALID_URL 
= r
'''(?x)https?:// 
  20             (?:www\.)?(?P<host>dplay\.(?P<country>dk|fi|jp|se|no))| 
  21             (?P<subdomain_country>es|it)\.dplay\.com 
  22         )/[^/]+/(?P<id>[^/]+/[^/?#]+)''' 
  25         # non geo restricted, via secure api, unsigned download hls URL 
  26         'url': 'https://www.dplay.se/videos/nugammalt-77-handelser-som-format-sverige/nugammalt-77-handelser-som-format-sverige-101', 
  29             'display_id': 'nugammalt-77-handelser-som-format-sverige/nugammalt-77-handelser-som-format-sverige-101', 
  31             'title': 'Svensken lär sig njuta av livet', 
  32             'description': 'md5:d3819c9bccffd0fe458ca42451dd50d8', 
  34             'timestamp': 1365453720, 
  35             'upload_date': '20130408', 
  37             'series': 'Nugammalt - 77 händelser som format Sverige', 
  42             'format': 'bestvideo', 
  43             'skip_download': True, 
  46         # geo restricted, via secure api, unsigned download hls URL 
  47         'url': 'http://www.dplay.dk/videoer/ted-bundy-mind-of-a-monster/ted-bundy-mind-of-a-monster', 
  50             'display_id': 'ted-bundy-mind-of-a-monster/ted-bundy-mind-of-a-monster', 
  52             'title': 'Ted Bundy: Mind Of A Monster', 
  53             'description': 'md5:8b780f6f18de4dae631668b8a9637995', 
  55             'timestamp': 1570694400, 
  56             'upload_date': '20191010', 
  57             'creator': 'ID - Investigation Discovery', 
  58             'series': 'Ted Bundy: Mind Of A Monster', 
  63             'format': 'bestvideo', 
  64             'skip_download': True, 
  68         'url': 'https://www.dplay.no/videoer/i-kongens-klr/sesong-1-episode-7', 
  71             'display_id': 'i-kongens-klr/sesong-1-episode-7', 
  74             'description': 'md5:e3e1411b2b9aebeea36a6ec5d50c60cf', 
  76             'timestamp': 1516726800, 
  77             'upload_date': '20180123', 
  78             'series': 'I kongens klær', 
  83             'format': 'bestvideo', 
  84             'skip_download': True, 
  86         'skip': 'Available for Premium users', 
  88         'url': 'http://it.dplay.com/nove/biografie-imbarazzanti/luigi-di-maio-la-psicosi-di-stanislawskij/', 
  89         'md5': '2b808ffb00fc47b884a172ca5d13053c', 
  92             'display_id': 'biografie-imbarazzanti/luigi-di-maio-la-psicosi-di-stanislawskij', 
  94             'title': 'Luigi Di Maio: la psicosi di Stanislawskij', 
  95             'description': 'md5:3c7a4303aef85868f867a26f5cc14813', 
  96             'thumbnail': r
're:^https?://.*\.jpe?g', 
  97             'upload_date': '20160524', 
  98             'timestamp': 1464076800, 
  99             'series': 'Biografie imbarazzanti', 
 101             'episode': 'Episode 1', 
 105         'url': 'https://es.dplay.com/dmax/la-fiebre-del-oro/temporada-8-episodio-1/', 
 108             'display_id': 'la-fiebre-del-oro/temporada-8-episodio-1', 
 110             'title': 'Episodio 1', 
 111             'description': 'md5:b9dcff2071086e003737485210675f69', 
 112             'thumbnail': r
're:^https?://.*\.png', 
 113             'upload_date': '20180709', 
 114             'timestamp': 1531173540, 
 115             'series': 'La fiebre del oro', 
 117             'episode': 'Episode 1', 
 121             'skip_download': True, 
 124         'url': 'https://www.dplay.fi/videot/shifting-gears-with-aaron-kaufman/episode-16', 
 125         'only_matching': True, 
 127         'url': 'https://www.dplay.jp/video/gold-rush/24086', 
 128         'only_matching': True, 
 131     def _get_disco_api_info(self
, url
, display_id
, disco_host
, realm
, country
): 
 132         geo_countries 
= [country
.upper()] 
 133         self
._initialize
_geo
_bypass
({ 
 134             'countries': geo_countries
, 
 136         disco_base 
= 'https://%s/' % disco_host
 
 137         token 
= self
._download
_json
( 
 138             disco_base 
+ 'token', display_id
, 'Downloading token', 
 141             })['data']['attributes']['token'] 
 144             'Authorization': 'Bearer ' + token
, 
 146         video 
= self
._download
_json
( 
 147             disco_base 
+ 'content/videos/' + display_id
, display_id
, 
 148             headers
=headers
, query
={ 
 149                 'fields[channel]': 'name', 
 150                 'fields[image]': 'height,src,width', 
 151                 'fields[show]': 'name', 
 152                 'fields[tag]': 'name', 
 153                 'fields[video]': 'description,episodeNumber,name,publishStart,seasonNumber,videoDuration', 
 154                 'include': 'images,primaryChannel,show,tags' 
 156         video_id 
= video
['data']['id'] 
 157         info 
= video
['data']['attributes'] 
 158         title 
= info
['name'].strip() 
 161             streaming 
= self
._download
_json
( 
 162                 disco_base 
+ 'playback/videoPlaybackInfo/' + video_id
, 
 163                 display_id
, headers
=headers
)['data']['attributes']['streaming'] 
 164         except ExtractorError 
as e
: 
 165             if isinstance(e
.cause
, compat_HTTPError
) and e
.cause
.code 
== 403: 
 166                 info 
= self
._parse
_json
(e
.cause
.read().decode('utf-8'), display_id
) 
 167                 error 
= info
['errors'][0] 
 168                 error_code 
= error
.get('code') 
 169                 if error_code 
== 'access.denied.geoblocked': 
 170                     self
.raise_geo_restricted(countries
=geo_countries
) 
 171                 elif error_code 
== 'access.denied.missingpackage': 
 172                     self
.raise_login_required() 
 173                 raise ExtractorError(info
['errors'][0]['detail'], expected
=True) 
 175         for format_id
, format_dict 
in streaming
.items(): 
 176             if not isinstance(format_dict
, dict): 
 178             format_url 
= format_dict
.get('url') 
 181             ext 
= determine_ext(format_url
) 
 182             if format_id 
== 'dash' or ext 
== 'mpd': 
 183                 formats
.extend(self
._extract
_mpd
_formats
( 
 184                     format_url
, display_id
, mpd_id
='dash', fatal
=False)) 
 185             elif format_id 
== 'hls' or ext 
== 'm3u8': 
 186                 formats
.extend(self
._extract
_m
3u8_formats
( 
 187                     format_url
, display_id
, 'mp4', 
 188                     entry_protocol
='m3u8_native', m3u8_id
='hls', 
 193                     'format_id': format_id
, 
 195         self
._sort
_formats
(formats
) 
 197         creator 
= series 
= None 
 200         included 
= video
.get('included') or [] 
 201         if isinstance(included
, list): 
 203                 attributes 
= e
.get('attributes') 
 206                 e_type 
= e
.get('type') 
 207                 if e_type 
== 'channel': 
 208                     creator 
= attributes
.get('name') 
 209                 elif e_type 
== 'image': 
 210                     src 
= attributes
.get('src') 
 214                             'width': int_or_none(attributes
.get('width')), 
 215                             'height': int_or_none(attributes
.get('height')), 
 218                     series 
= attributes
.get('name') 
 219                 elif e_type 
== 'tag': 
 220                     name 
= attributes
.get('name') 
 226             'display_id': display_id
, 
 228             'description': info
.get('description'), 
 229             'duration': float_or_none(info
.get('videoDuration'), 1000), 
 230             'timestamp': unified_timestamp(info
.get('publishStart')), 
 232             'season_number': int_or_none(info
.get('seasonNumber')), 
 233             'episode_number': int_or_none(info
.get('episodeNumber')), 
 236             'thumbnails': thumbnails
, 
 240     def _real_extract(self
, url
): 
 241         mobj 
= re
.match(self
._VALID
_URL
, url
) 
 242         display_id 
= mobj
.group('id') 
 243         domain 
= mobj
.group('domain').lstrip('www.') 
 244         country 
= mobj
.group('country') or mobj
.group('subdomain_country') 
 245         host 
= 'disco-api.' + domain 
if domain
.startswith('dplay.') else 'eu2-prod.disco-api.com' 
 246         return self
._get
_disco
_api
_info
( 
 247             url
, display_id
, host
, 'dplay' + country
, country
)