1
0
mirror of https://github.com/yt-dlp/yt-dlp.git synced 2025-12-21 15:38:53 +00:00

Merge branch 'master' into yt-live-from-start-range

This commit is contained in:
bashonly
2024-01-19 17:05:19 -06:00
committed by GitHub
346 changed files with 10935 additions and 13520 deletions

View File

@@ -428,7 +428,7 @@ class YoutubeBaseInfoExtractor(InfoExtractor):
r'(?:www\.)?piped\.adminforge\.de',
r'(?:www\.)?watch\.whatevertinfoil\.de',
r'(?:www\.)?piped\.qdi\.fi',
r'(?:www\.)?piped\.video',
r'(?:(?:www|cf)\.)?piped\.video',
r'(?:www\.)?piped\.aeong\.one',
r'(?:www\.)?piped\.moomoo\.me',
r'(?:www\.)?piped\.chauvet\.pro',
@@ -947,7 +947,10 @@ class YoutubeBaseInfoExtractor(InfoExtractor):
icd_rm = next(icd_retries)
main_retries = iter(self.RetryManager())
main_rm = next(main_retries)
for _ in range(main_rm.retries + icd_rm.retries + 1):
# Manual retry loop for multiple RetryManagers
# The proper RetryManager MUST be advanced after an error
# and its result MUST be checked if the manager is non fatal
while True:
try:
response = self._call_api(
ep=ep, fatal=True, headers=headers,
@@ -2069,7 +2072,6 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
'track': 'Voyeur Girl',
'album': 'it\'s too much love to know my dear',
'release_date': '20190313',
'release_year': 2019,
'alt_title': 'Voyeur Girl',
'view_count': int,
'playable_in_embed': True,
@@ -4510,14 +4512,13 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
if mobj:
info[mobj.group('type') + '_count'] = str_to_int(mobj.group('count'))
break
sbr_tooltip = try_get(
vpir, lambda x: x['sentimentBar']['sentimentBarRenderer']['tooltip'])
if sbr_tooltip:
like_count, dislike_count = sbr_tooltip.split(' / ')
info.update({
'like_count': str_to_int(like_count),
'dislike_count': str_to_int(dislike_count),
})
info['like_count'] = traverse_obj(vpir, (
'videoActions', 'menuRenderer', 'topLevelButtons', ...,
'segmentedLikeDislikeButtonViewModel', 'likeButtonViewModel', 'likeButtonViewModel',
'toggleButtonViewModel', 'toggleButtonViewModel', 'defaultButtonViewModel',
'buttonViewModel', 'accessibilityText', {parse_count}), get_all=False)
vcr = traverse_obj(vpir, ('viewCount', 'videoViewCountRenderer'))
if vcr:
vc = self._get_count(vcr, 'viewCount')
@@ -4589,6 +4590,14 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
self._parse_time_text(self._get_text(vpir, 'dateText'))) or upload_date
info['upload_date'] = upload_date
if upload_date and live_status not in ('is_live', 'post_live', 'is_upcoming'):
# Newly uploaded videos' HLS formats are potentially problematic and need to be checked
upload_datetime = datetime_from_str(upload_date).replace(tzinfo=datetime.timezone.utc)
if upload_datetime >= datetime_from_str('today-2days'):
for fmt in info['formats']:
if fmt.get('protocol') == 'm3u8_native':
fmt['__needs_testing'] = True
for s_k, d_k in [('artist', 'creator'), ('track', 'alt_title')]:
v = info.get(s_k)
if v:
@@ -5320,6 +5329,7 @@ class YoutubeTabBaseInfoExtractor(YoutubeBaseInfoExtractor):
# See: https://github.com/yt-dlp/yt-dlp/issues/116
if not traverse_obj(data, 'contents', 'currentVideoEndpoint', 'onResponseReceivedActions'):
retry.error = ExtractorError('Incomplete yt initial data received')
data = None
continue
return webpage, data
@@ -6491,6 +6501,9 @@ class YoutubeTabIE(YoutubeTabBaseInfoExtractor):
def _has_tab(self, tabs, tab_id):
return any(self._extract_tab_id_and_name(tab)[0] == tab_id for tab in tabs)
def _empty_playlist(self, item_id, data):
return self.playlist_result([], item_id, **self._extract_metadata_from_tabs(item_id, data))
@YoutubeTabBaseInfoExtractor.passthrough_smuggled_data
def _real_extract(self, url, smuggled_data):
item_id = self._match_id(url)
@@ -6556,6 +6569,10 @@ class YoutubeTabIE(YoutubeTabBaseInfoExtractor):
selected_tab_id, selected_tab_name = self._extract_tab_id_and_name(selected_tab, url) # NB: Name may be translated
self.write_debug(f'Selected tab: {selected_tab_id!r} ({selected_tab_name}), Requested tab: {original_tab_id!r}')
# /about is no longer a tab
if original_tab_id == 'about':
return self._empty_playlist(item_id, data)
if not original_tab_id and selected_tab_name:
self.to_screen('Downloading all uploads of the channel. '
'To download only the videos in a specific tab, pass the tab\'s URL')
@@ -6568,7 +6585,7 @@ class YoutubeTabIE(YoutubeTabBaseInfoExtractor):
if not extra_tabs and selected_tab_id != 'videos':
# Channel does not have streams, shorts or videos tabs
if item_id[:2] != 'UC':
raise ExtractorError('This channel has no uploads', expected=True)
return self._empty_playlist(item_id, data)
# Topic channels don't have /videos. Use the equivalent playlist instead
pl_id = f'UU{item_id[2:]}'
@@ -6576,7 +6593,7 @@ class YoutubeTabIE(YoutubeTabBaseInfoExtractor):
try:
data, ytcfg = self._extract_data(pl_url, pl_id, ytcfg=ytcfg, fatal=True, webpage_fatal=True)
except ExtractorError:
raise ExtractorError('This channel has no uploads', expected=True)
return self._empty_playlist(item_id, data)
else:
item_id, url = pl_id, pl_url
self.to_screen(
@@ -6708,7 +6725,7 @@ class YoutubePlaylistIE(InfoExtractor):
'uploader_url': 'https://www.youtube.com/@milan5503',
'availability': 'public',
},
'expected_warnings': [r'[Uu]navailable videos? (is|are|will be) hidden'],
'expected_warnings': [r'[Uu]navailable videos? (is|are|will be) hidden', 'Retrying', 'Giving up'],
}, {
'url': 'http://www.youtube.com/embed/_xDOZElKyNU?list=PLsyOSbh5bs16vubvKePAQ1x3PhKavfBIl',
'playlist_mincount': 455,