]>
Raphaƫl G. Git Repositories - youtubedl/blob - youtube_dl/extractor/tvnow.py
1bf47244440809f154d01b5664f1ffa085e4fb29
2 from __future__
import unicode_literals
6 from .common
import InfoExtractor
7 from ..compat
import compat_str
17 class TVNowBaseIE(InfoExtractor
):
19 'id', 'title', 'free', 'geoblocked', 'articleLong', 'articleShort',
20 'broadcastStartDate', 'isDrm', 'duration', 'season', 'episode',
21 'manifest.dashclear', 'format.title', 'format.defaultImage169Format',
22 'format.defaultImage169Logo')
24 def _call_api(self
, path
, video_id
, query
):
25 return self
._download
_json
(
26 'https://api.tvnow.de/v3/' + path
,
27 video_id
, query
=query
)
29 def _extract_video(self
, info
, display_id
):
30 video_id
= compat_str(info
['id'])
33 mpd_url
= info
['manifest']['dashclear']
37 'Video %s is DRM protected' % video_id
, expected
=True)
38 if info
.get('geoblocked'):
40 'Video %s is not available from your location due to geo restriction' % video_id
,
42 if not info
.get('free', True):
44 'Video %s is not available for free' % video_id
, expected
=True)
46 mpd_url
= update_url_query(mpd_url
, {'filter': ''})
47 formats
= self
._extract
_mpd
_formats
(mpd_url
, video_id
, mpd_id
='dash', fatal
=False)
48 formats
.extend(self
._extract
_ism
_formats
(
49 mpd_url
.replace('dash.', 'hss.').replace('/.mpd', '/Manifest'),
50 video_id
, ism_id
='mss', fatal
=False))
51 formats
.extend(self
._extract
_m
3u8_formats
(
52 mpd_url
.replace('dash.', 'hls.').replace('/.mpd', '/.m3u8'),
53 video_id
, 'mp4', 'm3u8_native', m3u8_id
='hls', fatal
=False))
54 self
._sort
_formats
(formats
)
56 description
= info
.get('articleLong') or info
.get('articleShort')
57 timestamp
= parse_iso8601(info
.get('broadcastStartDate'), ' ')
58 duration
= parse_duration(info
.get('duration'))
60 f
= info
.get('format', {})
61 thumbnail
= f
.get('defaultImage169Format') or f
.get('defaultImage169Logo')
65 'display_id': display_id
,
67 'description': description
,
68 'thumbnail': thumbnail
,
69 'timestamp': timestamp
,
71 'series': f
.get('title'),
72 'season_number': int_or_none(info
.get('season')),
73 'episode_number': int_or_none(info
.get('episode')),
79 class TVNowIE(TVNowBaseIE
):
80 _VALID_URL
= r
'https?://(?:www\.)?tvnow\.(?:de|at|ch)/(?:rtl(?:2|plus)?|nitro|superrtl|ntv|vox)/(?P<show_id>[^/]+)/(?:(?:list/[^/]+|jahr/\d{4}/\d{1,2})/)?(?P<id>[^/]+)/(?:player|preview)'
83 'url': 'https://www.tvnow.de/rtl2/grip-das-motormagazin/der-neue-porsche-911-gt-3/player',
86 'display_id': 'grip-das-motormagazin/der-neue-porsche-911-gt-3',
88 'title': 'Der neue Porsche 911 GT 3',
89 'description': 'md5:6143220c661f9b0aae73b245e5d898bb',
90 'thumbnail': r
're:^https?://.*\.jpg$',
91 'timestamp': 1495994400,
92 'upload_date': '20170528',
94 'series': 'GRIP - Das Motormagazin',
96 'episode_number': 405,
97 'episode': 'Der neue Porsche 911 GT 3',
101 'url': 'https://www.tvnow.de/rtl2/armes-deutschland/episode-0008/player',
102 'only_matching': 'True',
105 'url': 'https://www.tvnow.de/nitro/alarm-fuer-cobra-11-die-autobahnpolizei/auf-eigene-faust-pilot/player',
106 'only_matching': 'True',
109 'url': 'https://www.tvnow.de/superrtl/die-lustigsten-schlamassel-der-welt/u-a-ketchup-effekt/player',
110 'only_matching': 'True',
113 'url': 'https://www.tvnow.de/ntv/startup-news/goetter-in-weiss/player',
114 'only_matching': 'True',
117 'url': 'https://www.tvnow.de/vox/auto-mobil/neues-vom-automobilmarkt-2017-11-19-17-00-00/player',
118 'only_matching': 'True',
121 'url': 'https://www.tvnow.de/rtlplus/op-ruft-dr-bruckner/die-vernaehte-frau/player',
122 'only_matching': 'True',
125 def _real_extract(self
, url
):
126 display_id
= '%s/%s' % re
.match(self
._VALID
_URL
, url
).groups()
128 info
= self
._call
_api
(
129 'movies/' + display_id
, display_id
, query
={
130 'fields': ','.join(self
._VIDEO
_FIELDS
),
133 return self
._extract
_video
(info
, display_id
)
136 class TVNowListIE(TVNowBaseIE
):
137 _VALID_URL
= r
'(?P<base_url>https?://(?:www\.)?tvnow\.(?:de|at|ch)/(?:rtl(?:2|plus)?|nitro|superrtl|ntv|vox)/(?P<show_id>[^/]+)/)list/(?P<id>[^?/#&]+)$'
139 _SHOW_FIELDS
= ('title', )
140 _SEASON_FIELDS
= ('id', 'headline', 'seoheadline', )
141 _VIDEO_FIELDS
= ('id', 'headline', 'seoUrl', )
144 'url': 'https://www.tvnow.de/rtl/30-minuten-deutschland/list/aktuell',
147 'title': '30 Minuten Deutschland - Aktuell',
149 'playlist_mincount': 1,
152 def _real_extract(self
, url
):
153 base_url
, show_id
, season_id
= re
.match(self
._VALID
_URL
, url
).groups()
156 fields
.extend(self
._SHOW
_FIELDS
)
157 fields
.extend('formatTabs.%s' % field
for field
in self
._SEASON
_FIELDS
)
159 'formatTabs.formatTabPages.container.movies.%s' % field
160 for field
in self
._VIDEO
_FIELDS
)
162 list_info
= self
._call
_api
(
163 'formats/seo', season_id
, query
={
164 'fields': ','.join(fields
),
165 'name': show_id
+ '.php'
169 season
for season
in list_info
['formatTabs']['items']
170 if season
.get('seoheadline') == season_id
)
172 title
= '%s - %s' % (list_info
['title'], season
['headline'])
175 for container
in season
['formatTabPages']['items']:
176 for info
in ((container
.get('container') or {}).get('movies') or {}).get('items') or []:
177 seo_url
= info
.get('seoUrl')
180 entries
.append(self
.url_result(
181 base_url
+ seo_url
+ '/player', 'TVNow', info
.get('id')))
183 return self
.playlist_result(
184 entries
, compat_str(season
.get('id') or season_id
), title
)