From 349b87f563daf9084e2097bc1afc62731c0a6c97 Mon Sep 17 00:00:00 2001 From: garret1317 Date: Mon, 14 Jul 2025 10:04:09 +0100 Subject: [PATCH 1/3] smuggle track_info in case it's not included on the track page --- yt_dlp/extractor/bandcamp.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/yt_dlp/extractor/bandcamp.py b/yt_dlp/extractor/bandcamp.py index 939c2800e6..da838338eb 100644 --- a/yt_dlp/extractor/bandcamp.py +++ b/yt_dlp/extractor/bandcamp.py @@ -11,10 +11,12 @@ float_or_none, int_or_none, parse_filesize, + smuggle_url, str_or_none, try_get, unified_strdate, unified_timestamp, + unsmuggle_url, update_url_query, url_or_none, urljoin, @@ -127,6 +129,8 @@ def _extract_data_attr(self, webpage, video_id, attr='tralbum', fatal=True): attr + ' data', group=2), video_id, fatal=fatal) def _real_extract(self, url): + url, smuggled_track_info = unsmuggle_url(url, None) + title, uploader = self._match_valid_url(url).group('id', 'uploader') webpage = self._download_webpage(url, title) tralbum = self._extract_data_attr(webpage, title) @@ -138,7 +142,7 @@ def _real_extract(self, url): duration = None formats = [] - track_info = try_get(tralbum, lambda x: x['trackinfo'][0], dict) + track_info = try_get(tralbum, lambda x: x['trackinfo'][0], dict) or smuggled_track_info if track_info: file_ = track_info.get('file') if isinstance(file_, dict): @@ -366,7 +370,7 @@ def _real_extract(self, url): # Only tracks with duration info have songs entries = [ self.url_result( - urljoin(url, t['title_link']), BandcampIE.ie_key(), + smuggle_url(urljoin(url, t['title_link']), t), BandcampIE.ie_key(), str_or_none(t.get('track_id') or t.get('id')), t.get('title')) for t in track_info if t.get('duration')] From e0c545b14526c07392f222f6571802c7cfd61fc4 Mon Sep 17 00:00:00 2001 From: garret1317 Date: Mon, 14 Jul 2025 14:45:30 +0100 Subject: [PATCH 2/3] only smuggle when track has track_license_id set --- yt_dlp/extractor/bandcamp.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/yt_dlp/extractor/bandcamp.py b/yt_dlp/extractor/bandcamp.py index da838338eb..32190c19a6 100644 --- a/yt_dlp/extractor/bandcamp.py +++ b/yt_dlp/extractor/bandcamp.py @@ -368,12 +368,17 @@ def _real_extract(self, url): if not track_info: raise ExtractorError('The page doesn\'t contain any tracks') # Only tracks with duration info have songs - entries = [ - self.url_result( - smuggle_url(urljoin(url, t['title_link']), t), BandcampIE.ie_key(), - str_or_none(t.get('track_id') or t.get('id')), t.get('title')) - for t in track_info - if t.get('duration')] + entries = [] + for t in track_info: + if t.get('duration'): + url = urljoin(url, t['title_link']) + if t.get('track_license_id'): + # tracks with this set don't have a usable tralbum on their pages + url = smuggle_url(url, t) + entries.append(self.url_result( + url, BandcampIE.ie_key(), + str_or_none(t.get('track_id') or t.get('id')), t.get('title'), + )) current = tralbum.get('current') or {} From ace97a88fa889eb0118d6a73bfaa4eb249928e1e Mon Sep 17 00:00:00 2001 From: garret1317 Date: Mon, 14 Jul 2025 14:48:43 +0100 Subject: [PATCH 3/3] add tests for album that requires smuggling --- yt_dlp/extractor/bandcamp.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/yt_dlp/extractor/bandcamp.py b/yt_dlp/extractor/bandcamp.py index 32190c19a6..4b11cc93a2 100644 --- a/yt_dlp/extractor/bandcamp.py +++ b/yt_dlp/extractor/bandcamp.py @@ -351,6 +351,15 @@ class BandcampAlbumIE(BandcampIE): # XXX: Do not subclass from concrete IE 'description': 'md5:b3cf845ee41b2b1141dc7bde9237255f', }, 'playlist_count': 2, + }, { + # tracks need track_info smuggled because they don't have a usable one on the pages + 'url': 'https://wetleg.bandcamp.com/album/wet-leg', + 'info_dict': { + 'id': 'wet-leg', + 'title': 'Wet Leg', + 'uploader_id': 'wetleg', + }, + 'playlist_count': 12, }] @classmethod