From f277f1852dfe3f81005e1fbbefbefd5633174811 Mon Sep 17 00:00:00 2001 From: Izra Date: Thu, 5 Jun 2025 00:39:43 +0900 Subject: [PATCH 1/2] [ie/asobistage] Extract special videos --- yt_dlp/extractor/asobistage.py | 53 +++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/yt_dlp/extractor/asobistage.py b/yt_dlp/extractor/asobistage.py index 0437908bf..cab80675b 100644 --- a/yt_dlp/extractor/asobistage.py +++ b/yt_dlp/extractor/asobistage.py @@ -7,7 +7,7 @@ class AsobiStageIE(InfoExtractor): IE_DESC = 'ASOBISTAGE (アソビステージ)' - _VALID_URL = r'https?://asobistage\.asobistore\.jp/event/(?P(?P\w+)/(?Parchive|player)/(?P\w+))(?:[?#]|$)' + _VALID_URL = r'https?://asobistage\.asobistore\.jp/event/(?P(?P\w+)/(?Parchive|player|premium_lp)/(?P\w+))(?:[?#]|$)' _TESTS = [{ 'url': 'https://asobistage.asobistore.jp/event/315passionhour_2022summer/archive/frame', 'info_dict': { @@ -51,10 +51,20 @@ class AsobiStageIE(InfoExtractor): }, { 'url': 'https://asobistage.asobistore.jp/event/ijigenfes_utagassen/player/day1', 'only_matching': True, + }, { + 'url': 'https://asobistage.asobistore.jp/event/gakuen_1stperiod/premium_lp/ss_premium', + 'info_dict': { + 'id': 'gakuen_1stperiod/premium_lp/ss_premium', + 'title': '学園アイドルマスター The 1st Period Spotlight Star DAY1スペシャル視聴チケット特典', + }, + 'playlist_count': 2, }] _API_HOST = 'https://asobistage-api.asobistore.jp' _HEADERS = {} + _EMBED_HEADERS = { + 'Referer': 'https://asobistage.asobistore.jp/', + } _is_logged_in = False @functools.cached_property @@ -103,6 +113,10 @@ def _real_initialize(self): def _real_extract(self, url): webpage, urlh = self._download_webpage_handle(url, self._match_id(url)) video_id, event, type_, slug = self._match_valid_url(urlh.url).group('id', 'event', 'type', 'slug') + + if type_ == 'premium_lp': + return self._extract_premium_lp(video_id, event, slug) + video_type = {'archive': 'archives', 'player': 'broadcasts'}[type_] event_data = traverse_obj( @@ -153,3 +167,40 @@ def _real_extract(self, url): self.raise_login_required() return self.playlist_result(entries, video_id, **event_data) + + def _extract_premium_lp(self, video_id, event, slug): + contents = traverse_obj(self._download_json( + f'https://asobistage.asobistore.jp/cdn/v101/events/{event}/premium_lp.json', + video_id, 'Getting content list', 'Unable to get content list'), ( + 'contents', lambda _, v: v['premium_lp_slug'] == slug)) + if not contents: + self.report_warning(f'No content found for event "{event}"') + return None + + root_content = contents[0] + event_data = { + 'title': root_content.get('title'), + } + + entries = [] + for content in traverse_obj(root_content, ('contentList', ..., 'contents', ...)): + movie_url = content.get('movieUrl') + embed_id = movie_url.rsplit('/', 1)[-1] + webpage = self._download_webpage( + movie_url, embed_id, + 'Getting movie embed page', 'Failed to get movie embed page', + headers=self._EMBED_HEADERS) + m3u8_url = self._search_regex(r" Date: Fri, 6 Jun 2025 11:37:07 +0900 Subject: [PATCH 2/2] [ie/asobistage] Use get_by_cuid instead of webpage --- yt_dlp/extractor/asobistage.py | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/yt_dlp/extractor/asobistage.py b/yt_dlp/extractor/asobistage.py index cab80675b..36b9177c3 100644 --- a/yt_dlp/extractor/asobistage.py +++ b/yt_dlp/extractor/asobistage.py @@ -62,9 +62,6 @@ class AsobiStageIE(InfoExtractor): _API_HOST = 'https://asobistage-api.asobistore.jp' _HEADERS = {} - _EMBED_HEADERS = { - 'Referer': 'https://asobistage.asobistore.jp/', - } _is_logged_in = False @functools.cached_property @@ -185,19 +182,23 @@ def _extract_premium_lp(self, video_id, event, slug): entries = [] for content in traverse_obj(root_content, ('contentList', ..., 'contents', ...)): movie_url = content.get('movieUrl') - embed_id = movie_url.rsplit('/', 1)[-1] - webpage = self._download_webpage( - movie_url, embed_id, - 'Getting movie embed page', 'Failed to get movie embed page', - headers=self._EMBED_HEADERS) - m3u8_url = self._search_regex(r"