diff options
-rw-r--r-- | yt_dlp_plugins/extractor/radiko.py | 81 |
1 files changed, 63 insertions, 18 deletions
diff --git a/yt_dlp_plugins/extractor/radiko.py b/yt_dlp_plugins/extractor/radiko.py index 8ab8cad..920da6e 100644 --- a/yt_dlp_plugins/extractor/radiko.py +++ b/yt_dlp_plugins/extractor/radiko.py @@ -390,6 +390,8 @@ class _RadikoBaseIE(InfoExtractor): _APP_VERSIONS = ["7.5.0", "7.4.17", "7.4.16", "7.4.15", "7.4.14", "7.4.13", "7.4.12", "7.4.11", "7.4.10", "7.4.9", "7.4.8", "7.4.7", "7.4.6", "7.4.5", "7.4.4", "7.4.3", "7.4.2", "7.4.1", "7.4.0", "7.3.8", "7.3.7", "7.3.6", "7.3.1", "7.3.0", "7.2.11", "7.2.10"] + _STREAM_ONDEMAND = ("https://radiko.jp/v2/api/ts/playlist.m3u8") + _region = None _user = None @@ -528,6 +530,47 @@ class _RadikoBaseIE(InfoExtractor): self.to_screen(f"{station_id}: Using cached station metadata") return cachedata.get("meta") + def _generate_m3u8s(self, url, station, is_timefree, is_as_live, start_at=None, end_at=None): + playlist_url = update_url_query(url, { + "station_id": station, + "l": "15", # l = length, ie how many seconds in the live m3u8 (max 300) + "lsid": self._user, + "type": "b", # it is a mystery + }) + if not is_timefree: + return [playlist_url] + + playlist_url = update_url_query(playlist_url, { + "start_at": start_at.timestring(), + "ft": start_at.timestring(), + "end_at": end_at.timestring(), + "to": end_at.timestring(), + }) + + if not is_as_live: + return [playlist_url] + + entries = [] + chunk_length = 300 # max the api allows + + duration = int(end_at.timestamp() - start_at.timestamp()) + full_chunks = duration // chunk_length + print(full_chunks) + remainder_length = duration % chunk_length + + for i in range(full_chunks): + chunk_start = start_at + datetime.timedelta(seconds=chunk_length*i) + chunk_end = chunk_start + datetime.timedelta(seconds=chunk_length) + chunk_url = update_url_query(playlist_url, { + "start_at": chunk_start.timestring(), + "ft": chunk_start.timestring(), + "end_at": chunk_end.timestring(), + "to": chunk_end.timestring(), + }) + entries.append(chunk_url) + return entries + + def _get_station_formats(self, station, timefree, auth_data, start_at=None, end_at=None): device = self._configuration_arg('device', ['aSmartPhone7a'], casesense=True)[0] # aSmartPhone7a formats = always happy path url_data = self._download_xml(f"https://radiko.jp/v3/station/stream/{device}/{station}.xml", @@ -542,25 +585,26 @@ class _RadikoBaseIE(InfoExtractor): url = element.text if url in seen_urls: # there are always dupes, even with ^ specific filtering continue + print(url) + is_as_live = url not in self._STREAM_ONDEMAND seen_urls.append(url) - playlist_url = update_url_query(url, { - "station_id": station, - "l": "15", # l = length, ie how many seconds in the live m3u8 (max 300) - "lsid": self._user, - "type": "b", # it is a mystery - }) - if timefree: - playlist_url = update_url_query(playlist_url, { - "start_at": start_at.timestring(), - "ft": start_at.timestring(), - "end_at": end_at.timestring(), - "to": end_at.timestring(), - }) - domain = urllib.parse.urlparse(playlist_url).netloc - formats += self._extract_m3u8_formats( - playlist_url, station, m3u8_id=domain, fatal=False, headers=auth_data, - note=f"Downloading m3u8 information from {domain}") + domain = urllib.parse.urlparse(url).netloc + + preference = -1 + if is_as_live: + preference = 1 + + playlist_urls = self._generate_m3u8s(url, station, timefree, is_as_live, + start_at=start_at, end_at=end_at) + + entries = [] + for pl in playlist_urls: + entries.append(self._extract_m3u8_formats( + pl, station, m3u8_id=domain, fatal=False, headers=auth_data, + note=f"Downloading m3u8 information from {domain}", preference=preference)) + print(entries) + formats.append(entries) return formats @@ -817,7 +861,8 @@ class RadikoTimeFreeIE(_RadikoBaseIE): "alt_title": None, **meta, "chapters": chapters, - "formats": formats, + "_type": "multi_video", + "entries": formats, "live_status": live_status, "container": "m4a_dash", # force fixup, AAC-only HLS } |