diff --git a/yt_dlp/extractor/youtube/_video.py b/yt_dlp/extractor/youtube/_video.py index 14582c5f98..7986a43ec4 100644 --- a/yt_dlp/extractor/youtube/_video.py +++ b/yt_dlp/extractor/youtube/_video.py @@ -3850,11 +3850,33 @@ class YoutubeIE(YoutubeBaseInfoExtractor): player_responses, (..., 'microformat', 'playerMicroformatRenderer'), expected_type=dict) + # Fallbacks in case player responses are missing metadata + initial_sdcr = traverse_obj(initial_data, ( + 'engagementPanels', ..., 'engagementPanelSectionListRenderer', + 'content', 'structuredDescriptionContentRenderer', {dict}, any)) + initial_description = traverse_obj(initial_sdcr, ( + 'items', ..., 'expandableVideoDescriptionBodyRenderer', + 'attributedDescriptionBodyText', 'content', {str}, any)) + # videoDescriptionHeaderRenderer also has publishDate/channel/handle/ucid, but not needed + initial_vdhr = traverse_obj(initial_sdcr, ( + 'items', ..., 'videoDescriptionHeaderRenderer', {dict}, any)) or {} + initial_video_details_renderer = traverse_obj(initial_data, ( + 'playerOverlays', 'playerOverlayRenderer', 'videoDetails', + 'playerOverlayVideoDetailsRenderer', {dict})) or {} + initial_title = ( + self._get_text(initial_vdhr, 'title') + or self._get_text(initial_video_details_renderer, 'title')) + translated_title = self._get_text(microformats, (..., 'title')) video_title = ((self._preferred_lang and translated_title) or get_first(video_details, 'title') # primary or translated_title or search_meta(['og:title', 'twitter:title', 'title'])) + if not video_title and initial_title: + self.report_warning( + 'No title found in player responses; falling back to title from initial data. ' + 'Other metadata may also be missing') + video_title = initial_title translated_description = self._get_text(microformats, (..., 'description')) original_description = get_first(video_details, 'shortDescription') video_description = ( @@ -3862,6 +3884,8 @@ class YoutubeIE(YoutubeBaseInfoExtractor): # If original description is blank, it will be an empty string. # Do not prefer translated description in this case. or original_description if original_description is not None else translated_description) + if video_description is None: + video_description = initial_description multifeed_metadata_list = get_first( player_responses,