Compare commits

...

6 Commits

Author SHA1 Message Date
Allan Daemon
696b38132c
Merge f8703c429117a92ad63d2c94a99eee6d6f1165ae into 673277e510ebd996b62a2fcc76169bf3cce29910 2025-03-10 02:15:44 +00:00
dirkf
673277e510
[YouTube] Fix 91b1569 2025-02-28 01:02:20 +00:00
dirkf
91b1569f68
[YouTube] Fix channel playlist extraction (#33074)
* [YouTube] Extract playlist items from LOCKUP_VIEW_MODEL_...
* resolves #33073
* thx seproDev (yt-dlp/yt-dlp#11615)

Co-authored-by: sepro <sepro@sepr0.com>
2025-02-28 00:02:10 +00:00
Allan Daemon
f8703c4291 Give MySpace artist support a better name 2020-12-03 00:28:27 -03:00
Allan Daemon
7ae403d9fd [myspace] Fix issues for merging of all songs of an artist inclusion 2020-12-03 00:26:17 -03:00
Allan Daemon
48da538f7d [myspace] Added support for downloading all songs of an artist 2020-12-03 00:26:17 -03:00
3 changed files with 80 additions and 10 deletions

View File

@ -738,7 +738,7 @@ from .mtv import (
from .muenchentv import MuenchenTVIE
from .mwave import MwaveIE, MwaveMeetGreetIE
from .mychannels import MyChannelsIE
from .myspace import MySpaceIE, MySpaceAlbumIE
from .myspace import MySpaceIE, MySpaceAlbumIE, MySpaceArtistIE
from .myspass import MySpassIE
from .myvi import (
MyviIE,

View File

@ -203,10 +203,35 @@ class MySpaceAlbumIE(InfoExtractor):
entries = [
self.url_result(t_path, ie=MySpaceIE.ie_key())
for t_path in tracks_paths]
return {
'_type': 'playlist',
'id': playlist_id,
'display_id': display_id,
'title': self._og_search_title(webpage),
'entries': entries,
return self.playlist_result(entries, playlist_id, self._og_search_title(webpage))
class MySpaceArtistIE(InfoExtractor):
IE_NAME = 'MySpace:artist'
_VALID_URL = r'https?://myspace\.com/(?P<artist>[^/]*)/music/songs'
_TEST = {
'url': 'https://myspace.com/studio99/music/songs/',
'info_dict': {
'title': 'Studio 99 IS CLOSED!! R.I.P.',
},
'playlist_count': 4,
}
def _real_extract(self, url):
mobj = re.match(self._VALID_URL, url)
display_id = mobj.group('artist')
webpage = self._download_webpage(url, display_id)
tracks_paths = re.findall(r'<meta itemprop="url" content ="(.*?)">', webpage)
if not tracks_paths:
raise ExtractorError(
'%s: No songs found, try using proxy' % display_id,
expected=True)
entries = [
self.url_result('https://myspace.com/' + display_id + t_path, ie=MySpaceIE.ie_key())
for t_path in tracks_paths if t_path.startswith('/music/song/')]
# if we invert this if, we get album urls. but not all music are in alba.
# Also the musics in alba are already here individually
return self.playlist_result(entries, playlist_title=self._og_search_title(webpage))

View File

@ -27,6 +27,7 @@ from ..compat import (
)
from ..jsinterp import JSInterpreter
from ..utils import (
bug_reports_message,
clean_html,
dict_get,
error_to_compat_str,
@ -65,6 +66,7 @@ from ..utils import (
url_or_none,
urlencode_postdata,
urljoin,
variadic,
)
@ -460,6 +462,26 @@ class YoutubeBaseInfoExtractor(InfoExtractor):
'uploader': uploader,
}
@staticmethod
def _extract_thumbnails(data, *path_list, **kw_final_key):
"""
Extract thumbnails from thumbnails dict
@param path_list: path list to level that contains 'thumbnails' key
"""
final_key = kw_final_key.get('final_key', 'thumbnails')
return traverse_obj(data, ((
tuple(variadic(path) + (final_key, Ellipsis)
for path in path_list or [()])), {
'url': ('url', T(url_or_none),
# Sometimes youtube gives a wrong thumbnail URL. See:
# https://github.com/yt-dlp/yt-dlp/issues/233
# https://github.com/ytdl-org/youtube-dl/issues/28023
T(lambda u: update_url(u, query=None) if u and 'maxresdefault' in u else u)),
'height': ('height', T(int_or_none)),
'width': ('width', T(int_or_none)),
}, T(lambda t: t if t.get('url') else None)))
def _search_results(self, query, params):
data = {
'context': {
@ -3183,8 +3205,12 @@ class YoutubeTabIE(YoutubeBaseInfoExtractor):
expected_type=txt_or_none)
def _grid_entries(self, grid_renderer):
for item in grid_renderer['items']:
if not isinstance(item, dict):
for item in traverse_obj(grid_renderer, ('items', Ellipsis, T(dict))):
lockup_view_model = traverse_obj(item, ('lockupViewModel', T(dict)))
if lockup_view_model:
entry = self._extract_lockup_view_model(lockup_view_model)
if entry:
yield entry
continue
renderer = self._extract_grid_item_renderer(item)
if not isinstance(renderer, dict):
@ -3268,6 +3294,25 @@ class YoutubeTabIE(YoutubeBaseInfoExtractor):
continue
yield self._extract_video(renderer)
def _extract_lockup_view_model(self, view_model):
content_id = view_model.get('contentId')
if not content_id:
return
content_type = view_model.get('contentType')
if content_type not in ('LOCKUP_CONTENT_TYPE_PLAYLIST', 'LOCKUP_CONTENT_TYPE_PODCAST'):
self.report_warning(
'Unsupported lockup view model content type "{0}"{1}'.format(content_type, bug_reports_message()), only_once=True)
return
return merge_dicts(self.url_result(
update_url_query('https://www.youtube.com/playlist', {'list': content_id}),
ie=YoutubeTabIE.ie_key(), video_id=content_id), {
'title': traverse_obj(view_model, (
'metadata', 'lockupMetadataViewModel', 'title', 'content', T(compat_str))),
'thumbnails': self._extract_thumbnails(view_model, (
'contentImage', 'collectionThumbnailViewModel', 'primaryThumbnail',
'thumbnailViewModel', 'image'), final_key='sources'),
})
def _video_entry(self, video_renderer):
video_id = video_renderer.get('videoId')
if video_id: