yt-dlp 2025.11.21.232936.dev0__py3-none-any.whl → 2025.11.23.5251.dev0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -76,7 +76,7 @@ STREAMING_DATA_FETCH_GVS_PO_TOKEN = '__yt_dlp_fetch_gvs_po_token'
76
76
  STREAMING_DATA_PLAYER_TOKEN_PROVIDED = '__yt_dlp_player_token_provided'
77
77
  STREAMING_DATA_INNERTUBE_CONTEXT = '__yt_dlp_innertube_context'
78
78
  STREAMING_DATA_IS_PREMIUM_SUBSCRIBER = '__yt_dlp_is_premium_subscriber'
79
- STREAMING_DATA_FETCHED_TIMESTAMP = '__yt_dlp_fetched_timestamp'
79
+ STREAMING_DATA_AVAILABLE_AT_TIMESTAMP = '__yt_dlp_available_at_timestamp'
80
80
 
81
81
  PO_TOKEN_GUIDE_URL = 'https://github.com/yt-dlp/yt-dlp/wiki/PO-Token-Guide'
82
82
 
@@ -3032,7 +3032,6 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
3032
3032
  elif pr:
3033
3033
  # Save client details for introspection later
3034
3034
  innertube_context = traverse_obj(player_ytcfg or self._get_default_ytcfg(client), 'INNERTUBE_CONTEXT')
3035
- fetched_timestamp = int(time.time())
3036
3035
  sd = pr.setdefault('streamingData', {})
3037
3036
  sd[STREAMING_DATA_CLIENT_NAME] = client
3038
3037
  sd[STREAMING_DATA_FETCH_GVS_PO_TOKEN] = fetch_gvs_po_token_func
@@ -3040,7 +3039,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
3040
3039
  sd[STREAMING_DATA_INNERTUBE_CONTEXT] = innertube_context
3041
3040
  sd[STREAMING_DATA_FETCH_SUBS_PO_TOKEN] = fetch_subs_po_token_func
3042
3041
  sd[STREAMING_DATA_IS_PREMIUM_SUBSCRIBER] = is_premium_subscriber
3043
- sd[STREAMING_DATA_FETCHED_TIMESTAMP] = fetched_timestamp
3042
+ sd[STREAMING_DATA_AVAILABLE_AT_TIMESTAMP] = self._get_available_at_timestamp(pr, video_id, client)
3044
3043
  for f in traverse_obj(sd, (('formats', 'adaptiveFormats'), ..., {dict})):
3045
3044
  f[STREAMING_DATA_CLIENT_NAME] = client
3046
3045
  f[STREAMING_DATA_FETCH_GVS_PO_TOKEN] = fetch_gvs_po_token_func
@@ -3172,9 +3171,6 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
3172
3171
  # save pots per client to avoid fetching again
3173
3172
  gvs_pots = {}
3174
3173
 
3175
- # For handling potential pre-playback required waiting period
3176
- playback_wait = int_or_none(self._configuration_arg('playback_wait', [None])[0], default=6)
3177
-
3178
3174
  def get_language_code_and_preference(fmt_stream):
3179
3175
  audio_track = fmt_stream.get('audioTrack') or {}
3180
3176
  display_name = audio_track.get('displayName') or ''
@@ -3199,7 +3195,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
3199
3195
  is_premium_subscriber = streaming_data[STREAMING_DATA_IS_PREMIUM_SUBSCRIBER]
3200
3196
  player_token_provided = streaming_data[STREAMING_DATA_PLAYER_TOKEN_PROVIDED]
3201
3197
  client_name = streaming_data.get(STREAMING_DATA_CLIENT_NAME)
3202
- available_at = streaming_data[STREAMING_DATA_FETCHED_TIMESTAMP] + playback_wait
3198
+ available_at = streaming_data[STREAMING_DATA_AVAILABLE_AT_TIMESTAMP]
3203
3199
  streaming_formats = traverse_obj(streaming_data, (('formats', 'adaptiveFormats'), ...))
3204
3200
 
3205
3201
  def get_stream_id(fmt_stream):
@@ -3653,6 +3649,36 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
3653
3649
  }))
3654
3650
  return webpage
3655
3651
 
3652
+ def _get_available_at_timestamp(self, player_response, video_id, client):
3653
+ now = time.time()
3654
+ wait_seconds = 0
3655
+
3656
+ for renderer in traverse_obj(player_response, (
3657
+ 'adSlots', lambda _, v: v['adSlotRenderer']['adSlotMetadata']['triggerEvent'] == 'SLOT_TRIGGER_EVENT_BEFORE_CONTENT',
3658
+ 'adSlotRenderer', 'fulfillmentContent', 'fulfilledLayout', 'playerBytesAdLayoutRenderer', 'renderingContent', (
3659
+ None,
3660
+ ('playerBytesSequentialLayoutRenderer', 'sequentialLayouts', ..., 'playerBytesAdLayoutRenderer', 'renderingContent'),
3661
+ ), 'instreamVideoAdRenderer', {dict},
3662
+ )):
3663
+ duration = traverse_obj(renderer, ('playerVars', {urllib.parse.parse_qs}, 'length_seconds', -1, {int_or_none}))
3664
+ ad = 'an ad' if duration is None else f'a {duration}s ad'
3665
+
3666
+ skip_time = traverse_obj(renderer, ('skipOffsetMilliseconds', {float_or_none(scale=1000)}))
3667
+ if skip_time is not None:
3668
+ # YT allows skipping this ad; use the wait-until-skip time instead of full ad duration
3669
+ skip_time = skip_time if skip_time % 1 else int(skip_time)
3670
+ ad += f' skippable after {skip_time}s'
3671
+ duration = skip_time
3672
+
3673
+ if duration is not None:
3674
+ self.write_debug(f'{video_id}: Detected {ad} for {client}')
3675
+ wait_seconds += duration
3676
+
3677
+ if wait_seconds:
3678
+ return math.ceil(now) + wait_seconds
3679
+
3680
+ return int(now)
3681
+
3656
3682
  def _list_formats(self, video_id, microformats, video_details, player_responses, player_url, duration=None):
3657
3683
  live_broadcast_details = traverse_obj(microformats, (..., 'liveBroadcastDetails'))
3658
3684
  is_live = get_first(video_details, 'isLive')
yt_dlp/version.py CHANGED
@@ -1,8 +1,8 @@
1
1
  # Autogenerated by devscripts/update-version.py
2
2
 
3
- __version__ = '2025.11.21.232936'
3
+ __version__ = '2025.11.23.005251'
4
4
 
5
- RELEASE_GIT_HEAD = '0c696239ef418776ac6ba20284bd2f3976a011b4'
5
+ RELEASE_GIT_HEAD = '715af0c636b2b33fb3df1eb2ee37eac8262d43ac'
6
6
 
7
7
  VARIANT = 'pip'
8
8
 
@@ -12,4 +12,4 @@ CHANNEL = 'nightly'
12
12
 
13
13
  ORIGIN = 'yt-dlp/yt-dlp-nightly-builds'
14
14
 
15
- _pkg_version = '2025.11.21.232936dev'
15
+ _pkg_version = '2025.11.23.005251dev'
@@ -2375,9 +2375,6 @@ youtube
2375
2375
  requires one for the given context), never (never fetch a PO Token),
2376
2376
  or auto (default; only fetch a PO Token if the client requires one
2377
2377
  for the given context)
2378
- - playback_wait: Duration (in seconds) to wait inbetween the
2379
- extraction and download stages in order to ensure the formats are
2380
- available. The default is 6 seconds
2381
2378
  - jsc_trace: Enable debug logging for JS Challenge fetching. Either
2382
2379
  true or false (default)
2383
2380
 
@@ -2818,11 +2818,6 @@ client requires one for the given context), \f[V]never\f[R] (never fetch
2818
2818
  a PO Token), or \f[V]auto\f[R] (default; only fetch a PO Token if the
2819
2819
  client requires one for the given context)
2820
2820
  .IP \[bu] 2
2821
- \f[V]playback_wait\f[R]: Duration (in seconds) to wait inbetween the
2822
- extraction and download stages in order to ensure the formats are
2823
- available.
2824
- The default is \f[V]6\f[R] seconds
2825
- .IP \[bu] 2
2826
2821
  \f[V]jsc_trace\f[R]: Enable debug logging for JS Challenge fetching.
2827
2822
  Either \f[V]true\f[R] or \f[V]false\f[R] (default)
2828
2823
  .SS youtube-ejs
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: yt-dlp
3
- Version: 2025.11.21.232936.dev0
3
+ Version: 2025.11.23.5251.dev0
4
4
  Summary: A feature-rich command-line audio/video downloader
5
5
  Project-URL: Documentation, https://github.com/yt-dlp/yt-dlp#readme
6
6
  Project-URL: Repository, https://github.com/yt-dlp/yt-dlp
@@ -1939,7 +1939,6 @@ The following extractors use this feature:
1939
1939
  * `po_token`: Proof of Origin (PO) Token(s) to use. Comma seperated list of PO Tokens in the format `CLIENT.CONTEXT+PO_TOKEN`, e.g. `youtube:po_token=web.gvs+XXX,web.player=XXX,web_safari.gvs+YYY`. Context can be any of `gvs` (Google Video Server URLs), `player` (Innertube player request) or `subs` (Subtitles)
1940
1940
  * `pot_trace`: Enable debug logging for PO Token fetching. Either `true` or `false` (default)
1941
1941
  * `fetch_pot`: Policy to use for fetching a PO Token from providers. One of `always` (always try fetch a PO Token regardless if the client requires one for the given context), `never` (never fetch a PO Token), or `auto` (default; only fetch a PO Token if the client requires one for the given context)
1942
- * `playback_wait`: Duration (in seconds) to wait inbetween the extraction and download stages in order to ensure the formats are available. The default is `6` seconds
1943
1942
  * `jsc_trace`: Enable debug logging for JS Challenge fetching. Either `true` or `false` (default)
1944
1943
 
1945
1944
  #### youtube-ejs
@@ -11,7 +11,7 @@ yt_dlp/options.py,sha256=Icc0JRiKOzITWoMujE_ihEmkCS-uCcie42XhIh8LvS4,100388
11
11
  yt_dlp/plugins.py,sha256=EGmR0ydaahNspGrgszTNX4-YjHe93WOOhcw1gf6PZSs,8215
12
12
  yt_dlp/socks.py,sha256=oAuAfWM6jxI8A5hHDLEKq2U2-k9NyMB_z6nrKzNE9fg,8936
13
13
  yt_dlp/update.py,sha256=sY7gNFBQorzs7sEjRrqL5QOsTBNmGGa_FnpTtbxY1vA,25280
14
- yt_dlp/version.py,sha256=zz7xzUplK3l5P2uzb6hryJuPLREAjw_0eO1jVJRP1Zo,360
14
+ yt_dlp/version.py,sha256=wZtfH01wffjia452sDKTTNzqXADrpdph1Hn2zmdLu6g,360
15
15
  yt_dlp/webvtt.py,sha256=ONkXaaNCZcX8pQhJn3iwIKyaQ34BtVDrMEdG6wRNZwM,11451
16
16
  yt_dlp/__pyinstaller/__init__.py,sha256=-c4Zo8nQGKAm8wc_LDscxMtK7zr_YhZwRnC9CMruUBE,72
17
17
  yt_dlp/__pyinstaller/hook-yt_dlp.py,sha256=5Rd0zV2pDskjY1KtT0wsjxv4hStx67sLCjUexsFvFus,1339
@@ -1066,7 +1066,7 @@ yt_dlp/extractor/youtube/_notifications.py,sha256=1nhavzW0e2QWFAWHkfbTU4sSXNp4vU
1066
1066
  yt_dlp/extractor/youtube/_redirect.py,sha256=WWWnGEkfSGBXpZFi_bWY4XcHZ8PDeK7UsndDaTYYhQg,9005
1067
1067
  yt_dlp/extractor/youtube/_search.py,sha256=E9raTPGjUD6mm81WBpT4AsaxyiTBHdNssgzeHwVeNOE,6552
1068
1068
  yt_dlp/extractor/youtube/_tab.py,sha256=NcbpPvJ4XiTDDNBtaLtCZQBKyo2HuNcq_V-AalY8zj8,115736
1069
- yt_dlp/extractor/youtube/_video.py,sha256=eufl1QR9LllGqUjgZ4gpQNvYblSK8JFBb4tXM-2JiEQ,206909
1069
+ yt_dlp/extractor/youtube/_video.py,sha256=cMwrTnCHthcP92N_lH1O0epFR5WC8UhPeHw6Z2cgpPk,208247
1070
1070
  yt_dlp/extractor/youtube/jsc/__init__.py,sha256=HaVFP8ikrLaE-ClAh39-S28WCF4S2KTRaSu7QvA28E8,289
1071
1071
  yt_dlp/extractor/youtube/jsc/_director.py,sha256=92pB-KVSs6plmE5R8gpjkZL9aeoWNR0XTnGOBXMy9go,13167
1072
1072
  yt_dlp/extractor/youtube/jsc/_registry.py,sha256=Vg9GkHKHKKPeRfUQ-XSw01mfx_2Xyodh0SJpwjawYCA,102
@@ -1122,13 +1122,13 @@ yt_dlp/utils/progress.py,sha256=t9kVvJ0oWuEqRzo9fdFbIhHUBtO_8mg348QwZ1faqLo,3261
1122
1122
  yt_dlp/utils/traversal.py,sha256=64E3RcZ56iSX50RI_HbKdDNftkETMLBaEPX791_b7yQ,18265
1123
1123
  yt_dlp/utils/jslib/__init__.py,sha256=CbdJiRA7Eh5PnjF2V4lDTcg0J0XjBMaaq0H4pCfq9Tk,87
1124
1124
  yt_dlp/utils/jslib/devalue.py,sha256=7DCGK_zUN0ZeV5hwPT06zaRMUxX_hyUyFWqs79rxw24,5621
1125
- yt_dlp-2025.11.21.232936.dev0.data/data/share/bash-completion/completions/yt-dlp,sha256=b0pb9GLseKD27CjnLE6LlhVxhfmQjmyqV6r_CRbd6ko,5989
1126
- yt_dlp-2025.11.21.232936.dev0.data/data/share/doc/yt_dlp/README.txt,sha256=1p-zv2tZPh1gscLG3ceL7GGCzC4TQU8mS9wiqPS-oXE,164662
1127
- yt_dlp-2025.11.21.232936.dev0.data/data/share/fish/vendor_completions.d/yt-dlp.fish,sha256=hLa6lZnm7keENpNCjml9A88hbvefdsdoOpAiaNCVyHo,51488
1128
- yt_dlp-2025.11.21.232936.dev0.data/data/share/man/man1/yt-dlp.1,sha256=C33_xKvu5DD5SScnivPeV2EJEYSeJ1tPXYZnlJBDayc,159125
1129
- yt_dlp-2025.11.21.232936.dev0.data/data/share/zsh/site-functions/_yt-dlp,sha256=pNhu8tT4ZKrksLRI2mXLqarzGGhnOlm_hkCBVhSxLzg,5985
1130
- yt_dlp-2025.11.21.232936.dev0.dist-info/METADATA,sha256=sD1VdkhZtYG6Ov_6RoqOQDHQ-bS2ch1uzKBWegJfvT8,180054
1131
- yt_dlp-2025.11.21.232936.dev0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
1132
- yt_dlp-2025.11.21.232936.dev0.dist-info/entry_points.txt,sha256=vWfetvzYgZIwDfMW6BjCe0Cy4pmTZEXRNzxAkfYlRJA,103
1133
- yt_dlp-2025.11.21.232936.dev0.dist-info/licenses/LICENSE,sha256=fhLl30uuEsshWBuhV87SDhmGoFCN0Q0Oikq5pM-U6Fw,1211
1134
- yt_dlp-2025.11.21.232936.dev0.dist-info/RECORD,,
1125
+ yt_dlp-2025.11.23.5251.dev0.data/data/share/bash-completion/completions/yt-dlp,sha256=b0pb9GLseKD27CjnLE6LlhVxhfmQjmyqV6r_CRbd6ko,5989
1126
+ yt_dlp-2025.11.23.5251.dev0.data/data/share/doc/yt_dlp/README.txt,sha256=aO1yTJrp0tKhrdUa5fWmMnVxkrpUi0u3FoYo2uE2rVo,164489
1127
+ yt_dlp-2025.11.23.5251.dev0.data/data/share/fish/vendor_completions.d/yt-dlp.fish,sha256=hLa6lZnm7keENpNCjml9A88hbvefdsdoOpAiaNCVyHo,51488
1128
+ yt_dlp-2025.11.23.5251.dev0.data/data/share/man/man1/yt-dlp.1,sha256=YyGTf0wqbKUSsZigQ_6pOsAvxMyXNv_pd-6KmDBOrIY,158932
1129
+ yt_dlp-2025.11.23.5251.dev0.data/data/share/zsh/site-functions/_yt-dlp,sha256=pNhu8tT4ZKrksLRI2mXLqarzGGhnOlm_hkCBVhSxLzg,5985
1130
+ yt_dlp-2025.11.23.5251.dev0.dist-info/METADATA,sha256=ommtPdgOK2FzFmCXYaR-IEWMGk0nDdWeXcSAho6Qkq8,179885
1131
+ yt_dlp-2025.11.23.5251.dev0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
1132
+ yt_dlp-2025.11.23.5251.dev0.dist-info/entry_points.txt,sha256=vWfetvzYgZIwDfMW6BjCe0Cy4pmTZEXRNzxAkfYlRJA,103
1133
+ yt_dlp-2025.11.23.5251.dev0.dist-info/licenses/LICENSE,sha256=fhLl30uuEsshWBuhV87SDhmGoFCN0Q0Oikq5pM-U6Fw,1211
1134
+ yt_dlp-2025.11.23.5251.dev0.dist-info/RECORD,,