Compare commits

..

No commits in common. "9c32f15b7b1380a30bd3596c11aba2212cadfaa9" and "d8b9fbb521207609051b64218039808a95b013b2" have entirely different histories.

View File

@ -3,38 +3,26 @@ from .common import InfoExtractor
from ..utils import ( from ..utils import (
ExtractorError, ExtractorError,
float_or_none, float_or_none,
format_field,
int_or_none, int_or_none,
parse_iso8601, parse_iso8601,
parse_qs, parse_qs,
truncate_string, truncate_string,
url_or_none, url_or_none,
) )
from ..utils.traversal import traverse_obj, value from ..utils.traversal import traverse_obj
class BandlabBaseIE(InfoExtractor): class BandlabBaseIE(InfoExtractor):
_API_HEADERS = { _API_HEADERS = {
'accept': 'application/json',
'referer': 'https://www.bandlab.com/', 'referer': 'https://www.bandlab.com/',
'x-client-id': 'BandLab-Web', 'x-client-id': 'BandLab-Web',
'x-client-version': '10.1.124', 'x-client-version': '10.1.123',
} }
def _call_api(self, endpoint, asset_id, **kwargs): def _parse_revision(self, revision_data):
return self._download_json(
f'https://www.bandlab.com/api/v1.3/{endpoint}/{asset_id}',
asset_id, headers=self._API_HEADERS, **kwargs)
def _parse_revision(self, revision_data, url=None):
return { return {
'vcodec': 'none', 'vcodec': 'none',
'media_type': 'revision',
'extractor_key': BandlabIE.ie_key(),
'extractor': BandlabIE.IE_NAME,
**traverse_obj(revision_data, { **traverse_obj(revision_data, {
'webpage_url': (
'id', ({value(url)}, {format_field(template='https://www.bandlab.com/revision/%s')}), filter, any),
'id': (('revisionId', 'id'), {str}, any), 'id': (('revisionId', 'id'), {str}, any),
'title': ('song', 'name', {str}), 'title': ('song', 'name', {str}),
'track': ('song', 'name', {str}), 'track': ('song', 'name', {str}),
@ -52,15 +40,10 @@ class BandlabBaseIE(InfoExtractor):
}), }),
} }
def _parse_track(self, track_data, url=None): def _parse_track(self, track_data):
return { return {
'vcodec': 'none', 'vcodec': 'none',
'media_type': 'track',
'extractor_key': BandlabIE.ie_key(),
'extractor': BandlabIE.IE_NAME,
**traverse_obj(track_data, { **traverse_obj(track_data, {
'webpage_url': (
'id', ({value(url)}, {format_field(template='https://www.bandlab.com/post/%s')}), filter, any),
'id': (('revisionId', 'id'), {str}, any), 'id': (('revisionId', 'id'), {str}, any),
'url': ('track', 'sample', 'audioUrl', {url_or_none}), 'url': ('track', 'sample', 'audioUrl', {url_or_none}),
'title': ('track', 'name', {str}), 'title': ('track', 'name', {str}),
@ -77,15 +60,9 @@ class BandlabBaseIE(InfoExtractor):
}), }),
} }
def _parse_video(self, video_data, url=None): def _parse_video(self, video_data):
return { return traverse_obj(video_data, {
'media_type': 'video',
'extractor_key': BandlabIE.ie_key(),
'extractor': BandlabIE.IE_NAME,
**traverse_obj(video_data, {
'id': ('id', {str}), 'id': ('id', {str}),
'webpage_url': (
'id', ({value(url)}, {format_field(template='https://www.bandlab.com/post/%s')}), filter, any),
'url': ('video', 'url', {url_or_none}), 'url': ('video', 'url', {url_or_none}),
'title': ('caption', {lambda x: x.replace('\n', ' ')}, {truncate_string(left=50)}), 'title': ('caption', {lambda x: x.replace('\n', ' ')}, {truncate_string(left=50)}),
'description': ('caption', {str}), 'description': ('caption', {str}),
@ -96,8 +73,7 @@ class BandlabBaseIE(InfoExtractor):
'duration': ('video', 'duration', {float_or_none}), 'duration': ('video', 'duration', {float_or_none}),
'uploader': ('creator', 'name', {str}), 'uploader': ('creator', 'name', {str}),
'uploader_id': ('creator', 'username', {str}), 'uploader_id': ('creator', 'username', {str}),
}), })
}
class BandlabIE(BandlabBaseIE): class BandlabIE(BandlabBaseIE):
@ -125,7 +101,6 @@ class BandlabIE(BandlabBaseIE):
'genres': ['Lofi'], 'genres': ['Lofi'],
'uploader': 'ender milze', 'uploader': 'ender milze',
'comment_count': int, 'comment_count': int,
'media_type': 'revision',
}, },
}, { }, {
# Same track as above but post URL # Same track as above but post URL
@ -147,7 +122,6 @@ class BandlabIE(BandlabBaseIE):
'genres': ['Lofi'], 'genres': ['Lofi'],
'uploader': 'ender milze', 'uploader': 'ender milze',
'comment_count': int, 'comment_count': int,
'media_type': 'revision',
}, },
}, { }, {
# SharedKey Example # SharedKey Example
@ -169,7 +143,6 @@ class BandlabIE(BandlabBaseIE):
'upload_date': '20240305', 'upload_date': '20240305',
'uploader': 'Erna Wageneder', 'uploader': 'Erna Wageneder',
'title': 'PodcastMaerchen4b', 'title': 'PodcastMaerchen4b',
'media_type': 'revision',
}, },
}, { }, {
# Different Revision selected # Different Revision selected
@ -191,7 +164,6 @@ class BandlabIE(BandlabBaseIE):
'upload_date': '20200430', 'upload_date': '20200430',
'like_count': int, 'like_count': int,
'duration': 279.43, 'duration': 279.43,
'media_type': 'revision',
}, },
}, { }, {
# Video # Video
@ -208,7 +180,6 @@ class BandlabIE(BandlabBaseIE):
'uploader': 'auraa', 'uploader': 'auraa',
'like_count': int, 'like_count': int,
'description': 'backing vocals', 'description': 'backing vocals',
'media_type': 'video',
}, },
}, { }, {
# Embed Example # Embed Example
@ -230,7 +201,6 @@ class BandlabIE(BandlabBaseIE):
'uploader_id': 'microfreaks', 'uploader_id': 'microfreaks',
'title': 'Positronic Meltdown', 'title': 'Positronic Meltdown',
'like_count': int, 'like_count': int,
'media_type': 'revision',
}, },
}, { }, {
# Track without revisions available # Track without revisions available
@ -250,7 +220,6 @@ class BandlabIE(BandlabBaseIE):
'thumbnail': 'https://bandlabimages.azureedge.net/v1.0/users/572a351a-0f3a-4c6a-ac39-1a5defdeeb1c/', 'thumbnail': 'https://bandlabimages.azureedge.net/v1.0/users/572a351a-0f3a-4c6a-ac39-1a5defdeeb1c/',
'timestamp': 1691162128, 'timestamp': 1691162128,
'upload_date': '20230804', 'upload_date': '20230804',
'media_type': 'track',
}, },
}, { }, {
'url': 'https://www.bandlab.com/revision/014de0a4-7d82-ea11-a94c-0003ffd19c0f', 'url': 'https://www.bandlab.com/revision/014de0a4-7d82-ea11-a94c-0003ffd19c0f',
@ -274,7 +243,6 @@ class BandlabIE(BandlabBaseIE):
'title': 'Vermilion Pt. 2 (Cover)', 'title': 'Vermilion Pt. 2 (Cover)',
'track': 'Vermilion Pt. 2 (Cover)', 'track': 'Vermilion Pt. 2 (Cover)',
'thumbnail': 'https://bandlabimages.azureedge.net/v1.0/songs/62b10750-7aef-4f42-ad08-1af52f577e97/', 'thumbnail': 'https://bandlabimages.azureedge.net/v1.0/songs/62b10750-7aef-4f42-ad08-1af52f577e97/',
'media_type': 'revision',
}, },
}] }]
@ -288,8 +256,9 @@ class BandlabIE(BandlabBaseIE):
revision_data = None revision_data = None
if not revision_id: if not revision_id:
post_data = self._call_api( post_data = self._download_json(
'posts', display_id, note='Downloading post data', f'https://www.bandlab.com/api/v1.3/posts/{display_id}', display_id,
note='Downloading post data', headers=self._API_HEADERS,
query=traverse_obj(qs, {'sharedKey': ('sharedKey', 0)})) query=traverse_obj(qs, {'sharedKey': ('sharedKey', 0)}))
revision_id = traverse_obj(post_data, (('revisionId', ('revision', 'id')), {str}, any)) revision_id = traverse_obj(post_data, (('revisionId', ('revision', 'id')), {str}, any))
@ -298,16 +267,17 @@ class BandlabIE(BandlabBaseIE):
if not revision_data and not revision_id: if not revision_data and not revision_id:
post_type = post_data.get('type') post_type = post_data.get('type')
if post_type == 'Video': if post_type == 'Video':
return self._parse_video(post_data, url=url) return self._parse_video(post_data)
if post_type == 'Track': if post_type == 'Track':
return self._parse_track(post_data, url=url) return self._parse_track(post_data)
raise ExtractorError('Could not extract data') raise ExtractorError('Could not extract data')
if not revision_data: if not revision_data:
revision_data = self._call_api( revision_data = self._download_json(
'revisions', revision_id, note='Downloading revision data', query={'edit': 'false'}) f'https://www.bandlab.com/api/v1.3/revisions/{revision_id}', revision_id,
note='Downloading revision data', headers=self._API_HEADERS, query={'edit': 'false'})
return self._parse_revision(revision_data, url=url) return self._parse_revision(revision_data)
class BandlabPlaylistIE(BandlabBaseIE): class BandlabPlaylistIE(BandlabBaseIE):
@ -409,8 +379,9 @@ class BandlabPlaylistIE(BandlabBaseIE):
'embed': ['collections', 'albums'], 'embed': ['collections', 'albums'],
}.get(playlist_type) }.get(playlist_type)
for endpoint in endpoints: for endpoint in endpoints:
playlist_data = self._call_api( playlist_data = self._download_json(
endpoint, playlist_id, note=f'Downloading {endpoint[:-1]} data', f'https://www.bandlab.com/api/v1.3/{endpoint}/{playlist_id}', playlist_id,
note=f'Downloading {endpoint[:-1]} data', headers=self._API_HEADERS,
fatal=False, expected_status=404) fatal=False, expected_status=404)
if not playlist_data.get('errorCode'): if not playlist_data.get('errorCode'):
playlist_type = endpoint playlist_type = endpoint