mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2025-06-27 17:08:32 +00:00
Review changes
This commit is contained in:
parent
c34129c354
commit
a5778de413
@ -1,4 +1,7 @@
|
|||||||
|
import re
|
||||||
|
|
||||||
from .common import InfoExtractor
|
from .common import InfoExtractor
|
||||||
|
from ..utils import determine_ext, urljoin
|
||||||
|
|
||||||
|
|
||||||
class UdioIE(InfoExtractor):
|
class UdioIE(InfoExtractor):
|
||||||
@ -6,74 +9,84 @@ class UdioIE(InfoExtractor):
|
|||||||
_TESTS = [{
|
_TESTS = [{
|
||||||
'url': 'https://www.udio.com/songs/ehJuLz9DuCtVapQMVMcA7N',
|
'url': 'https://www.udio.com/songs/ehJuLz9DuCtVapQMVMcA7N',
|
||||||
'info_dict':
|
'info_dict':
|
||||||
{'id': 'ehJuLz9DuCtVapQMVMcA7N',
|
{
|
||||||
'title': 'Lost Love | Udio',
|
'id': 'ehJuLz9DuCtVapQMVMcA7N',
|
||||||
'description': "Listen to Lost Love by The I Don't Knows on Udio. Discover, create, and share music with the world. Use the latest technology to create AI music in seconds.",
|
'title': 'Lost Love',
|
||||||
'uploader': "The I Don't Knows",
|
'description': "Listen to Lost Love by The I Don't Knows on Udio. Discover, create, and share music with the world. Use the latest technology to create AI music in seconds.",
|
||||||
'uploader_url': "https://udio.com/artist/The I Don't Knows"},
|
'uploader': "The I Don't Knows",
|
||||||
|
'uploader_url': "https://udio.com/artist/The I Don't Knows",
|
||||||
|
},
|
||||||
'playlist_count': 1,
|
'playlist_count': 1,
|
||||||
}, {
|
}, {
|
||||||
'url': 'https://www.udio.com/songs/hGZqWy3bPMrN3tosf5QZqt',
|
'url': 'https://www.udio.com/songs/hGZqWy3bPMrN3tosf5QZqt',
|
||||||
'info_dict':
|
'info_dict':
|
||||||
{'id': 'hGZqWy3bPMrN3tosf5QZqt',
|
{
|
||||||
'title': 'Batou - What is this love thing? (feat. EchoShadow) | Udio',
|
'id': 'hGZqWy3bPMrN3tosf5QZqt',
|
||||||
'description': 'Listen to Batou - What is this love thing? (feat. EchoShadow) by DigitalScribe on Udio. Discover, create, and share music with the world. Use the latest technology to create AI music in seconds.',
|
'title': 'Batou - What is this love thing? (feat. EchoShadow)',
|
||||||
'uploader': 'DigitalScribe',
|
'description': 'Listen to Batou - What is this love thing? (feat. EchoShadow) by DigitalScribe on Udio. Discover, create, and share music with the world. Use the latest technology to create AI music in seconds.',
|
||||||
'uploader_url': 'https://udio.com/artist/DigitalScribe'},
|
'uploader': 'DigitalScribe',
|
||||||
|
'uploader_url': 'https://udio.com/artist/DigitalScribe',
|
||||||
|
},
|
||||||
'playlist_count': 1,
|
'playlist_count': 1,
|
||||||
}, {
|
}, {
|
||||||
'url': 'https://www.udio.com/songs/dRFAMqCzqkTAX13F4MTKCb',
|
'url': 'https://www.udio.com/songs/dRFAMqCzqkTAX13F4MTKCb',
|
||||||
'info_dict': {'id': 'dRFAMqCzqkTAX13F4MTKCb',
|
'info_dict': {
|
||||||
'title': 'Évasion en Route | Udio',
|
'id': 'dRFAMqCzqkTAX13F4MTKCb',
|
||||||
'description': 'Listen to Évasion en Route by aveiro on Udio. Discover, create, and share music with the world. Use the latest technology to create AI music in seconds.',
|
'title': 'Évasion en Route',
|
||||||
'uploader': 'aveiro',
|
'description': 'Listen to Évasion en Route by aveiro on Udio. Discover, create, and share music with the world. Use the latest technology to create AI music in seconds.',
|
||||||
'uploader_url': 'https://udio.com/artist/aveiro'},
|
'uploader': 'aveiro',
|
||||||
|
'uploader_url': 'https://udio.com/artist/aveiro',
|
||||||
|
},
|
||||||
'playlist_count': 1,
|
'playlist_count': 1,
|
||||||
}, {
|
}, {
|
||||||
'url': 'https://www.udio.com/songs/edMsDRvAiFosixHHTVbJ1L',
|
'url': 'https://www.udio.com/songs/edMsDRvAiFosixHHTVbJ1L',
|
||||||
'info_dict': {'id': 'edMsDRvAiFosixHHTVbJ1L',
|
'info_dict': {
|
||||||
'title': 'Charlie e la Felicità ext v2.2 | Udio',
|
'id': 'edMsDRvAiFosixHHTVbJ1L',
|
||||||
'description': 'Listen to Charlie e la Felicità ext v2.2 by GIANI_curzioilGRANDE on Udio. Discover, create, and share music with the world. Use the latest technology to create AI music in seconds.',
|
'title': 'Charlie e la Felicità ext v2.2',
|
||||||
'uploader': 'GIANI_curzioilGRANDE',
|
'description': 'Listen to Charlie e la Felicità ext v2.2 by GIANI_curzioilGRANDE on Udio. Discover, create, and share music with the world. Use the latest technology to create AI music in seconds.',
|
||||||
'uploader_url': 'https://udio.com/artist/GIANI_curzioilGRANDE'},
|
'uploader': 'GIANI_curzioilGRANDE',
|
||||||
|
'uploader_url': 'https://udio.com/artist/GIANI_curzioilGRANDE',
|
||||||
|
},
|
||||||
'playlist_count': 1,
|
'playlist_count': 1,
|
||||||
}, {
|
}, {
|
||||||
'url': 'https://www.udio.com/songs/fPoZ7yLUv8orY2sNzeYNFp',
|
'url': 'https://www.udio.com/songs/fPoZ7yLUv8orY2sNzeYNFp',
|
||||||
'info_dict': {'id': 'fPoZ7yLUv8orY2sNzeYNFp',
|
'info_dict': {
|
||||||
'title': 'Nocturnal Vibes | Udio',
|
'id': 'fPoZ7yLUv8orY2sNzeYNFp',
|
||||||
'description': 'Listen to Nocturnal Vibes by RaulKong898 on Udio. Discover, create, and share music with the world. Use the latest technology to create AI music in seconds.',
|
'title': 'Nocturnal Vibes',
|
||||||
'uploader': 'RaulKong898',
|
'description': 'Listen to Nocturnal Vibes by RaulKong898 on Udio. Discover, create, and share music with the world. Use the latest technology to create AI music in seconds.',
|
||||||
'uploader_url': 'https://udio.com/artist/RaulKong898'},
|
'uploader': 'RaulKong898',
|
||||||
|
'uploader_url': 'https://udio.com/artist/RaulKong898',
|
||||||
|
},
|
||||||
'playlist_count': 1,
|
'playlist_count': 1,
|
||||||
}, {
|
}, {
|
||||||
'url': 'https://www.udio.com/songs/pzGGivV6oAR76ZxsnkbVw2',
|
'url': 'https://www.udio.com/songs/pzGGivV6oAR76ZxsnkbVw2',
|
||||||
'info_dict': {'id': 'pzGGivV6oAR76ZxsnkbVw2',
|
'info_dict': {
|
||||||
'title': 'Eternal Darkness | Udio',
|
'id': 'pzGGivV6oAR76ZxsnkbVw2',
|
||||||
'description': 'Listen to Eternal Darkness by Para$Graf0815 on Udio. Discover, create, and share music with the world. Use the latest technology to create AI music in seconds.',
|
'title': 'Eternal Darkness',
|
||||||
'uploader': 'Para$Graf0815',
|
'description': 'Listen to Eternal Darkness by Para$Graf0815 on Udio. Discover, create, and share music with the world. Use the latest technology to create AI music in seconds.',
|
||||||
'uploader_url': 'https://udio.com/artist/Para$Graf0815'},
|
'uploader': 'Para$Graf0815',
|
||||||
|
'uploader_url': 'https://udio.com/artist/Para$Graf0815',
|
||||||
|
},
|
||||||
'playlist_count': 1,
|
'playlist_count': 1,
|
||||||
}, {
|
}, {
|
||||||
'url': 'https://www.udio.com/songs/hSzvdEyBjBXF2CdsJP4zYr',
|
'url': 'https://www.udio.com/songs/hSzvdEyBjBXF2CdsJP4zYr',
|
||||||
'info_dict': {'id': 'hSzvdEyBjBXF2CdsJP4zYr',
|
'info_dict': {
|
||||||
'title': 'Revenge of the Dreamer | Udio',
|
'id': 'hSzvdEyBjBXF2CdsJP4zYr',
|
||||||
'description': 'Listen to Revenge of the Dreamer by Doc Immortal on Udio. Discover, create, and share music with the world. Use the latest technology to create AI music in seconds.',
|
'title': 'Revenge of the Dreamer',
|
||||||
'uploader': 'Doc Immortal',
|
'description': 'Listen to Revenge of the Dreamer by Doc Immortal on Udio. Discover, create, and share music with the world. Use the latest technology to create AI music in seconds.',
|
||||||
'uploader_url': 'https://udio.com/artist/Doc Immortal'},
|
'uploader': 'Doc Immortal',
|
||||||
|
'uploader_url': 'https://udio.com/artist/Doc Immortal',
|
||||||
|
},
|
||||||
'playlist_count': 1,
|
'playlist_count': 1,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
def _real_extract(self, url):
|
def _real_extract(self, url):
|
||||||
artist_id = self._match_id(url)
|
song_id = self._match_id(url)
|
||||||
webpage = self._download_webpage(url, artist_id)
|
webpage = self._download_webpage(url, song_id)
|
||||||
|
media_url = self._og_search_video_url(webpage, default=None)
|
||||||
# Extract the audio URL from the <meta> tag
|
|
||||||
audio_src = self._html_search_meta('og:audio', webpage, 'audio src', fatal=True)
|
|
||||||
artist_name, title = self._html_extract_title(webpage, default=None).split('-', 1)
|
artist_name, title = self._html_extract_title(webpage, default=None).split('-', 1)
|
||||||
description = self._og_search_description(webpage, default=None)
|
title = title.split('|', 1)
|
||||||
# Create a single entry for the playlist
|
|
||||||
# Extract lyrics from the pre tag with specific classes
|
|
||||||
lyrics = self._search_regex(
|
lyrics = self._search_regex(
|
||||||
r'<pre>\s*(.*?)\s*</pre>',
|
r'<pre>\s*(.*?)\s*</pre>',
|
||||||
webpage,
|
webpage,
|
||||||
@ -82,12 +95,15 @@ def _real_extract(self, url):
|
|||||||
)
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'id': artist_id,
|
'id': song_id,
|
||||||
'title': title.strip(),
|
'title': title[0].strip(),
|
||||||
'description': lyrics,
|
'description': lyrics,
|
||||||
'uploader': artist_name.strip(),
|
'uploader': artist_name.strip(),
|
||||||
'uploader_url': f'https://udio.com/artist/{artist_name.strip()}',
|
'uploader_url': urljoin('https://udio.com/artist/', artist_name.strip()),
|
||||||
'url': audio_src,
|
'formats': [{
|
||||||
|
'url': media_url,
|
||||||
|
'ext': determine_ext(media_url),
|
||||||
|
}],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -135,32 +151,17 @@ class UdioListIE(InfoExtractor):
|
|||||||
}]
|
}]
|
||||||
|
|
||||||
def _find_links(self, webpage, base_url=None):
|
def _find_links(self, webpage, base_url=None):
|
||||||
"""
|
|
||||||
Find all song links in the webpage.
|
|
||||||
Returns a list of absolute URLs.
|
|
||||||
Args:
|
|
||||||
webpage: The HTML content of the webpage
|
|
||||||
base_url: Base URL to prepend to relative links (optional)
|
|
||||||
Returns:
|
|
||||||
List of absolute song URLs
|
|
||||||
"""
|
|
||||||
import re
|
|
||||||
|
|
||||||
# Look for href attributes with relative song links
|
|
||||||
relative_links = re.findall(r'href="(/songs/[^"?&/]+)"', webpage)
|
relative_links = re.findall(r'href="(/songs/[^"?&/]+)"', webpage)
|
||||||
|
|
||||||
# Convert relative URLs to absolute URLs
|
|
||||||
if not base_url:
|
if not base_url:
|
||||||
base_url = 'https://www.udio.com'
|
base_url = 'https://www.udio.com'
|
||||||
|
|
||||||
return [f'{base_url}{relative_link}' for relative_link in relative_links]
|
return [f'{base_url}{relative_link}' for relative_link in relative_links]
|
||||||
|
|
||||||
def _real_extract(self, url):
|
def _real_extract(self, url):
|
||||||
import re
|
|
||||||
list_type, list_id = self._match_valid_url(url).group('list_type', 'id')
|
list_type, list_id = self._match_valid_url(url).group('list_type', 'id')
|
||||||
webpage = self._download_webpage(url, list_id)
|
webpage = self._download_webpage(url, list_id)
|
||||||
|
|
||||||
# Look for song cards in the webpage
|
|
||||||
song_cards = re.findall(r'<div[^>]*class="[^"]*song-card[^"]*"[^>]*>(.*?)</div>\s*</div>',
|
song_cards = re.findall(r'<div[^>]*class="[^"]*song-card[^"]*"[^>]*>(.*?)</div>\s*</div>',
|
||||||
webpage, re.DOTALL)
|
webpage, re.DOTALL)
|
||||||
|
|
||||||
@ -168,31 +169,26 @@ def _real_extract(self, url):
|
|||||||
|
|
||||||
entries = []
|
entries = []
|
||||||
for card in song_cards:
|
for card in song_cards:
|
||||||
# Extract song URL
|
|
||||||
song_url_match = re.search(r'href="(/songs/([^"?&/]+))"', card)
|
song_url_match = re.search(r'href="(/songs/([^"?&/]+))"', card)
|
||||||
if not song_url_match:
|
if not song_url_match:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
song_path = song_url_match.group(1)
|
song_path = song_url_match.group(1)
|
||||||
song_id = song_url_match.group(2)
|
song_id = song_url_match.group(2)
|
||||||
song_url = f'https://www.udio.com{song_path}'
|
song_url = urljoin('https://www.udio.com/', song_path)
|
||||||
|
|
||||||
# Extract song title
|
|
||||||
song_title = self._search_regex(
|
song_title = self._search_regex(
|
||||||
r'<div[^>]*class="[^"]*song-title[^"]*"[^>]*>(.*?)</div>',
|
r'<div[^>]*class="[^"]*song-title[^"]*"[^>]*>(.*?)</div>',
|
||||||
card, 'song title', default=None)
|
card, 'song title', default=None)
|
||||||
|
|
||||||
# Extract artist name
|
|
||||||
artist_name = self._search_regex(
|
artist_name = self._search_regex(
|
||||||
r'<div[^>]*class="[^"]*artist-name[^"]*"[^>]*>(.*?)</div>',
|
r'<div[^>]*class="[^"]*artist-name[^"]*"[^>]*>(.*?)</div>',
|
||||||
card, 'artist name', default=None)
|
card, 'artist name', default=None)
|
||||||
|
|
||||||
# Extract thumbnail
|
|
||||||
thumbnail = self._search_regex(
|
thumbnail = self._search_regex(
|
||||||
r'<img[^>]*src="([^"]+)"[^>]*class="[^"]*song-cover[^"]*"',
|
r'<img[^>]*src="([^"]+)"[^>]*class="[^"]*song-cover[^"]*"',
|
||||||
card, 'thumbnail', default=None)
|
card, 'thumbnail', default=None)
|
||||||
|
|
||||||
# If we found detailed metadata, create a more detailed entry
|
|
||||||
if song_title or artist_name or thumbnail:
|
if song_title or artist_name or thumbnail:
|
||||||
self.to_screen(f'Found metadata for song {song_id}: {song_title} by {artist_name}')
|
self.to_screen(f'Found metadata for song {song_id}: {song_title} by {artist_name}')
|
||||||
entry = {
|
entry = {
|
||||||
@ -211,10 +207,8 @@ def _real_extract(self, url):
|
|||||||
|
|
||||||
entries.append(entry)
|
entries.append(entry)
|
||||||
else:
|
else:
|
||||||
# Fall back to simple URL result if no metadata found
|
|
||||||
entries.append(self.url_result(song_url, 'Udio', song_id))
|
entries.append(self.url_result(song_url, 'Udio', song_id))
|
||||||
|
|
||||||
# If no entries found using song cards, fall back to our existing method
|
|
||||||
if not entries:
|
if not entries:
|
||||||
self.to_screen('No song cards found, trying alternative methods')
|
self.to_screen('No song cards found, trying alternative methods')
|
||||||
song_urls = self._find_links(webpage)
|
song_urls = self._find_links(webpage)
|
||||||
|
Loading…
Reference in New Issue
Block a user