Allow watch urls from music.youtube.com to be directly handled by the addon

This commit is contained in:
MoojMidge 2025-10-18 19:12:12 +11:00
parent 01e4322791
commit 5f38dc3931
2 changed files with 24 additions and 5 deletions

View file

@ -53,12 +53,13 @@ VALUE_TO_STR = {
1: 'true', 1: 'true',
} }
YOUTUBE_HOSTNAMES = { YOUTUBE_HOSTNAMES = frozenset((
'youtube.com', 'youtube.com',
'www.youtube.com', 'www.youtube.com',
'm.youtube.com', 'm.youtube.com',
'www.youtubekids.com', 'www.youtubekids.com',
} 'music.youtube.com',
))
# Flags # Flags
ABORT_FLAG = 'abort_requested' ABORT_FLAG = 'abort_requested'

View file

@ -64,12 +64,16 @@ class YouTubeResolver(AbstractResolver):
r'|(?P<is_clip>"clipConfig":\{)' r'|(?P<is_clip>"clipConfig":\{)'
r'|("startTimeMs":"(?P<start_time>\d+)")' r'|("startTimeMs":"(?P<start_time>\d+)")'
r'|("endTimeMs":"(?P<end_time>\d+)")') r'|("endTimeMs":"(?P<end_time>\d+)")')
_RE_MUSIC_VIDEO_ID = re_compile(r'"INITIAL_ENDPOINT":.+?videoId\\":\\"'
r'(?P<video_id>[^\\"]+)'
r'\\"')
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(YouTubeResolver, self).__init__(*args, **kwargs) super(YouTubeResolver, self).__init__(*args, **kwargs)
def supports_url(self, url, url_components): def supports_url(self, url, url_components):
if url_components.hostname not in YOUTUBE_HOSTNAMES: hostname = url_components.hostname
if hostname not in YOUTUBE_HOSTNAMES:
return False return False
path = url_components.path.lower() path = url_components.path.lower()
@ -88,10 +92,14 @@ class YouTubeResolver(AbstractResolver):
'/redirect', '/redirect',
'/shorts', '/shorts',
'/supported_browsers', '/supported_browsers',
'/watch',
)): )):
return 'HEAD' return 'HEAD'
if path.startswith('/watch'):
if hostname.startswith('music.'):
return 'GET'
return 'HEAD'
# user channel in the form of youtube.com/username # user channel in the form of youtube.com/username
path = path.strip('/').split('/', 1) path = path.strip('/').split('/', 1)
return 'GET' if len(path) == 1 and path[0] else False return 'GET' if len(path) == 1 and path[0] else False
@ -189,7 +197,17 @@ class YouTubeResolver(AbstractResolver):
query=urlencode(new_params) query=urlencode(new_params)
).geturl() ).geturl()
# we try to extract the channel id from the html content # try to extract the real videoId from the html content
elif method == 'GET' and url_components.hostname.startswith('music.'):
match = self._RE_MUSIC_VIDEO_ID.search(response_text)
if match:
params = dict(parse_qsl(url_components.query))
params['v'] = match.group('video_id')
return url_components._replace(
query=urlencode(params)
).geturl()
# try to extract the channel id from the html content
# With the channel id we can construct a URL we already work with # With the channel id we can construct a URL we already work with
# https://www.youtube.com/channel/<CHANNEL_ID> # https://www.youtube.com/channel/<CHANNEL_ID>
elif method == 'GET': elif method == 'GET':