]>
jfr.im git - yt-dlp.git/blob - yt_dlp/extractor/rtbf.py
3 from .common
import InfoExtractor
12 class RTBFIE(InfoExtractor
):
14 https?://(?:www\.)?rtbf\.be/
17 ouftivi/(?:[^/]+/)*[^?]+\?.*\bvideoId=|
18 auvio/[^/]+\?.*\b(?P<live>l)?id=
21 'url': 'https://www.rtbf.be/video/detail_les-diables-au-coeur-episode-2?id=1921274',
22 'md5': '8c876a1cceeb6cf31b476461ade72384',
26 'title': 'Les Diables au coeur (épisode 2)',
27 'description': '(du 25/04/2014)',
29 'upload_date': '20140425',
30 'timestamp': 1398456300,
34 'url': 'http://www.rtbf.be/ouftivi/heros/detail_scooby-doo-mysteres-associes?id=1097&videoId=2057442',
35 'only_matching': True,
37 'url': 'http://www.rtbf.be/ouftivi/niouzz?videoId=2055858',
38 'only_matching': True,
40 'url': 'http://www.rtbf.be/auvio/detail_jeudi-en-prime-siegfried-bracke?id=2102996',
41 'only_matching': True,
44 'url': 'https://www.rtbf.be/auvio/direct_pure-fm?lid=134775',
45 'only_matching': True,
48 'url': 'https://www.rtbf.be/auvio/detail_cinq-heures-cinema?id=2360811',
49 'only_matching': True,
52 'url': 'https://www.rtbf.be/auvio/detail_les-carnets-du-bourlingueur?id=2361588',
53 'only_matching': True,
55 _IMAGE_HOST
= 'http://ds1.ds.static.rtbf.be'
58 'DAILYMOTION': 'Dailymotion',
67 def _real_extract(self
, url
):
68 live
, media_id
= self
._match
_valid
_url
(url
).groups()
69 embed_page
= self
._download
_webpage
(
70 'https://www.rtbf.be/auvio/embed/' + ('direct' if live
else 'media'),
71 media_id
, query
={'id': media_id}
)
72 data
= self
._parse
_json
(self
._html
_search
_regex
(
73 r
'data-media="([^"]+)"', embed_page
, 'media data'), media_id
)
75 error
= data
.get('error')
77 raise ExtractorError('%s said: %s' % (self
.IE_NAME
, error
), expected
=True)
79 provider
= data
.get('provider')
80 if provider
in self
._PROVIDERS
:
81 return self
.url_result(data
['url'], self
._PROVIDERS
[provider
])
84 is_live
= data
.get('isLive')
85 height_re
= r
'-(\d+)p\.'
88 m3u8_url
= data
.get('urlHlsAes128') or data
.get('urlHls')
90 formats
.extend(self
._extract
_m
3u8_formats
(
91 m3u8_url
, media_id
, 'mp4', m3u8_id
='hls', fatal
=False))
93 fix_url
= lambda x
: x
.replace('//rtbf-vod.', '//rtbf.') if '/geo/drm/' in x
else x
94 http_url
= data
.get('url')
95 if formats
and http_url
and re
.search(height_re
, http_url
):
96 http_url
= fix_url(http_url
)
97 for m3u8_f
in formats
[:]:
98 height
= m3u8_f
.get('height')
104 'format_id': m3u8_f
['format_id'].replace('hls-', 'http-'),
105 'url': re
.sub(height_re
, '-%dp.' % height
, http_url
),
109 sources
= data
.get('sources') or {}
110 for key
, format_id
in self
._QUALITIES
:
111 format_url
= sources
.get(key
)
114 height
= int_or_none(self
._search
_regex
(
115 height_re
, format_url
, 'height', default
=None))
117 'format_id': format_id
,
118 'url': fix_url(format_url
),
122 mpd_url
= data
.get('urlDash')
123 if mpd_url
and (self
.get_param('allow_unplayable_formats') or not data
.get('drm')):
124 formats
.extend(self
._extract
_mpd
_formats
(
125 mpd_url
, media_id
, mpd_id
='dash', fatal
=False))
127 audio_url
= data
.get('urlAudio')
130 'format_id': 'audio',
134 self
._sort
_formats
(formats
)
137 for track
in (data
.get('tracks') or {}).values():
138 sub_url
= track
.get('url')
141 subtitles
.setdefault(track
.get('lang') or 'fr', []).append({
149 'description': strip_or_none(data
.get('description')),
150 'thumbnail': data
.get('thumbnail'),
151 'duration': float_or_none(data
.get('realDuration')),
152 'timestamp': int_or_none(data
.get('liveFrom')),
153 'series': data
.get('programLabel'),
154 'subtitles': subtitles
,