Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/youtube/_video.py (Python)

Code before:
                self._configuration_arg('player_params', [None], casesense=True)[0]
                or traverse_obj(INNERTUBE_CLIENTS, (webpage_client, 'PLAYER_PARAMS', {str}))
            )
            if pp:
                query['pp'] = pp
            webpage = self._download_webpage_with_retries(
                webpage_url, video_id, query=query,
                headers=traverse_obj(self._get_default_ytcfg(webpage_client), {
                    'User-Agent': ('INNERTUBE_CONTEXT', 'client', 'userAgent', {str}),
                }))
        return webpage

    def _get_preroll_length(self, ad_slot_lists):
        for ad_slot in traverse_obj(ad_slot_lists, ('adSlots'), []):
            slot_renderer = traverse_obj(ad_slot, ('adSlotRenderer'))
            trigger = traverse_obj(slot_renderer, ('adSlotMetadata', 'triggerEvent'))
            if trigger != 'SLOT_TRIGGER_EVENT_BEFORE_CONTENT':
                continue
            instream_ad_renderer = traverse_obj(slot_renderer, ('fulfillmentContent', 'fulfilledLayout', 'playerBytesAdLayoutRenderer', 'renderingContent', 'instreamVideoAdRenderer'))
            skip_time = traverse_obj(instream_ad_renderer, ('skipOffsetMilliseconds'))
            if skip_time is not None:
                return skip_time
            length = traverse_obj(instream_ad_renderer, ('playerVars', {urllib.parse.parse_qs}, 'length_seconds', 0))
            if length is not None:
                return int(length) * 1000
        return 0

    def _list_formats(self, video_id, microformats, video_details, player_responses, player_url, duration=None):
        live_broadcast_details = traverse_obj(microformats, (..., 'liveBroadcastDetails'))
        is_live = get_first(video_details, 'isLive')
        if is_live is None:
            is_live = get_first(live_broadcast_details, 'isLiveNow')
        live_content = get_first(video_details, 'isLiveContent')
        is_upcoming = get_first(video_details, 'isUpcoming')
        post_live = get_first(video_details, 'isPostLiveDvr')
        live_status = ('post_live' if post_live
                       else 'is_live' if is_live
                       else 'is_upcoming' if is_upcoming
                       else 'was_live' if live_content
                       else 'not_live' if False in (is_live, live_content)
                       else None)
        streaming_data = traverse_obj(player_responses, (..., 'streamingData'))
        *formats, subtitles = self._extract_formats_and_subtitles(streaming_data, video_id, player_url, live_status, duration)
        if all(f.get('has_drm') for f in formats):
            # If there are no formats that definitely don't have DRM, all have DRM
            for f in formats:
                f['has_drm'] = True

        return live_broadcast_details, live_status, streaming_data, formats, subtitles

    def _download_initial_data(self, video_id, webpage, webpage_client, webpage_ytcfg):

Review comment (suggestion):
```suggestion
            seconds = traverse_obj(instream_ad_renderer, ('playerVars', {urllib.parse.parse_qs}, 'length_seconds', -1, {int_or_none}))
            if seconds is not None:
                return seconds * 1000
        return 0
```

Code after:
            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 = (
            (self._preferred_lang and translated_description)
            # 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,
            ('multicamera', 'playerLegacyMulticameraRenderer', 'metadataList'),
            expected_type=str)
        if multifeed_metadata_list and not smuggled_data.get('force_singlefeed'):
            if self.get_param('noplaylist'):
                self.to_screen(f'Downloading just video {video_id} because of --no-playlist')
            else:
                entries = []
                feed_ids = []
                for feed in multifeed_metadata_list.split(','):