-# coding: utf-8
-from __future__ import unicode_literals
-
import itertools
import random
import re
from .common import InfoExtractor
-from ..compat import compat_str
+from ..compat import compat_HTTPError, compat_str
from ..utils import (
- determine_ext,
ExtractorError,
+ determine_ext,
int_or_none,
parse_duration,
+ parse_iso8601,
str_or_none,
try_get,
- urljoin,
url_or_none,
+ urljoin,
)
return self._download_json(
urljoin('https://psapi.nrk.no/', path),
video_id, note or 'Downloading %s JSON' % item,
- fatal=fatal, query=query,
- headers={'Accept-Encoding': 'gzip, deflate, br'})
+ fatal=fatal, query=query)
class NRKIE(NRKBaseIE):
def _real_extract(self, url):
video_id = self._match_id(url).split('/')[-1]
- path_templ = 'playback/%s/' + video_id
-
def call_playback_api(item, query=None):
- return self._call_api(path_templ % item, video_id, item, query=query)
+ try:
+ return self._call_api(f'playback/{item}/program/{video_id}', video_id, item, query=query)
+ except ExtractorError as e:
+ if isinstance(e.cause, compat_HTTPError) and e.cause.code == 400:
+ return self._call_api(f'playback/{item}/{video_id}', video_id, item, query=query)
+ raise
+
# known values for preferredCdn: akamai, iponly, minicdn and telenor
manifest = call_playback_api('manifest', {'preferredCdn': 'akamai'})
'format_id': asset_format,
'vcodec': 'none',
})
- self._sort_formats(formats)
data = call_playback_api('metadata')
title = titles['title']
alt_title = titles.get('subtitle')
- description = preplay.get('description')
+ description = try_get(preplay, lambda x: x['description'].replace('\r', '\n'))
duration = parse_duration(playable.get('duration')) or parse_duration(data.get('duration'))
thumbnails = []
'age_limit': age_limit,
'formats': formats,
'subtitles': subtitles,
+ 'timestamp': parse_iso8601(try_get(manifest, lambda x: x['availability']['onDemand']['from'], str))
}
if is_series:
}]
def _real_extract(self, url):
- display_id, season_number, episode_number = re.match(self._VALID_URL, url).groups()
+ display_id, season_number, episode_number = self._match_valid_url(url).groups()
webpage = self._download_webpage(url, display_id)
else super(NRKTVSeasonIE, cls).suitable(url))
def _real_extract(self, url):
- mobj = re.match(self._VALID_URL, url)
+ mobj = self._match_valid_url(url)
domain = mobj.group('domain')
serie_kind = mobj.group('serie_kind')
serie = mobj.group('serie')
else super(NRKTVSeriesIE, cls).suitable(url))
def _real_extract(self, url):
- site, serie_kind, series_id = re.match(self._VALID_URL, url).groups()
+ site, serie_kind, series_id = self._match_valid_url(url).groups()
is_radio = site == 'radio.nrk'
domain = 'radio' if is_radio else 'tv'
entries, series_id, titles.get('title'), titles.get('subtitle'))
-class NRKTVDirekteIE(NRKTVIE):
+class NRKTVDirekteIE(NRKTVIE): # XXX: Do not subclass from concrete IE
IE_DESC = 'NRK TV Direkte and NRK Radio Direkte'
_VALID_URL = r'https?://(?:tv|radio)\.nrk\.no/direkte/(?P<id>[^/?#&]+)'
for video_id in re.findall(self._ITEM_RE, webpage)
]
- playlist_title = self. _extract_title(webpage)
+ playlist_title = self._extract_title(webpage)
playlist_description = self._extract_description(webpage)
return self.playlist_result(