yt-dlp 2025.11.21.232936.dev0__py3-none-any.whl → 2025.11.23.233008.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.
- yt_dlp/extractor/youtube/_video.py +33 -7
- yt_dlp/version.py +3 -3
- {yt_dlp-2025.11.21.232936.dev0.data → yt_dlp-2025.11.23.233008.dev0.data}/data/share/doc/yt_dlp/README.txt +0 -3
- {yt_dlp-2025.11.21.232936.dev0.data → yt_dlp-2025.11.23.233008.dev0.data}/data/share/man/man1/yt-dlp.1 +0 -5
- {yt_dlp-2025.11.21.232936.dev0.dist-info → yt_dlp-2025.11.23.233008.dev0.dist-info}/METADATA +1 -2
- {yt_dlp-2025.11.21.232936.dev0.dist-info → yt_dlp-2025.11.23.233008.dev0.dist-info}/RECORD +12 -12
- {yt_dlp-2025.11.21.232936.dev0.data → yt_dlp-2025.11.23.233008.dev0.data}/data/share/bash-completion/completions/yt-dlp +0 -0
- {yt_dlp-2025.11.21.232936.dev0.data → yt_dlp-2025.11.23.233008.dev0.data}/data/share/fish/vendor_completions.d/yt-dlp.fish +0 -0
- {yt_dlp-2025.11.21.232936.dev0.data → yt_dlp-2025.11.23.233008.dev0.data}/data/share/zsh/site-functions/_yt-dlp +0 -0
- {yt_dlp-2025.11.21.232936.dev0.dist-info → yt_dlp-2025.11.23.233008.dev0.dist-info}/WHEEL +0 -0
- {yt_dlp-2025.11.21.232936.dev0.dist-info → yt_dlp-2025.11.23.233008.dev0.dist-info}/entry_points.txt +0 -0
- {yt_dlp-2025.11.21.232936.dev0.dist-info → yt_dlp-2025.11.23.233008.dev0.dist-info}/licenses/LICENSE +0 -0
|
@@ -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
|
-
|
|
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[
|
|
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[
|
|
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.
|
|
3
|
+
__version__ = '2025.11.23.233008'
|
|
4
4
|
|
|
5
|
-
RELEASE_GIT_HEAD = '
|
|
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.
|
|
15
|
+
_pkg_version = '2025.11.23.233008dev'
|
|
@@ -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
|
{yt_dlp-2025.11.21.232936.dev0.dist-info → yt_dlp-2025.11.23.233008.dev0.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: yt-dlp
|
|
3
|
-
Version: 2025.11.
|
|
3
|
+
Version: 2025.11.23.233008.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=
|
|
14
|
+
yt_dlp/version.py,sha256=d7hQ4GO9N8MkJpftg2fHU7BE5ZzVJ_fzBVzlBWPNIkQ,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=
|
|
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.
|
|
1126
|
-
yt_dlp-2025.11.
|
|
1127
|
-
yt_dlp-2025.11.
|
|
1128
|
-
yt_dlp-2025.11.
|
|
1129
|
-
yt_dlp-2025.11.
|
|
1130
|
-
yt_dlp-2025.11.
|
|
1131
|
-
yt_dlp-2025.11.
|
|
1132
|
-
yt_dlp-2025.11.
|
|
1133
|
-
yt_dlp-2025.11.
|
|
1134
|
-
yt_dlp-2025.11.
|
|
1125
|
+
yt_dlp-2025.11.23.233008.dev0.data/data/share/bash-completion/completions/yt-dlp,sha256=b0pb9GLseKD27CjnLE6LlhVxhfmQjmyqV6r_CRbd6ko,5989
|
|
1126
|
+
yt_dlp-2025.11.23.233008.dev0.data/data/share/doc/yt_dlp/README.txt,sha256=aO1yTJrp0tKhrdUa5fWmMnVxkrpUi0u3FoYo2uE2rVo,164489
|
|
1127
|
+
yt_dlp-2025.11.23.233008.dev0.data/data/share/fish/vendor_completions.d/yt-dlp.fish,sha256=hLa6lZnm7keENpNCjml9A88hbvefdsdoOpAiaNCVyHo,51488
|
|
1128
|
+
yt_dlp-2025.11.23.233008.dev0.data/data/share/man/man1/yt-dlp.1,sha256=YyGTf0wqbKUSsZigQ_6pOsAvxMyXNv_pd-6KmDBOrIY,158932
|
|
1129
|
+
yt_dlp-2025.11.23.233008.dev0.data/data/share/zsh/site-functions/_yt-dlp,sha256=pNhu8tT4ZKrksLRI2mXLqarzGGhnOlm_hkCBVhSxLzg,5985
|
|
1130
|
+
yt_dlp-2025.11.23.233008.dev0.dist-info/METADATA,sha256=QlfLw0-s_x-635WTohvvP4V75DJO-Acakqqh_Y85_ds,179887
|
|
1131
|
+
yt_dlp-2025.11.23.233008.dev0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
1132
|
+
yt_dlp-2025.11.23.233008.dev0.dist-info/entry_points.txt,sha256=vWfetvzYgZIwDfMW6BjCe0Cy4pmTZEXRNzxAkfYlRJA,103
|
|
1133
|
+
yt_dlp-2025.11.23.233008.dev0.dist-info/licenses/LICENSE,sha256=fhLl30uuEsshWBuhV87SDhmGoFCN0Q0Oikq5pM-U6Fw,1211
|
|
1134
|
+
yt_dlp-2025.11.23.233008.dev0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{yt_dlp-2025.11.21.232936.dev0.dist-info → yt_dlp-2025.11.23.233008.dev0.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{yt_dlp-2025.11.21.232936.dev0.dist-info → yt_dlp-2025.11.23.233008.dev0.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|