mirror of
https://github.com/yt-dlp/yt-dlp
synced 2024-12-26 21:59:08 +01:00
Merge branch 'yt-dlp:master' into pr/live-sections
This commit is contained in:
commit
7d101c82a0
11 changed files with 68 additions and 17 deletions
|
@ -711,3 +711,5 @@ gitninja1234
|
||||||
jkruse
|
jkruse
|
||||||
xiaomac
|
xiaomac
|
||||||
wesson09
|
wesson09
|
||||||
|
Crypto90
|
||||||
|
MutantPiggieGolem1
|
||||||
|
|
14
Changelog.md
14
Changelog.md
|
@ -4,6 +4,20 @@
|
||||||
# To create a release, dispatch the https://github.com/yt-dlp/yt-dlp/actions/workflows/release.yml workflow on master
|
# To create a release, dispatch the https://github.com/yt-dlp/yt-dlp/actions/workflows/release.yml workflow on master
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
### 2024.12.13
|
||||||
|
|
||||||
|
#### Extractor changes
|
||||||
|
- **patreon**: campaign: [Support /c/ URLs](https://github.com/yt-dlp/yt-dlp/commit/bc262bcad4d3683ceadf61a7eb87e233e72adef3) ([#11756](https://github.com/yt-dlp/yt-dlp/issues/11756)) by [bashonly](https://github.com/bashonly)
|
||||||
|
- **soundcloud**: [Fix extraction](https://github.com/yt-dlp/yt-dlp/commit/f4d3e9e6dc25077b79849a31a2f67f93fdc01e62) ([#11777](https://github.com/yt-dlp/yt-dlp/issues/11777)) by [bashonly](https://github.com/bashonly)
|
||||||
|
- **youtube**
|
||||||
|
- [Fix `release_date` extraction](https://github.com/yt-dlp/yt-dlp/commit/d5e2a379f2adcb28bc48c7d9e90716d7278f89d2) ([#11759](https://github.com/yt-dlp/yt-dlp/issues/11759)) by [MutantPiggieGolem1](https://github.com/MutantPiggieGolem1)
|
||||||
|
- [Fix signature function extraction for `2f1832d2`](https://github.com/yt-dlp/yt-dlp/commit/5460cd91891bf613a2065e2fc278d9903c37a127) ([#11801](https://github.com/yt-dlp/yt-dlp/issues/11801)) by [bashonly](https://github.com/bashonly)
|
||||||
|
- [Prioritize original language over auto-dubbed audio](https://github.com/yt-dlp/yt-dlp/commit/dc3c4fddcc653989dae71fc563d82a308fc898cc) ([#11803](https://github.com/yt-dlp/yt-dlp/issues/11803)) by [bashonly](https://github.com/bashonly)
|
||||||
|
- search_url: [Fix playlist searches](https://github.com/yt-dlp/yt-dlp/commit/f6c73aad5f1a67544bea137ebd9d1e22e0e56567) ([#11782](https://github.com/yt-dlp/yt-dlp/issues/11782)) by [Crypto90](https://github.com/Crypto90)
|
||||||
|
|
||||||
|
#### Misc. changes
|
||||||
|
- **cleanup**: [Make more playlist entries lazy](https://github.com/yt-dlp/yt-dlp/commit/54216696261bc07cacd9a837c501d9e0b7fed09e) ([#11763](https://github.com/yt-dlp/yt-dlp/issues/11763)) by [seproDev](https://github.com/seproDev)
|
||||||
|
|
||||||
### 2024.12.06
|
### 2024.12.06
|
||||||
|
|
||||||
#### Core changes
|
#### Core changes
|
||||||
|
|
|
@ -73,6 +73,11 @@ _SIG_TESTS = [
|
||||||
'2aq0aqSyOoJXtK73m-uME_jv7-pT15gOFC02RFkGMqWpzEICs69VdbwQ0LDp1v7j8xx92efCJlYFYb1sUkkBSPOlPmXgIARw8JQ0qOAOAA',
|
'2aq0aqSyOoJXtK73m-uME_jv7-pT15gOFC02RFkGMqWpzEICs69VdbwQ0LDp1v7j8xx92efCJlYFYb1sUkkBSPOlPmXgIARw8JQ0qOAOAA',
|
||||||
'MyOSJXtKI3m-uME_jv7-pT12gOFC02RFkGoqWpzE0Cs69VdbwQ0LDp1v7j8xx92efCJlYFYb1sUkkBSPOlPmXgIARw8JQ0qOAOAA',
|
'MyOSJXtKI3m-uME_jv7-pT12gOFC02RFkGoqWpzE0Cs69VdbwQ0LDp1v7j8xx92efCJlYFYb1sUkkBSPOlPmXgIARw8JQ0qOAOAA',
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
'https://www.youtube.com/s/player/2f1832d2/player_ias.vflset/en_US/base.js',
|
||||||
|
'2aq0aqSyOoJXtK73m-uME_jv7-pT15gOFC02RFkGMqWpzEICs69VdbwQ0LDp1v7j8xx92efCJlYFYb1sUkkBSPOlPmXgIARw8JQ0qOAOAA',
|
||||||
|
'0QJ8wRAIgXmPlOPSBkkUs1bYFYlJCfe29xxAj7v1pDL0QwbdV96sCIEzpWqMGkFR20CFOg51Tp-7vj_EMu-m37KtXJ2OySqa0q',
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
_NSIG_TESTS = [
|
_NSIG_TESTS = [
|
||||||
|
@ -192,6 +197,10 @@ _NSIG_TESTS = [
|
||||||
'https://www.youtube.com/s/player/3bb1f723/player_ias.vflset/en_US/base.js',
|
'https://www.youtube.com/s/player/3bb1f723/player_ias.vflset/en_US/base.js',
|
||||||
'gK15nzVyaXE9RsMP3z', 'ZFFWFLPWx9DEgQ',
|
'gK15nzVyaXE9RsMP3z', 'ZFFWFLPWx9DEgQ',
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
'https://www.youtube.com/s/player/2f1832d2/player_ias.vflset/en_US/base.js',
|
||||||
|
'YWt1qdbe8SAfkoPHW5d', 'RrRjWQOJmBiP',
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ from ..utils import (
|
||||||
update_url_query,
|
update_url_query,
|
||||||
url_or_none,
|
url_or_none,
|
||||||
)
|
)
|
||||||
|
from ..utils.traversal import traverse_obj
|
||||||
|
|
||||||
|
|
||||||
class BrightcoveLegacyIE(InfoExtractor):
|
class BrightcoveLegacyIE(InfoExtractor):
|
||||||
|
@ -935,8 +936,8 @@ class BrightcoveNewIE(BrightcoveNewBaseIE):
|
||||||
|
|
||||||
if content_type == 'playlist':
|
if content_type == 'playlist':
|
||||||
return self.playlist_result(
|
return self.playlist_result(
|
||||||
[self._parse_brightcove_metadata(vid, vid.get('id'), headers)
|
(self._parse_brightcove_metadata(vid, vid['id'], headers)
|
||||||
for vid in json_data.get('videos', []) if vid.get('id')],
|
for vid in traverse_obj(json_data, ('videos', lambda _, v: v['id']))),
|
||||||
json_data.get('id'), json_data.get('name'),
|
json_data.get('id'), json_data.get('name'),
|
||||||
json_data.get('description'))
|
json_data.get('description'))
|
||||||
|
|
||||||
|
|
|
@ -162,7 +162,7 @@ class DVTVIE(InfoExtractor):
|
||||||
items = re.findall(r'(?s)playlist\.push\(({.+?})\);', webpage)
|
items = re.findall(r'(?s)playlist\.push\(({.+?})\);', webpage)
|
||||||
if items:
|
if items:
|
||||||
return self.playlist_result(
|
return self.playlist_result(
|
||||||
[self._parse_video_metadata(i, video_id, timestamp) for i in items],
|
(self._parse_video_metadata(i, video_id, timestamp) for i in items),
|
||||||
video_id, self._html_search_meta('twitter:title', webpage))
|
video_id, self._html_search_meta('twitter:title', webpage))
|
||||||
|
|
||||||
item = self._search_regex(
|
item = self._search_regex(
|
||||||
|
|
|
@ -343,7 +343,7 @@ class NYTimesCookingIE(NYTimesBaseIE):
|
||||||
if media_ids:
|
if media_ids:
|
||||||
media_ids.append(lead_video_id)
|
media_ids.append(lead_video_id)
|
||||||
return self.playlist_result(
|
return self.playlist_result(
|
||||||
[self._extract_video(media_id) for media_id in media_ids], page_id, title, description)
|
map(self._extract_video, media_ids), page_id, title, description)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
**self._extract_video(lead_video_id),
|
**self._extract_video(lead_video_id),
|
||||||
|
|
|
@ -457,7 +457,7 @@ class PatreonCampaignIE(PatreonBaseIE):
|
||||||
_VALID_URL = r'''(?x)
|
_VALID_URL = r'''(?x)
|
||||||
https?://(?:www\.)?patreon\.com/(?:
|
https?://(?:www\.)?patreon\.com/(?:
|
||||||
(?:m|api/campaigns)/(?P<campaign_id>\d+)|
|
(?:m|api/campaigns)/(?P<campaign_id>\d+)|
|
||||||
(?P<vanity>(?!creation[?/]|posts/|rss[?/])[\w-]+)
|
(?:c/)?(?P<vanity>(?!creation[?/]|posts/|rss[?/])[\w-]+)
|
||||||
)(?:/posts)?/?(?:$|[?#])'''
|
)(?:/posts)?/?(?:$|[?#])'''
|
||||||
_TESTS = [{
|
_TESTS = [{
|
||||||
'url': 'https://www.patreon.com/dissonancepod/',
|
'url': 'https://www.patreon.com/dissonancepod/',
|
||||||
|
@ -509,6 +509,26 @@ class PatreonCampaignIE(PatreonBaseIE):
|
||||||
'thumbnail': r're:^https?://.*$',
|
'thumbnail': r're:^https?://.*$',
|
||||||
},
|
},
|
||||||
'playlist_mincount': 201,
|
'playlist_mincount': 201,
|
||||||
|
}, {
|
||||||
|
'url': 'https://www.patreon.com/c/OgSog',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '8504388',
|
||||||
|
'title': 'OGSoG',
|
||||||
|
'description': r're:(?s)Hello and welcome to our Patreon page. We are Mari, Lasercorn, .+',
|
||||||
|
'channel': 'OGSoG',
|
||||||
|
'channel_id': '8504388',
|
||||||
|
'channel_url': 'https://www.patreon.com/OgSog',
|
||||||
|
'uploader_url': 'https://www.patreon.com/OgSog',
|
||||||
|
'uploader_id': '72323575',
|
||||||
|
'uploader': 'David Moss',
|
||||||
|
'thumbnail': r're:https?://.+/.+',
|
||||||
|
'channel_follower_count': int,
|
||||||
|
'age_limit': 0,
|
||||||
|
},
|
||||||
|
'playlist_mincount': 331,
|
||||||
|
}, {
|
||||||
|
'url': 'https://www.patreon.com/c/OgSog/posts',
|
||||||
|
'only_matching': True,
|
||||||
}, {
|
}, {
|
||||||
'url': 'https://www.patreon.com/dissonancepod/posts',
|
'url': 'https://www.patreon.com/dissonancepod/posts',
|
||||||
'only_matching': True,
|
'only_matching': True,
|
||||||
|
|
|
@ -259,6 +259,8 @@ class SoundcloudBaseIE(InfoExtractor):
|
||||||
preset_base = preset.partition('_')[0]
|
preset_base = preset.partition('_')[0]
|
||||||
|
|
||||||
protocol = traverse_obj(t, ('format', 'protocol', {str})) or 'http'
|
protocol = traverse_obj(t, ('format', 'protocol', {str})) or 'http'
|
||||||
|
if protocol.startswith(('ctr-', 'cbc-')):
|
||||||
|
continue
|
||||||
if protocol == 'progressive':
|
if protocol == 'progressive':
|
||||||
protocol = 'http'
|
protocol = 'http'
|
||||||
if protocol != 'hls' and '/hls' in format_url:
|
if protocol != 'hls' and '/hls' in format_url:
|
||||||
|
|
|
@ -421,5 +421,5 @@ class VidyardIE(VidyardBaseIE):
|
||||||
return self._process_video_json(video_json['chapters'][0], video_id)
|
return self._process_video_json(video_json['chapters'][0], video_id)
|
||||||
|
|
||||||
return self.playlist_result(
|
return self.playlist_result(
|
||||||
[self._process_video_json(chapter, video_id) for chapter in video_json['chapters']],
|
(self._process_video_json(chapter, video_id) for chapter in video_json['chapters']),
|
||||||
str(video_json['playerUuid']), video_json.get('name'))
|
str(video_json['playerUuid']), video_json.get('name'))
|
||||||
|
|
|
@ -3156,9 +3156,9 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
||||||
# ;N&&(N=sig(decodeURIComponent(N)),J.set(R,encodeURIComponent(N)));return J};
|
# ;N&&(N=sig(decodeURIComponent(N)),J.set(R,encodeURIComponent(N)));return J};
|
||||||
# {var H=u,k=f.sp,v=sig(decodeURIComponent(f.s));H.set(k,encodeURIComponent(v))}
|
# {var H=u,k=f.sp,v=sig(decodeURIComponent(f.s));H.set(k,encodeURIComponent(v))}
|
||||||
funcname = self._search_regex(
|
funcname = self._search_regex(
|
||||||
(r'\b(?P<var>[a-zA-Z0-9$]+)&&\((?P=var)=(?P<sig>[a-zA-Z0-9$]{2,})\(decodeURIComponent\((?P=var)\)\)',
|
(r'\b(?P<var>[a-zA-Z0-9_$]+)&&\((?P=var)=(?P<sig>[a-zA-Z0-9_$]{2,})\(decodeURIComponent\((?P=var)\)\)',
|
||||||
r'(?P<sig>[a-zA-Z0-9$]+)\s*=\s*function\(\s*(?P<arg>[a-zA-Z0-9$]+)\s*\)\s*{\s*(?P=arg)\s*=\s*(?P=arg)\.split\(\s*""\s*\)\s*;\s*[^}]+;\s*return\s+(?P=arg)\.join\(\s*""\s*\)',
|
r'(?P<sig>[a-zA-Z0-9_$]+)\s*=\s*function\(\s*(?P<arg>[a-zA-Z0-9_$]+)\s*\)\s*{\s*(?P=arg)\s*=\s*(?P=arg)\.split\(\s*""\s*\)\s*;\s*[^}]+;\s*return\s+(?P=arg)\.join\(\s*""\s*\)',
|
||||||
r'(?:\b|[^a-zA-Z0-9$])(?P<sig>[a-zA-Z0-9$]{2,})\s*=\s*function\(\s*a\s*\)\s*{\s*a\s*=\s*a\.split\(\s*""\s*\)(?:;[a-zA-Z0-9$]{2}\.[a-zA-Z0-9$]{2}\(a,\d+\))?',
|
r'(?:\b|[^a-zA-Z0-9_$])(?P<sig>[a-zA-Z0-9_$]{2,})\s*=\s*function\(\s*a\s*\)\s*{\s*a\s*=\s*a\.split\(\s*""\s*\)(?:;[a-zA-Z0-9_$]{2}\.[a-zA-Z0-9_$]{2}\(a,\d+\))?',
|
||||||
# Old patterns
|
# Old patterns
|
||||||
r'\b[cs]\s*&&\s*[adf]\.set\([^,]+\s*,\s*encodeURIComponent\s*\(\s*(?P<sig>[a-zA-Z0-9$]+)\(',
|
r'\b[cs]\s*&&\s*[adf]\.set\([^,]+\s*,\s*encodeURIComponent\s*\(\s*(?P<sig>[a-zA-Z0-9$]+)\(',
|
||||||
r'\b[a-zA-Z0-9]+\s*&&\s*[a-zA-Z0-9]+\.set\([^,]+\s*,\s*encodeURIComponent\s*\(\s*(?P<sig>[a-zA-Z0-9$]+)\(',
|
r'\b[a-zA-Z0-9]+\s*&&\s*[a-zA-Z0-9]+\.set\([^,]+\s*,\s*encodeURIComponent\s*\(\s*(?P<sig>[a-zA-Z0-9$]+)\(',
|
||||||
|
@ -4096,10 +4096,12 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
||||||
if height:
|
if height:
|
||||||
res_qualities[height] = quality
|
res_qualities[height] = quality
|
||||||
|
|
||||||
|
display_name = audio_track.get('displayName') or ''
|
||||||
|
is_original = 'original' in display_name.lower()
|
||||||
|
is_descriptive = 'descriptive' in display_name.lower()
|
||||||
is_default = audio_track.get('audioIsDefault')
|
is_default = audio_track.get('audioIsDefault')
|
||||||
is_descriptive = 'descriptive' in (audio_track.get('displayName') or '').lower()
|
|
||||||
language_code = audio_track.get('id', '').split('.')[0]
|
language_code = audio_track.get('id', '').split('.')[0]
|
||||||
if language_code and is_default:
|
if language_code and (is_original or (is_default and not original_language)):
|
||||||
original_language = language_code
|
original_language = language_code
|
||||||
|
|
||||||
# FORMAT_STREAM_TYPE_OTF(otf=1) requires downloading the init fragment
|
# FORMAT_STREAM_TYPE_OTF(otf=1) requires downloading the init fragment
|
||||||
|
@ -4180,7 +4182,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
||||||
'filesize': int_or_none(fmt.get('contentLength')),
|
'filesize': int_or_none(fmt.get('contentLength')),
|
||||||
'format_id': f'{itag}{"-drc" if fmt.get("isDrc") else ""}',
|
'format_id': f'{itag}{"-drc" if fmt.get("isDrc") else ""}',
|
||||||
'format_note': join_nonempty(
|
'format_note': join_nonempty(
|
||||||
join_nonempty(audio_track.get('displayName'), is_default and ' (default)', delim=''),
|
join_nonempty(display_name, is_default and ' (default)', delim=''),
|
||||||
name, fmt.get('isDrc') and 'DRC',
|
name, fmt.get('isDrc') and 'DRC',
|
||||||
try_get(fmt, lambda x: x['projectionType'].replace('RECTANGULAR', '').lower()),
|
try_get(fmt, lambda x: x['projectionType'].replace('RECTANGULAR', '').lower()),
|
||||||
try_get(fmt, lambda x: x['spatialAudioType'].replace('SPATIAL_AUDIO_TYPE_', '').lower()),
|
try_get(fmt, lambda x: x['spatialAudioType'].replace('SPATIAL_AUDIO_TYPE_', '').lower()),
|
||||||
|
@ -4199,7 +4201,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
||||||
'url': fmt_url,
|
'url': fmt_url,
|
||||||
'width': int_or_none(fmt.get('width')),
|
'width': int_or_none(fmt.get('width')),
|
||||||
'language': join_nonempty(language_code, 'desc' if is_descriptive else '') or None,
|
'language': join_nonempty(language_code, 'desc' if is_descriptive else '') or None,
|
||||||
'language_preference': PREFERRED_LANG_VALUE if is_default else -10 if is_descriptive else -1,
|
'language_preference': PREFERRED_LANG_VALUE if is_original else 5 if is_default else -10 if is_descriptive else -1,
|
||||||
# Strictly de-prioritize broken, damaged and 3gp formats
|
# Strictly de-prioritize broken, damaged and 3gp formats
|
||||||
'preference': -20 if is_broken else -10 if is_damaged else -2 if itag == '17' else None,
|
'preference': -20 if is_broken else -10 if is_damaged else -2 if itag == '17' else None,
|
||||||
}
|
}
|
||||||
|
@ -4721,7 +4723,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
||||||
(?=(?P<artist>[^\n]+))(?P=artist)\n+
|
(?=(?P<artist>[^\n]+))(?P=artist)\n+
|
||||||
(?=(?P<album>[^\n]+))(?P=album)\n
|
(?=(?P<album>[^\n]+))(?P=album)\n
|
||||||
(?:.+?℗\s*(?P<release_year>\d{4})(?!\d))?
|
(?:.+?℗\s*(?P<release_year>\d{4})(?!\d))?
|
||||||
(?:.+?Released on\s*:\s*(?P<release_date>\d{4}-\d{2}-\d{2}))?
|
(?:.+?Released\ on\s*:\s*(?P<release_date>\d{4}-\d{2}-\d{2}))?
|
||||||
(.+?\nArtist\s*:\s*
|
(.+?\nArtist\s*:\s*
|
||||||
(?=(?P<clean_artist>[^\n]+))(?P=clean_artist)\n
|
(?=(?P<clean_artist>[^\n]+))(?P=clean_artist)\n
|
||||||
)?.+\nAuto-generated\ by\ YouTube\.\s*$
|
)?.+\nAuto-generated\ by\ YouTube\.\s*$
|
||||||
|
@ -5314,6 +5316,7 @@ class YoutubeTabBaseInfoExtractor(YoutubeBaseInfoExtractor):
|
||||||
'channelRenderer': lambda x: self._grid_entries({'items': [{'channelRenderer': x}]}),
|
'channelRenderer': lambda x: self._grid_entries({'items': [{'channelRenderer': x}]}),
|
||||||
'hashtagTileRenderer': lambda x: [self._hashtag_tile_entry(x)],
|
'hashtagTileRenderer': lambda x: [self._hashtag_tile_entry(x)],
|
||||||
'richGridRenderer': lambda x: self._extract_entries(x, continuation_list),
|
'richGridRenderer': lambda x: self._extract_entries(x, continuation_list),
|
||||||
|
'lockupViewModel': lambda x: [self._extract_lockup_view_model(x)],
|
||||||
}
|
}
|
||||||
for key, renderer in isr_content.items():
|
for key, renderer in isr_content.items():
|
||||||
if key not in known_renderers:
|
if key not in known_renderers:
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# Autogenerated by devscripts/update-version.py
|
# Autogenerated by devscripts/update-version.py
|
||||||
|
|
||||||
__version__ = '2024.12.06'
|
__version__ = '2024.12.13'
|
||||||
|
|
||||||
RELEASE_GIT_HEAD = '4bd2655398aed450456197a6767639114a24eac2'
|
RELEASE_GIT_HEAD = '54216696261bc07cacd9a837c501d9e0b7fed09e'
|
||||||
|
|
||||||
VARIANT = None
|
VARIANT = None
|
||||||
|
|
||||||
|
@ -12,4 +12,4 @@ CHANNEL = 'stable'
|
||||||
|
|
||||||
ORIGIN = 'yt-dlp/yt-dlp'
|
ORIGIN = 'yt-dlp/yt-dlp'
|
||||||
|
|
||||||
_pkg_version = '2024.12.06'
|
_pkg_version = '2024.12.13'
|
||||||
|
|
Loading…
Reference in a new issue