diff --git a/yt_dlp/extractor/youtube/_video.py b/yt_dlp/extractor/youtube/_video.py index ff74195649..48e599e430 100644 --- a/yt_dlp/extractor/youtube/_video.py +++ b/yt_dlp/extractor/youtube/_video.py @@ -79,6 +79,7 @@ STREAMING_DATA_FETCH_GVS_PO_TOKEN = '__yt_dlp_fetch_gvs_po_token' STREAMING_DATA_PLAYER_TOKEN_PROVIDED = '__yt_dlp_player_token_provided' STREAMING_DATA_INNERTUBE_CONTEXT = '__yt_dlp_innertube_context' STREAMING_DATA_IS_PREMIUM_SUBSCRIBER = '__yt_dlp_is_premium_subscriber' +STREAMING_DATA_FETCHED_TIMESTAMP = '__yt_dlp_fetched_timestamp' PO_TOKEN_GUIDE_URL = 'https://github.com/yt-dlp/yt-dlp/wiki/PO-Token-Guide' @@ -3244,6 +3245,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor): elif pr: # Save client details for introspection later innertube_context = traverse_obj(player_ytcfg or self._get_default_ytcfg(client), 'INNERTUBE_CONTEXT') + fetched_timestamp = int(time.time()) sd = pr.setdefault('streamingData', {}) sd[STREAMING_DATA_CLIENT_NAME] = client sd[STREAMING_DATA_FETCH_GVS_PO_TOKEN] = fetch_gvs_po_token_func @@ -3256,6 +3258,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor): f[STREAMING_DATA_FETCH_GVS_PO_TOKEN] = fetch_gvs_po_token_func f[STREAMING_DATA_IS_PREMIUM_SUBSCRIBER] = is_premium_subscriber f[STREAMING_DATA_PLAYER_TOKEN_PROVIDED] = bool(player_po_token) + f[STREAMING_DATA_FETCHED_TIMESTAMP] = fetched_timestamp if deprioritize_pr: deprioritized_prs.append(pr) else: @@ -3372,8 +3375,12 @@ class YoutubeIE(YoutubeBaseInfoExtractor): # save pots per client to avoid fetching again gvs_pots = {} + # For handling potential pre-playback required waiting period + playback_wait = int_or_none(self._configuration_arg('playback_wait', [None])[0], default=6) + for fmt in streaming_formats: client_name = fmt[STREAMING_DATA_CLIENT_NAME] + available_at = fmt[STREAMING_DATA_FETCHED_TIMESTAMP] + playback_wait if fmt.get('targetDurationSec'): continue @@ -3555,6 +3562,10 @@ class YoutubeIE(YoutubeBaseInfoExtractor): if single_stream and dct.get('ext'): dct['container'] = dct['ext'] + '_dash' + # For handling potential pre-playback required waiting period + if live_status not in ('is_live', 'post_live'): + dct['available_at'] = available_at + if (all_formats or 'dashy' in format_types) and dct['filesize']: yield { **dct, @@ -3592,6 +3603,10 @@ class YoutubeIE(YoutubeBaseInfoExtractor): if not all_formats and key in itags[itag]: return False + # For handling potential pre-playback required waiting period + if live_status not in ('is_live', 'post_live'): + f['available_at'] = available_at + if f.get('source_preference') is None: f['source_preference'] = -1 @@ -4037,12 +4052,6 @@ class YoutubeIE(YoutubeBaseInfoExtractor): if needs_live_processing: self._prepare_live_from_start_formats( formats, video_id, live_start_time, url, webpage_url, smuggled_data, live_status == 'is_live') - elif live_status != 'is_live': - # Handle pre-playback waiting period - playback_wait = int_or_none(self._configuration_arg('playback_wait', [None])[0], default=6) - available_at = int(time.time()) + playback_wait - for fmt in formats: - fmt['available_at'] = available_at formats.extend(self._extract_storyboard(player_responses, duration))