]>
Raphaƫl G. Git Repositories - youtubedl/blob - youtube_dl/extractor/tvnow.py
e2169f2bce30a3bc42fcb422bd6978dda0175f3b
2 from __future__
import unicode_literals
6 from .common
import InfoExtractor
7 from ..compat
import compat_str
16 class TVNowBaseIE(InfoExtractor
):
18 'id', 'title', 'free', 'geoblocked', 'articleLong', 'articleShort',
19 'broadcastStartDate', 'isDrm', 'duration', 'manifest.dashclear',
20 'format.defaultImage169Format', 'format.defaultImage169Logo')
22 def _call_api(self
, path
, video_id
, query
):
23 return self
._download
_json
(
24 'https://api.tvnow.de/v3/' + path
,
25 video_id
, query
=query
)
27 def _extract_video(self
, info
, display_id
):
28 video_id
= compat_str(info
['id'])
31 mpd_url
= info
['manifest']['dashclear']
35 'Video %s is DRM protected' % video_id
, expected
=True)
36 if info
.get('geoblocked'):
38 'Video %s is not available from your location due to geo restriction' % video_id
,
40 if not info
.get('free', True):
42 'Video %s is not available for free' % video_id
, expected
=True)
44 mpd_url
= update_url_query(mpd_url
, {'filter': ''})
45 formats
= self
._extract
_mpd
_formats
(mpd_url
, video_id
, mpd_id
='dash', fatal
=False)
46 formats
.extend(self
._extract
_ism
_formats
(
47 mpd_url
.replace('dash.', 'hss.').replace('/.mpd', '/Manifest'),
48 video_id
, ism_id
='mss', fatal
=False))
49 formats
.extend(self
._extract
_m
3u8_formats
(
50 mpd_url
.replace('dash.', 'hls.').replace('/.mpd', '/.m3u8'),
51 video_id
, 'mp4', 'm3u8_native', m3u8_id
='hls', fatal
=False))
52 self
._sort
_formats
(formats
)
54 description
= info
.get('articleLong') or info
.get('articleShort')
55 timestamp
= parse_iso8601(info
.get('broadcastStartDate'), ' ')
56 duration
= parse_duration(info
.get('duration'))
58 f
= info
.get('format', {})
59 thumbnail
= f
.get('defaultImage169Format') or f
.get('defaultImage169Logo')
63 'display_id': display_id
,
65 'description': description
,
66 'thumbnail': thumbnail
,
67 'timestamp': timestamp
,
73 class TVNowIE(TVNowBaseIE
):
74 _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)'
78 'url': 'https://www.tvnow.de/rtl/alarm-fuer-cobra-11/freier-fall/player?return=/rtl',
81 'display_id': 'alarm-fuer-cobra-11/freier-fall',
83 'title': 'Freier Fall',
84 'description': 'md5:8c2d8f727261adf7e0dc18366124ca02',
85 'thumbnail': r
're:^https?://.*\.jpg$',
86 'timestamp': 1512677700,
87 'upload_date': '20171207',
92 'url': 'https://www.tvnow.de/rtl2/armes-deutschland/episode-0008/player',
93 'only_matching': 'True',
96 'url': 'https://www.tvnow.de/nitro/alarm-fuer-cobra-11-die-autobahnpolizei/auf-eigene-faust-pilot/player',
97 'only_matching': 'True',
100 'url': 'https://www.tvnow.de/superrtl/die-lustigsten-schlamassel-der-welt/u-a-ketchup-effekt/player',
101 'only_matching': 'True',
104 'url': 'https://www.tvnow.de/ntv/startup-news/goetter-in-weiss/player',
105 'only_matching': 'True',
108 'url': 'https://www.tvnow.de/vox/auto-mobil/neues-vom-automobilmarkt-2017-11-19-17-00-00/player',
109 'only_matching': 'True',
112 'url': 'https://www.tvnow.de/rtlplus/op-ruft-dr-bruckner/die-vernaehte-frau/player',
113 'only_matching': 'True',
116 def _real_extract(self
, url
):
117 display_id
= '%s/%s' % re
.match(self
._VALID
_URL
, url
).groups()
119 info
= self
._call
_api
(
120 'movies/' + display_id
, display_id
, query
={
121 'fields': ','.join(self
._VIDEO
_FIELDS
),
124 return self
._extract
_video
(info
, display_id
)
127 class TVNowListIE(TVNowBaseIE
):
128 _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>[^?/#&]+)$'
130 _SHOW_FIELDS
= ('title', )
131 _SEASON_FIELDS
= ('id', 'headline', 'seoheadline', )
132 _VIDEO_FIELDS
= ('id', 'headline', 'seoUrl', )
135 'url': 'https://www.tvnow.de/rtl/30-minuten-deutschland/list/aktuell',
138 'title': '30 Minuten Deutschland - Aktuell',
140 'playlist_mincount': 1,
143 def _real_extract(self
, url
):
144 base_url
, show_id
, season_id
= re
.match(self
._VALID
_URL
, url
).groups()
147 fields
.extend(self
._SHOW
_FIELDS
)
148 fields
.extend('formatTabs.%s' % field
for field
in self
._SEASON
_FIELDS
)
150 'formatTabs.formatTabPages.container.movies.%s' % field
151 for field
in self
._VIDEO
_FIELDS
)
153 list_info
= self
._call
_api
(
154 'formats/seo', season_id
, query
={
155 'fields': ','.join(fields
),
156 'name': show_id
+ '.php'
160 season
for season
in list_info
['formatTabs']['items']
161 if season
.get('seoheadline') == season_id
)
163 title
= '%s - %s' % (list_info
['title'], season
['headline'])
166 for container
in season
['formatTabPages']['items']:
167 for info
in ((container
.get('container') or {}).get('movies') or {}).get('items') or []:
168 seo_url
= info
.get('seoUrl')
171 entries
.append(self
.url_result(
172 base_url
+ seo_url
+ '/player', 'TVNow', info
.get('id')))
174 return self
.playlist_result(
175 entries
, compat_str(season
.get('id') or season_id
), title
)