3 from .common
import InfoExtractor
18 class BibelTVBaseIE(InfoExtractor
):
19 _GEO_COUNTRIES
= ['AT', 'CH', 'DE']
22 API_URL
= 'https://www.bibeltv.de/mediathek/api'
23 AUTH_TOKEN
= 'j88bRXY8DsEqJ9xmTdWhrByVi5Hm'
25 def _extract_formats_and_subtitles(self
, data
, crn_id
, *, is_live
=False):
28 for media_url
in traverse_obj(data
, (..., 'src', {url_or_none}
)):
29 media_ext
= determine_ext(media_url
)
30 if media_ext
== 'm3u8':
31 m3u8_formats
, m3u8_subs
= self
._extract
_m
3u8_formats
_and
_subtitles
(
32 media_url
, crn_id
, live
=is_live
)
33 formats
.extend(m3u8_formats
)
34 subtitles
.update(m3u8_subs
)
35 elif media_ext
== 'mpd':
36 mpd_formats
, mpd_subs
= self
._extract
_mpd
_formats
_and
_subtitles
(media_url
, crn_id
)
37 formats
.extend(mpd_formats
)
38 subtitles
.update(mpd_subs
)
39 elif media_ext
== 'mp4':
40 formats
.append({'url': media_url
})
42 self
.report_warning(f
'Unknown format {media_ext!r}')
44 return formats
, subtitles
47 def _extract_base_info(data
):
50 **traverse_obj(data
, {
52 'description': 'description',
53 'duration': ('duration', {functools
.partial(int_or_none
, scale
=1000)}),
54 'timestamp': ('schedulingStart', {parse_iso8601}
),
55 'season_number': 'seasonNumber',
56 'episode_number': 'episodeNumber',
57 'view_count': 'viewCount',
58 'like_count': 'likeCount',
60 'thumbnails': orderedSet(traverse_obj(data
, ('images', ..., {
61 'url': ('url', {url_or_none}
),
65 def _extract_url_info(self
, data
):
68 'url': format_field(data
, 'slug', 'https://www.bibeltv.de/mediathek/videos/%s'),
69 **self
._extract
_base
_info
(data
),
72 def _extract_video_info(self
, data
):
76 self
.report_drm(crn_id
)
78 json_data
= self
._download
_json
(
79 format_field(data
, 'id', f
'{self.API_URL}/video/%s'), crn_id
,
80 headers
={'Authorization': self
.AUTH_TOKEN
}, fatal
=False,
81 errnote
='No formats available') or {}
83 formats
, subtitles
= self
._extract
_formats
_and
_subtitles
(
84 traverse_obj(json_data
, ('video', 'videoUrls', ...)), crn_id
)
88 **self
._extract
_base
_info
(data
),
90 'subtitles': subtitles
,
94 class BibelTVVideoIE(BibelTVBaseIE
):
95 IE_DESC
= 'BibelTV single video'
96 _VALID_URL
= r
'https?://(?:www\.)?bibeltv\.de/mediathek/videos/(?P<id>\d+)[\w-]+'
97 IE_NAME
= 'bibeltv:video'
100 'url': 'https://www.bibeltv.de/mediathek/videos/344436-alte-wege',
101 'md5': 'ec1c07efe54353780512e8a4103b612e',
105 'title': 'Alte Wege',
106 'description': 'md5:2f4eb7294c9797a47b8fd13cccca22e9',
107 'timestamp': 1677877071,
109 'upload_date': '20230303',
110 'thumbnail': r
're:https://bibeltv\.imgix\.net/[\w-]+\.jpg',
111 'episode': 'Episode 1',
121 def _real_extract(self
, url
):
122 crn_id
= self
._match
_id
(url
)
123 video_data
= traverse_obj(
124 self
._search
_nextjs
_data
(self
._download
_webpage
(url
, crn_id
), crn_id
),
125 ('props', 'pageProps', 'videoPageData', 'videos', 0, {dict}
))
127 raise ExtractorError('Missing video data.')
129 return self
._extract
_video
_info
(video_data
)
132 class BibelTVSeriesIE(BibelTVBaseIE
):
133 IE_DESC
= 'BibelTV series playlist'
134 _VALID_URL
= r
'https?://(?:www\.)?bibeltv\.de/mediathek/serien/(?P<id>\d+)[\w-]+'
135 IE_NAME
= 'bibeltv:series'
138 'url': 'https://www.bibeltv.de/mediathek/serien/333485-ein-wunder-fuer-jeden-tag',
139 'playlist_mincount': 400,
142 'title': 'Ein Wunder für jeden Tag',
143 'description': 'Tägliche Kurzandacht mit Déborah Rosenkranz.',
147 def _real_extract(self
, url
):
148 crn_id
= self
._match
_id
(url
)
149 webpage
= self
._download
_webpage
(url
, crn_id
)
150 nextjs_data
= self
._search
_nextjs
_data
(webpage
, crn_id
)
151 series_data
= traverse_obj(nextjs_data
, ('props', 'pageProps', 'seriePageData', {dict}
))
153 raise ExtractorError('Missing series data.')
155 return self
.playlist_result(
156 traverse_obj(series_data
, ('videos', ..., {dict}
, {self
._extract
_url
_info
})),
157 crn_id
, series_data
.get('title'), clean_html(series_data
.get('description')))
160 class BibelTVLiveIE(BibelTVBaseIE
):
161 IE_DESC
= 'BibelTV live program'
162 _VALID_URL
= r
'https?://(?:www\.)?bibeltv\.de/livestreams/(?P<id>[\w-]+)'
163 IE_NAME
= 'bibeltv:live'
166 'url': 'https://www.bibeltv.de/livestreams/bibeltv/',
170 'title': 're:Bibel TV',
171 'live_status': 'is_live',
172 'thumbnail': 'https://streampreview.bibeltv.de/bibeltv.webp',
174 'params': {'skip_download': 'm3u8'},
176 'url': 'https://www.bibeltv.de/livestreams/impuls/',
177 'only_matching': True,
180 def _real_extract(self
, url
):
181 stream_id
= self
._match
_id
(url
)
182 webpage
= self
._download
_webpage
(url
, stream_id
)
183 stream_data
= self
._search
_json
(
184 r
'\\"video\\":', webpage
, 'bibeltvData', stream_id
,
185 transform_source
=lambda jstring
: js_to_json(jstring
.replace('\\"', '"')))
187 formats
, subtitles
= self
._extract
_formats
_and
_subtitles
(
188 traverse_obj(stream_data
, ('src', ...)), stream_id
, is_live
=True)
192 'title': stream_data
.get('title'),
193 'thumbnail': stream_data
.get('poster'),
196 'subtitles': subtitles
,