|
|
@ -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_PLAYER_TOKEN_PROVIDED = '__yt_dlp_player_token_provided'
|
|
|
|
STREAMING_DATA_INNERTUBE_CONTEXT = '__yt_dlp_innertube_context'
|
|
|
|
STREAMING_DATA_INNERTUBE_CONTEXT = '__yt_dlp_innertube_context'
|
|
|
|
STREAMING_DATA_IS_PREMIUM_SUBSCRIBER = '__yt_dlp_is_premium_subscriber'
|
|
|
|
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'
|
|
|
|
PO_TOKEN_GUIDE_URL = 'https://github.com/yt-dlp/yt-dlp/wiki/PO-Token-Guide'
|
|
|
|
|
|
|
|
|
|
|
@ -3244,6 +3245,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
|
|
|
elif pr:
|
|
|
|
elif pr:
|
|
|
|
# Save client details for introspection later
|
|
|
|
# Save client details for introspection later
|
|
|
|
innertube_context = traverse_obj(player_ytcfg or self._get_default_ytcfg(client), 'INNERTUBE_CONTEXT')
|
|
|
|
innertube_context = traverse_obj(player_ytcfg or self._get_default_ytcfg(client), 'INNERTUBE_CONTEXT')
|
|
|
|
|
|
|
|
fetched_timestamp = int(time.time())
|
|
|
|
sd = pr.setdefault('streamingData', {})
|
|
|
|
sd = pr.setdefault('streamingData', {})
|
|
|
|
sd[STREAMING_DATA_CLIENT_NAME] = client
|
|
|
|
sd[STREAMING_DATA_CLIENT_NAME] = client
|
|
|
|
sd[STREAMING_DATA_FETCH_GVS_PO_TOKEN] = fetch_gvs_po_token_func
|
|
|
|
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_FETCH_GVS_PO_TOKEN] = fetch_gvs_po_token_func
|
|
|
|
f[STREAMING_DATA_IS_PREMIUM_SUBSCRIBER] = is_premium_subscriber
|
|
|
|
f[STREAMING_DATA_IS_PREMIUM_SUBSCRIBER] = is_premium_subscriber
|
|
|
|
f[STREAMING_DATA_PLAYER_TOKEN_PROVIDED] = bool(player_po_token)
|
|
|
|
f[STREAMING_DATA_PLAYER_TOKEN_PROVIDED] = bool(player_po_token)
|
|
|
|
|
|
|
|
f[STREAMING_DATA_FETCHED_TIMESTAMP] = fetched_timestamp
|
|
|
|
if deprioritize_pr:
|
|
|
|
if deprioritize_pr:
|
|
|
|
deprioritized_prs.append(pr)
|
|
|
|
deprioritized_prs.append(pr)
|
|
|
|
else:
|
|
|
|
else:
|
|
|
@ -3372,8 +3375,12 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
|
|
|
# save pots per client to avoid fetching again
|
|
|
|
# save pots per client to avoid fetching again
|
|
|
|
gvs_pots = {}
|
|
|
|
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:
|
|
|
|
for fmt in streaming_formats:
|
|
|
|
client_name = fmt[STREAMING_DATA_CLIENT_NAME]
|
|
|
|
client_name = fmt[STREAMING_DATA_CLIENT_NAME]
|
|
|
|
|
|
|
|
available_at = fmt[STREAMING_DATA_FETCHED_TIMESTAMP] + playback_wait
|
|
|
|
if fmt.get('targetDurationSec'):
|
|
|
|
if fmt.get('targetDurationSec'):
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
|
@ -3555,6 +3562,10 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
|
|
|
if single_stream and dct.get('ext'):
|
|
|
|
if single_stream and dct.get('ext'):
|
|
|
|
dct['container'] = dct['ext'] + '_dash'
|
|
|
|
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']:
|
|
|
|
if (all_formats or 'dashy' in format_types) and dct['filesize']:
|
|
|
|
yield {
|
|
|
|
yield {
|
|
|
|
**dct,
|
|
|
|
**dct,
|
|
|
@ -3592,6 +3603,10 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
|
|
|
if not all_formats and key in itags[itag]:
|
|
|
|
if not all_formats and key in itags[itag]:
|
|
|
|
return False
|
|
|
|
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:
|
|
|
|
if f.get('source_preference') is None:
|
|
|
|
f['source_preference'] = -1
|
|
|
|
f['source_preference'] = -1
|
|
|
|
|
|
|
|
|
|
|
@ -4037,12 +4052,6 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
|
|
|
if needs_live_processing:
|
|
|
|
if needs_live_processing:
|
|
|
|
self._prepare_live_from_start_formats(
|
|
|
|
self._prepare_live_from_start_formats(
|
|
|
|
formats, video_id, live_start_time, url, webpage_url, smuggled_data, live_status == 'is_live')
|
|
|
|
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))
|
|
|
|
formats.extend(self._extract_storyboard(player_responses, duration))
|
|
|
|
|
|
|
|
|
|
|
|