yt-dlp 2026.1.27.233257.dev0__py3-none-any.whl → 2026.1.29.165626.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.
Files changed (19) hide show
  1. yt_dlp/YoutubeDL.py +14 -10
  2. yt_dlp/extractor/tarangplus.py +2 -1
  3. yt_dlp/extractor/vimeo.py +16 -1
  4. yt_dlp/extractor/whyp.py +15 -11
  5. yt_dlp/extractor/youtube/_base.py +32 -26
  6. yt_dlp/extractor/youtube/_video.py +15 -5
  7. yt_dlp/extractor/youtube/jsc/_builtin/vendor/_info.py +3 -3
  8. yt_dlp/extractor/youtube/jsc/_builtin/vendor/yt.solver.core.js +66 -13
  9. yt_dlp/version.py +3 -3
  10. {yt_dlp-2026.1.27.233257.dev0.data → yt_dlp-2026.1.29.165626.dev0.data}/data/share/doc/yt_dlp/README.txt +11 -10
  11. {yt_dlp-2026.1.27.233257.dev0.data → yt_dlp-2026.1.29.165626.dev0.data}/data/share/man/man1/yt-dlp.1 +10 -9
  12. {yt_dlp-2026.1.27.233257.dev0.dist-info → yt_dlp-2026.1.29.165626.dev0.dist-info}/METADATA +7 -7
  13. {yt_dlp-2026.1.27.233257.dev0.dist-info → yt_dlp-2026.1.29.165626.dev0.dist-info}/RECORD +19 -19
  14. {yt_dlp-2026.1.27.233257.dev0.data → yt_dlp-2026.1.29.165626.dev0.data}/data/share/bash-completion/completions/yt-dlp +0 -0
  15. {yt_dlp-2026.1.27.233257.dev0.data → yt_dlp-2026.1.29.165626.dev0.data}/data/share/fish/vendor_completions.d/yt-dlp.fish +0 -0
  16. {yt_dlp-2026.1.27.233257.dev0.data → yt_dlp-2026.1.29.165626.dev0.data}/data/share/zsh/site-functions/_yt-dlp +0 -0
  17. {yt_dlp-2026.1.27.233257.dev0.dist-info → yt_dlp-2026.1.29.165626.dev0.dist-info}/WHEEL +0 -0
  18. {yt_dlp-2026.1.27.233257.dev0.dist-info → yt_dlp-2026.1.29.165626.dev0.dist-info}/entry_points.txt +0 -0
  19. {yt_dlp-2026.1.27.233257.dev0.dist-info → yt_dlp-2026.1.29.165626.dev0.dist-info}/licenses/LICENSE +0 -0
yt_dlp/YoutubeDL.py CHANGED
@@ -1602,8 +1602,10 @@ class YoutubeDL:
1602
1602
  if ret is NO_DEFAULT:
1603
1603
  while True:
1604
1604
  filename = self._format_screen(self.prepare_filename(info_dict), self.Styles.FILENAME)
1605
- reply = input(self._format_screen(
1606
- f'Download "{filename}"? (Y/n): ', self.Styles.EMPHASIS)).lower().strip()
1605
+ self.to_screen(
1606
+ self._format_screen(f'Download "{filename}"? (Y/n): ', self.Styles.EMPHASIS),
1607
+ skip_eol=True)
1608
+ reply = input().lower().strip()
1607
1609
  if reply in {'y', ''}:
1608
1610
  return None
1609
1611
  elif reply == 'n':
@@ -3030,9 +3032,10 @@ class YoutubeDL:
3030
3032
  # Bypass interactive format selection if no formats & --ignore-no-formats-error
3031
3033
  formats_to_download = None
3032
3034
  break
3033
- req_format = input(self._format_screen('\nEnter format selector ', self.Styles.EMPHASIS)
3034
- + '(Press ENTER for default, or Ctrl+C to quit)'
3035
- + self._format_screen(': ', self.Styles.EMPHASIS))
3035
+ self.to_screen(self._format_screen('\nEnter format selector ', self.Styles.EMPHASIS)
3036
+ + '(Press ENTER for default, or Ctrl+C to quit)'
3037
+ + self._format_screen(': ', self.Styles.EMPHASIS), skip_eol=True)
3038
+ req_format = input()
3036
3039
  try:
3037
3040
  format_selector = self.build_format_selector(req_format) if req_format else None
3038
3041
  except SyntaxError as err:
@@ -3478,11 +3481,12 @@ class YoutubeDL:
3478
3481
  if dl_filename is not None:
3479
3482
  self.report_file_already_downloaded(dl_filename)
3480
3483
  elif fd:
3481
- for f in info_dict['requested_formats'] if fd != FFmpegFD else []:
3482
- f['filepath'] = fname = prepend_extension(
3483
- correct_ext(temp_filename, info_dict['ext']),
3484
- 'f{}'.format(f['format_id']), info_dict['ext'])
3485
- downloaded.append(fname)
3484
+ if fd != FFmpegFD and temp_filename != '-':
3485
+ for f in info_dict['requested_formats']:
3486
+ f['filepath'] = fname = prepend_extension(
3487
+ correct_ext(temp_filename, info_dict['ext']),
3488
+ 'f{}'.format(f['format_id']), info_dict['ext'])
3489
+ downloaded.append(fname)
3486
3490
  info_dict['url'] = '\n'.join(f['url'] for f in info_dict['requested_formats'])
3487
3491
  success, real_download = self.dl(temp_filename, info_dict)
3488
3492
  info_dict['__real_download'] = real_download
@@ -11,6 +11,7 @@ from ..utils import (
11
11
  OnDemandPagedList,
12
12
  clean_html,
13
13
  extract_attributes,
14
+ url_or_none,
14
15
  urljoin,
15
16
  )
16
17
  from ..utils.traversal import (
@@ -128,7 +129,7 @@ class TarangPlusVideoIE(TarangPlusBaseIE):
128
129
  **traverse_obj(metadata, {
129
130
  'id': ('content_id', {str}),
130
131
  'title': ('title', {str}),
131
- 'thumbnail': ('image', {str}),
132
+ 'thumbnail': ('image', {url_or_none}),
132
133
  }),
133
134
  **traverse_obj(hidden_inputs_data, {
134
135
  'id': ('content_id', {str}),
yt_dlp/extractor/vimeo.py CHANGED
@@ -49,7 +49,7 @@ class VimeoBaseInfoExtractor(InfoExtractor):
49
49
  'Cannot download embed-only video without embedding URL. Please call yt-dlp '
50
50
  'with the URL of the page that embeds this video.')
51
51
 
52
- _DEFAULT_CLIENT = 'web'
52
+ _DEFAULT_CLIENT = 'macos'
53
53
  _DEFAULT_AUTHED_CLIENT = 'web'
54
54
  _CLIENT_HEADERS = {
55
55
  'Accept': 'application/vnd.vimeo.*+json; version=3.4.10',
@@ -87,6 +87,21 @@ class VimeoBaseInfoExtractor(InfoExtractor):
87
87
  'upload', 'transcode', 'is_playable', 'has_audio',
88
88
  ),
89
89
  },
90
+ 'macos': {
91
+ 'CACHE_KEY': 'oauth-token-macos',
92
+ 'CACHE_ONLY': False,
93
+ 'VIEWER_JWT': False,
94
+ 'REQUIRES_AUTH': False,
95
+ 'AUTH': 'NDc1N2JlN2Y5ZjZmMjU3NzE3NTRkZTg1NmY2YzU2MTI0OTFlNjJiYjpwVUNDWUlBZmZqSHhQcndBYWxGMzgyYys2NkN5d1JrREJZZXdPcEdsU05tdjFlVVo2aE1lYk9GcWE3ZW9KVldlYnFlOWh5Vno5UWtpUGJ5empYZFBpYkFwV0FFTnB5VWV4ZEh3aHZnRUNEL0VySnBzTmFraDdNbS9nMXhWanhIcw==',
96
+ 'USER_AGENT': 'Vimeo/1.6.3 (com.vimeo.mac; build:251121.142637.0; macOS 13.7.8) Alamofire/5.9.0 VimeoNetworking/5.0.0',
97
+ 'VIDEOS_FIELDS': (
98
+ 'uri', 'name', 'description', 'type', 'link', 'player_embed_url', 'duration', 'width',
99
+ 'language', 'height', 'embed', 'created_time', 'modified_time', 'release_time', 'content_rating',
100
+ 'content_rating_class', 'rating_mod_locked', 'license', 'privacy', 'pictures', 'tags', 'stats',
101
+ 'categories', 'uploader', 'metadata', 'user', 'files', 'download', 'app', 'play', 'status',
102
+ 'resource_key', 'badge', 'upload', 'transcode', 'is_playable', 'has_audio',
103
+ ),
104
+ },
90
105
  'web': {
91
106
  'CACHE_ONLY': False,
92
107
  'VIEWER_JWT': True,
yt_dlp/extractor/whyp.py CHANGED
@@ -1,6 +1,7 @@
1
1
  from .common import InfoExtractor
2
2
  from ..utils import (
3
3
  float_or_none,
4
+ int_or_none,
4
5
  str_or_none,
5
6
  traverse_obj,
6
7
  url_or_none,
@@ -11,17 +12,16 @@ class WhypIE(InfoExtractor):
11
12
  _VALID_URL = r'https?://(?:www\.)?whyp\.it/tracks/(?P<id>\d+)'
12
13
  _TESTS = [{
13
14
  'url': 'https://www.whyp.it/tracks/18337/home-page-example-track-b4kq7',
14
- 'md5': 'c1187b42ebf8605284e3dc92aeb33d16',
15
+ 'md5': '02fd96427acd9547445979bf0496b013',
15
16
  'info_dict': {
16
- 'url': 'https://cdn.whyp.it/50eb17cc-e9ff-4e18-b89b-dc9206a95cb1.mp3',
17
17
  'id': '18337',
18
- 'title': 'Home Page Example Track',
19
- 'description': 'md5:bd758000fb93f3159339c852b5b9133c',
20
- 'ext': 'mp3',
21
- 'duration': 52.82,
18
+ 'title': 'Example Track',
19
+ 'description': 'md5:e0b1bcf1d267dc1a0f15efff09c8f297',
20
+ 'ext': 'flac',
21
+ 'duration': 135.63,
22
22
  'uploader': 'Brad',
23
23
  'uploader_id': '1',
24
- 'thumbnail': 'https://cdn.whyp.it/a537bb36-3373-4c61-96c8-27fc1b2f427a.jpg',
24
+ 'thumbnail': 'https://cdn.whyp.it/6ad0bbd9-577d-42bb-9b61-2a4f57f647eb.jpg',
25
25
  },
26
26
  }, {
27
27
  'url': 'https://www.whyp.it/tracks/18337',
@@ -34,8 +34,15 @@ class WhypIE(InfoExtractor):
34
34
  data = self._search_nuxt_data(webpage, unique_id)['rawTrack']
35
35
 
36
36
  return {
37
- 'url': data['audio_url'],
38
37
  'id': unique_id,
38
+ 'formats': [{
39
+ 'url': data[f'{prefix}_url'],
40
+ 'format_id': prefix,
41
+ 'filesize': int_or_none(data.get(f'{prefix}_size')),
42
+ 'vcodec': 'none',
43
+ 'quality': 10 if prefix == 'lossless' else -1,
44
+ 'http_headers': {'Referer': 'https://whyp.it/'},
45
+ } for prefix in ('audio', 'lossy', 'lossless') if url_or_none(data.get(f'{prefix}_url'))],
39
46
  **traverse_obj(data, {
40
47
  'title': 'title',
41
48
  'description': 'description',
@@ -44,7 +51,4 @@ class WhypIE(InfoExtractor):
44
51
  'uploader_id': ('user', 'id', {str_or_none}),
45
52
  'thumbnail': ('artwork_url', {url_or_none}),
46
53
  }),
47
- 'ext': 'mp3',
48
- 'vcodec': 'none',
49
- 'http_headers': {'Referer': 'https://whyp.it/'},
50
54
  }
@@ -223,20 +223,6 @@ INNERTUBE_CLIENTS = {
223
223
  },
224
224
  'PLAYER_PO_TOKEN_POLICY': PlayerPoTokenPolicy(required=False, recommended=True),
225
225
  },
226
- # Doesn't require a PoToken for some reason
227
- 'android_sdkless': {
228
- 'INNERTUBE_CONTEXT': {
229
- 'client': {
230
- 'clientName': 'ANDROID',
231
- 'clientVersion': '21.02.35',
232
- 'userAgent': 'com.google.android.youtube/21.02.35 (Linux; U; Android 11) gzip',
233
- 'osName': 'Android',
234
- 'osVersion': '11',
235
- },
236
- },
237
- 'INNERTUBE_CONTEXT_CLIENT_NAME': 3,
238
- 'REQUIRE_JS_PLAYER': False,
239
- },
240
226
  # YouTube Kids videos aren't returned on this client for some reason
241
227
  'android_vr': {
242
228
  'INNERTUBE_CONTEXT': {
@@ -285,6 +271,34 @@ INNERTUBE_CLIENTS = {
285
271
  'PLAYER_PO_TOKEN_POLICY': PlayerPoTokenPolicy(required=False, recommended=True),
286
272
  'REQUIRE_JS_PLAYER': False,
287
273
  },
274
+ 'ios_downgraded': {
275
+ 'INNERTUBE_CONTEXT': {
276
+ 'client': {
277
+ 'clientName': 'IOS',
278
+ 'clientVersion': '19.49.7',
279
+ 'deviceMake': 'Apple',
280
+ 'deviceModel': 'iPhone16,2',
281
+ 'userAgent': 'com.google.ios.youtube/19.49.7 (iPhone16,2; U; CPU iOS 17_5_1 like Mac OS X;)',
282
+ 'osName': 'iPhone',
283
+ 'osVersion': '17.5.1.21F90',
284
+ },
285
+ },
286
+ 'INNERTUBE_CONTEXT_CLIENT_NAME': 5,
287
+ 'GVS_PO_TOKEN_POLICY': {
288
+ StreamingProtocol.HTTPS: GvsPoTokenPolicy(
289
+ required=True,
290
+ recommended=True,
291
+ not_required_with_player_token=True,
292
+ ),
293
+ StreamingProtocol.HLS: GvsPoTokenPolicy(
294
+ required=False,
295
+ recommended=True,
296
+ not_required_with_player_token=True,
297
+ ),
298
+ },
299
+ 'PLAYER_PO_TOKEN_POLICY': PlayerPoTokenPolicy(required=False, recommended=True),
300
+ 'REQUIRE_JS_PLAYER': False,
301
+ },
288
302
  # mweb has 'ultralow' formats
289
303
  # See: https://github.com/yt-dlp/yt-dlp/pull/557
290
304
  'mweb': {
@@ -323,13 +337,12 @@ INNERTUBE_CLIENTS = {
323
337
  'client': {
324
338
  'clientName': 'TVHTML5',
325
339
  'clientVersion': '7.20260114.12.00',
326
- 'userAgent': 'Mozilla/5.0 (ChromiumStylePlatform) Cobalt/Version',
340
+ # See: https://github.com/youtube/cobalt/blob/main/cobalt/browser/user_agent/user_agent_platform_info.cc#L506
341
+ 'userAgent': 'Mozilla/5.0 (ChromiumStylePlatform) Cobalt/25.lts.30.1034943-gold (unlike Gecko), Unknown_TV_Unknown_0/Unknown (Unknown, Unknown)',
327
342
  },
328
343
  },
329
344
  'INNERTUBE_CONTEXT_CLIENT_NAME': 7,
330
345
  'SUPPORTS_COOKIES': True,
331
- # See: https://github.com/youtube/cobalt/blob/main/cobalt/browser/user_agent/user_agent_platform_info.cc#L506
332
- 'AUTHENTICATED_USER_AGENT': 'Mozilla/5.0 (ChromiumStylePlatform) Cobalt/25.lts.30.1034943-gold (unlike Gecko), Unknown_TV_Unknown_0/Unknown (Unknown, Unknown)',
333
346
  },
334
347
  'tv_downgraded': {
335
348
  'INNERTUBE_CONTEXT': {
@@ -340,6 +353,7 @@ INNERTUBE_CLIENTS = {
340
353
  },
341
354
  },
342
355
  'INNERTUBE_CONTEXT_CLIENT_NAME': 7,
356
+ 'REQUIRE_AUTH': True,
343
357
  'SUPPORTS_COOKIES': True,
344
358
  },
345
359
  'tv_simply': {
@@ -418,7 +432,6 @@ def build_innertube_clients():
418
432
  ytcfg.setdefault('SUPPORTS_COOKIES', False)
419
433
  ytcfg.setdefault('SUPPORTS_AD_PLAYBACK_CONTEXT', False)
420
434
  ytcfg.setdefault('PLAYER_PARAMS', None)
421
- ytcfg.setdefault('AUTHENTICATED_USER_AGENT', None)
422
435
  ytcfg['INNERTUBE_CONTEXT']['client'].setdefault('hl', 'en')
423
436
 
424
437
  _, base_client, variant = _split_innertube_client(client)
@@ -703,14 +716,7 @@ class YoutubeBaseInfoExtractor(InfoExtractor):
703
716
  _YT_INITIAL_PLAYER_RESPONSE_RE = r'ytInitialPlayerResponse\s*='
704
717
 
705
718
  def _get_default_ytcfg(self, client='web'):
706
- ytcfg = copy.deepcopy(INNERTUBE_CLIENTS[client])
707
-
708
- # Currently, only the tv client needs to use an alternative user-agent when logged-in
709
- if ytcfg.get('AUTHENTICATED_USER_AGENT') and self.is_authenticated:
710
- client_context = ytcfg.setdefault('INNERTUBE_CONTEXT', {}).setdefault('client', {})
711
- client_context['userAgent'] = ytcfg['AUTHENTICATED_USER_AGENT']
712
-
713
- return ytcfg
719
+ return copy.deepcopy(INNERTUBE_CLIENTS[client])
714
720
 
715
721
  def _get_innertube_host(self, client='web'):
716
722
  return INNERTUBE_CLIENTS[client]['INNERTUBE_HOST']
@@ -145,8 +145,8 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
145
145
  r'\b(?P<id>vfl[a-zA-Z0-9_-]+)\b.*?\.js$',
146
146
  )
147
147
  _SUBTITLE_FORMATS = ('json3', 'srv1', 'srv2', 'srv3', 'ttml', 'srt', 'vtt')
148
- _DEFAULT_CLIENTS = ('android_sdkless', 'web', 'web_safari')
149
- _DEFAULT_JSLESS_CLIENTS = ('android_sdkless',)
148
+ _DEFAULT_CLIENTS = ('android_vr', 'ios_downgraded', 'web', 'web_safari')
149
+ _DEFAULT_JSLESS_CLIENTS = ('android_vr', 'ios_downgraded')
150
150
  _DEFAULT_AUTHED_CLIENTS = ('tv_downgraded', 'web', 'web_safari')
151
151
  # Premium does not require POT (except for subtitles)
152
152
  _DEFAULT_PREMIUM_CLIENTS = ('tv_downgraded', 'web_creator', 'web')
@@ -1690,7 +1690,8 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
1690
1690
  'playable_in_embed': True,
1691
1691
  'availability': 'public',
1692
1692
  'live_status': 'not_live',
1693
- 'comment_count': 15, # XXX: minimum
1693
+ 'comment_count': 15, # XXX: minimum, but investigate if this changes
1694
+ 'comments': 'count:15',
1694
1695
  },
1695
1696
  'params': {
1696
1697
  'skip_download': True,
@@ -1723,7 +1724,12 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
1723
1724
  'playable_in_embed': True,
1724
1725
  'availability': 'unlisted',
1725
1726
  'live_status': 'not_live',
1726
- 'comment_count': 9, # XXX: minimum
1727
+ 'comment_count': 9, # XXX: minimum, but investigate if this changes
1728
+ 'comments': 'count:9',
1729
+ },
1730
+ 'params': {
1731
+ 'skip_download': True,
1732
+ 'getcomments': True,
1727
1733
  },
1728
1734
  }]
1729
1735
  _WEBPAGE_TESTS = [{
@@ -1884,7 +1890,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
1884
1890
  'tv': 'tv-player-ias.vflset/tv-player-ias.js',
1885
1891
  'tv_es6': 'tv-player-es6.vflset/tv-player-es6.js',
1886
1892
  'phone': 'player-plasma-ias-phone-en_US.vflset/base.js',
1887
- 'tablet': 'player-plasma-ias-tablet-en_US.vflset/base.js',
1893
+ 'tablet': 'player-plasma-ias-tablet-en_US.vflset/base.js', # Dead since 19712d96 (2025.11.06)
1888
1894
  }
1889
1895
  _INVERSE_PLAYER_JS_VARIANT_MAP = {v: k for k, v in _PLAYER_JS_VARIANT_MAP.items()}
1890
1896
 
@@ -3589,6 +3595,10 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
3589
3595
  if client_name == 'web_safari' and proto == 'hls' and live_status != 'is_live':
3590
3596
  f['source_preference'] -= 1
3591
3597
 
3598
+ # Safeguard against inevitable ios_downgraded client breakage
3599
+ if client_name == 'ios_downgraded' and proto == 'hls' and live_status != 'is_live':
3600
+ f['__needs_testing'] = True
3601
+
3592
3602
  if missing_pot:
3593
3603
  f['format_note'] = join_nonempty(f.get('format_note'), 'MISSING POT', delim=' ')
3594
3604
  f['source_preference'] -= 20
@@ -1,10 +1,10 @@
1
1
  # This file is generated by devscripts/update_ejs.py. DO NOT MODIFY!
2
2
 
3
- VERSION = '0.3.2'
3
+ VERSION = '0.4.0'
4
4
  HASHES = {
5
5
  'yt.solver.bun.lib.js': '6ff45e94de9f0ea936a183c48173cfa9ce526ee4b7544cd556428427c1dd53c8073ef0174e79b320252bf0e7c64b0032cc1cf9c4358f3fda59033b7caa01c241',
6
- 'yt.solver.core.js': '0cd96b2d3f319dfa62cae689efa7d930ef1706e95f5921794db5089b2262957ec0a17d73938d8975ea35d0309cbfb4c8e4418d5e219837215eee242890c8b64d',
7
- 'yt.solver.core.min.js': '370d627703002b4a73b10027702734a3de9484f6b56b739942be1dc2b60fee49dee2aa86ed117d1c8ae1ac55181d326481f1fe2e2e8d5211154d48e2a55dac51',
6
+ 'yt.solver.core.js': '05964b458d92a65d4fb7a90bcb5921c9fed2370f4e4f2f25badb41f28aff9069e0b3c4e5bf1baf2d3021787b67fc6093cefa44de30cffdc6f9fb25532484003b',
7
+ 'yt.solver.core.min.js': '0cd3c0b37e095d3cca99443b58fe03980ac3bf2e777c2485c23e1f6052b5ede9f07c7f1c79a9c3af3258ea91a228f099741e7eb07b53125b5dcc84bb4c0054f3',
8
8
  'yt.solver.deno.lib.js': '9c8ee3ab6c23e443a5a951e3ac73c6b8c1c8fb34335e7058a07bf99d349be5573611de00536dcd03ecd3cf34014c4e9b536081de37af3637c5390c6a6fd6a0f0',
9
9
  'yt.solver.lib.js': '1ee3753a8222fc855f5c39db30a9ccbb7967dbe1fb810e86dc9a89aa073a0907f294c720e9b65427d560a35aa1ce6af19ef854d9126a05ca00afe03f72047733',
10
10
  'yt.solver.lib.min.js': '8420c259ad16e99ce004e4651ac1bcabb53b4457bf5668a97a9359be9a998a789fee8ab124ee17f91a2ea8fd84e0f2b2fc8eabcaf0b16a186ba734cf422ad053',
@@ -60,6 +60,26 @@ var jsc = (function (meriyah, astring) {
60
60
  }
61
61
  return value;
62
62
  }
63
+ const nsigExpression = {
64
+ type: 'VariableDeclaration',
65
+ kind: 'var',
66
+ declarations: [
67
+ {
68
+ type: 'VariableDeclarator',
69
+ init: {
70
+ type: 'CallExpression',
71
+ callee: { type: 'Identifier' },
72
+ arguments: [
73
+ { type: 'Literal' },
74
+ {
75
+ type: 'CallExpression',
76
+ callee: { type: 'Identifier', name: 'decodeURIComponent' },
77
+ },
78
+ ],
79
+ },
80
+ },
81
+ ],
82
+ };
63
83
  const logicalExpression = {
64
84
  type: 'ExpressionStatement',
65
85
  expression: {
@@ -186,24 +206,57 @@ var jsc = (function (meriyah, astring) {
186
206
  'call',
187
207
  (_8) => _8(-2),
188
208
  ]);
189
- if (!matchesStructure(relevantExpression, logicalExpression)) {
190
- return null;
191
- }
192
- if (
209
+ let call = null;
210
+ if (matchesStructure(relevantExpression, logicalExpression)) {
211
+ if (
212
+ _optionalChain$2([
213
+ relevantExpression,
214
+ 'optionalAccess',
215
+ (_9) => _9.type,
216
+ ]) !== 'ExpressionStatement' ||
217
+ relevantExpression.expression.type !== 'LogicalExpression' ||
218
+ relevantExpression.expression.right.type !== 'SequenceExpression' ||
219
+ relevantExpression.expression.right.expressions[0].type !==
220
+ 'AssignmentExpression' ||
221
+ relevantExpression.expression.right.expressions[0].right.type !==
222
+ 'CallExpression'
223
+ ) {
224
+ return null;
225
+ }
226
+ call = relevantExpression.expression.right.expressions[0].right;
227
+ } else if (
193
228
  _optionalChain$2([
194
229
  relevantExpression,
195
230
  'optionalAccess',
196
- (_9) => _9.type,
197
- ]) !== 'ExpressionStatement' ||
198
- relevantExpression.expression.type !== 'LogicalExpression' ||
199
- relevantExpression.expression.right.type !== 'SequenceExpression' ||
200
- relevantExpression.expression.right.expressions[0].type !==
201
- 'AssignmentExpression'
231
+ (_10) => _10.type,
232
+ ]) === 'IfStatement' &&
233
+ relevantExpression.consequent.type === 'BlockStatement'
202
234
  ) {
203
- return null;
235
+ for (const n of relevantExpression.consequent.body) {
236
+ if (!matchesStructure(n, nsigExpression)) {
237
+ continue;
238
+ }
239
+ if (
240
+ n.type !== 'VariableDeclaration' ||
241
+ _optionalChain$2([
242
+ n,
243
+ 'access',
244
+ (_11) => _11.declarations,
245
+ 'access',
246
+ (_12) => _12[0],
247
+ 'access',
248
+ (_13) => _13.init,
249
+ 'optionalAccess',
250
+ (_14) => _14.type,
251
+ ]) !== 'CallExpression'
252
+ ) {
253
+ continue;
254
+ }
255
+ call = n.declarations[0].init;
256
+ break;
257
+ }
204
258
  }
205
- const call = relevantExpression.expression.right.expressions[0].right;
206
- if (call.type !== 'CallExpression' || call.callee.type !== 'Identifier') {
259
+ if (call === null) {
207
260
  return null;
208
261
  }
209
262
  return {
yt_dlp/version.py CHANGED
@@ -1,8 +1,8 @@
1
1
  # Autogenerated by devscripts/update-version.py
2
2
 
3
- __version__ = '2026.01.27.233257'
3
+ __version__ = '2026.01.29.165626'
4
4
 
5
- RELEASE_GIT_HEAD = '1c739bf53e673e06d2a43feddb5a31ee8496fa6e'
5
+ RELEASE_GIT_HEAD = '8b275536d945c4b3d07b6c520677922c67a7c10f'
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 = '2026.01.27.233257dev'
15
+ _pkg_version = '2026.01.29.165626dev'
@@ -265,8 +265,8 @@ Strongly recommended
265
265
  Important: What you need is ffmpeg binary, NOT the Python package of
266
266
  the same name
267
267
 
268
- - yt-dlp-ejs - Required for deciphering YouTube n/sig values. Licensed
269
- under Unlicense, bundles MIT and ISC components.
268
+ - yt-dlp-ejs - Required for full YouTube support. Licensed under
269
+ Unlicense, bundles MIT and ISC components.
270
270
 
271
271
  A JavaScript runtime/engine like deno (recommended), node.js, bun,
272
272
  or QuickJS is also required to run yt-dlp-ejs. See the wiki.
@@ -2312,11 +2312,11 @@ youtube
2312
2312
  respectively
2313
2313
  - player_client: Clients to extract video data from. The currently
2314
2314
  available clients are web, web_safari, web_embedded, web_music,
2315
- web_creator, mweb, ios, android, android_sdkless, android_vr, tv,
2315
+ web_creator, mweb, ios, ios_downgraded, android, android_vr, tv,
2316
2316
  tv_simply, tv_downgraded, and tv_embedded. By default,
2317
- android_sdkless,web,web_safari is used. If no JavaScript
2318
- runtime/engine is available, then only android_sdkless is used. If
2319
- logged-in cookies are passed to yt-dlp, then
2317
+ android_vr,ios_downgraded,web,web_safari is used. If no JavaScript
2318
+ runtime/engine is available, then android_vr,ios_downgraded is used.
2319
+ If logged-in cookies are passed to yt-dlp, then
2320
2320
  tv_downgraded,web,web_safari is used for free accounts and
2321
2321
  tv_downgraded,web_creator,web is used for premium accounts. The
2322
2322
  web_music client is added for music.youtube.com URLs when logged-in
@@ -2591,10 +2591,11 @@ tver
2591
2591
  vimeo
2592
2592
 
2593
2593
  - client: Client to extract video data from. The currently available
2594
- clients are android, ios, and web. Only one client can be used. The
2595
- web client is used by default. The web client only works with
2596
- account cookies or login credentials. The android and ios clients
2597
- only work with previously cached OAuth tokens
2594
+ clients are android, ios, macos and web. Only one client can be
2595
+ used. The macos client is used by default, but the web client is
2596
+ used when logged-in. The web client only works with account cookies
2597
+ or login credentials. The android and ios clients only work with
2598
+ previously cached OAuth tokens
2598
2599
  - original_format_policy: Policy for when to try extracting original
2599
2600
  formats. One of always, never, or auto. The default auto policy
2600
2601
  tries to avoid exceeding the web client's API rate-limit by only
@@ -2713,12 +2713,12 @@ respectively
2713
2713
  \f[V]player_client\f[R]: Clients to extract video data from.
2714
2714
  The currently available clients are \f[V]web\f[R], \f[V]web_safari\f[R],
2715
2715
  \f[V]web_embedded\f[R], \f[V]web_music\f[R], \f[V]web_creator\f[R],
2716
- \f[V]mweb\f[R], \f[V]ios\f[R], \f[V]android\f[R],
2717
- \f[V]android_sdkless\f[R], \f[V]android_vr\f[R], \f[V]tv\f[R],
2716
+ \f[V]mweb\f[R], \f[V]ios\f[R], \f[V]ios_downgraded\f[R],
2717
+ \f[V]android\f[R], \f[V]android_vr\f[R], \f[V]tv\f[R],
2718
2718
  \f[V]tv_simply\f[R], \f[V]tv_downgraded\f[R], and \f[V]tv_embedded\f[R].
2719
- By default, \f[V]android_sdkless,web,web_safari\f[R] is used.
2720
- If no JavaScript runtime/engine is available, then only
2721
- \f[V]android_sdkless\f[R] is used.
2719
+ By default, \f[V]android_vr,ios_downgraded,web,web_safari\f[R] is used.
2720
+ If no JavaScript runtime/engine is available, then
2721
+ \f[V]android_vr,ios_downgraded\f[R] is used.
2722
2722
  If logged-in cookies are passed to yt-dlp, then
2723
2723
  \f[V]tv_downgraded,web,web_safari\f[R] is used for free accounts and
2724
2724
  \f[V]tv_downgraded,web_creator,web\f[R] is used for premium accounts.
@@ -3075,9 +3075,10 @@ Default is \f[V]asc\f[R]
3075
3075
  .IP \[bu] 2
3076
3076
  \f[V]client\f[R]: Client to extract video data from.
3077
3077
  The currently available clients are \f[V]android\f[R], \f[V]ios\f[R],
3078
- and \f[V]web\f[R].
3078
+ \f[V]macos\f[R] and \f[V]web\f[R].
3079
3079
  Only one client can be used.
3080
- The \f[V]web\f[R] client is used by default.
3080
+ The \f[V]macos\f[R] client is used by default, but the \f[V]web\f[R]
3081
+ client is used when logged-in.
3081
3082
  The \f[V]web\f[R] client only works with account cookies or login
3082
3083
  credentials.
3083
3084
  The \f[V]android\f[R] and \f[V]ios\f[R] clients only work with
@@ -3215,8 +3216,8 @@ for details on the specific issues solved by these builds
3215
3216
  name (https://pypi.org/project/ffmpeg)
3216
3217
  .RE
3217
3218
  .IP \[bu] 2
3218
- \f[B]yt-dlp-ejs\f[R] (https://github.com/yt-dlp/ejs) - Required for
3219
- deciphering YouTube n/sig values.
3219
+ \f[B]yt-dlp-ejs\f[R] (https://github.com/yt-dlp/ejs) - Required for full
3220
+ YouTube support.
3220
3221
  Licensed under
3221
3222
  Unlicense (https://github.com/yt-dlp/ejs/blob/main/LICENSE), bundles
3222
3223
  MIT (https://github.com/davidbonnet/astring/blob/main/LICENSE) and
@@ -1,13 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: yt-dlp
3
- Version: 2026.1.27.233257.dev0
3
+ Version: 2026.1.29.165626.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
7
7
  Project-URL: Tracker, https://github.com/yt-dlp/yt-dlp/issues
8
8
  Project-URL: Funding, https://github.com/yt-dlp/yt-dlp/blob/master/Maintainers.md#maintainers
9
9
  Author-email: pukkandan <pukkandan.ytdlp@gmail.com>
10
- Maintainer-email: maintainers@yt-dlp.org, Grub4K <contact@grub4k.xyz>, bashonly <bashonly@protonmail.com>, coletdjnz <coletdjnz@protonmail.com>, sepro <sepro@sepr0.com>
10
+ Maintainer-email: maintainers@yt-dlp.org, Grub4K <contact@grub4k.dev>, bashonly <bashonly@protonmail.com>, coletdjnz <coletdjnz@protonmail.com>
11
11
  License-Expression: Unlicense
12
12
  License-File: LICENSE
13
13
  Keywords: cli,downloader,sponsorblock,youtube-dl,youtube-downloader,yt-dlp
@@ -46,9 +46,9 @@ Requires-Dist: pycryptodomex; extra == 'default'
46
46
  Requires-Dist: requests<3,>=2.32.2; extra == 'default'
47
47
  Requires-Dist: urllib3<3,>=2.0.2; extra == 'default'
48
48
  Requires-Dist: websockets>=13.0; extra == 'default'
49
- Requires-Dist: yt-dlp-ejs==0.3.2; extra == 'default'
49
+ Requires-Dist: yt-dlp-ejs==0.4.0; extra == 'default'
50
50
  Provides-Extra: deno
51
- Requires-Dist: deno>=2.6.5; extra == 'deno'
51
+ Requires-Dist: deno>=2.6.6; extra == 'deno'
52
52
  Provides-Extra: dev
53
53
  Requires-Dist: autopep8~=2.0; extra == 'dev'
54
54
  Requires-Dist: pre-commit; extra == 'dev'
@@ -287,7 +287,7 @@ While all the other dependencies are optional, `ffmpeg`, `ffprobe`, `yt-dlp-ejs`
287
287
 
288
288
  **Important**: What you need is ffmpeg *binary*, **NOT** [the Python package of the same name](https://pypi.org/project/ffmpeg)
289
289
 
290
- * [**yt-dlp-ejs**](https://github.com/yt-dlp/ejs) - Required for deciphering YouTube n/sig values. Licensed under [Unlicense](https://github.com/yt-dlp/ejs/blob/main/LICENSE), bundles [MIT](https://github.com/davidbonnet/astring/blob/main/LICENSE) and [ISC](https://github.com/meriyah/meriyah/blob/main/LICENSE.md) components.
290
+ * [**yt-dlp-ejs**](https://github.com/yt-dlp/ejs) - Required for full YouTube support. Licensed under [Unlicense](https://github.com/yt-dlp/ejs/blob/main/LICENSE), bundles [MIT](https://github.com/davidbonnet/astring/blob/main/LICENSE) and [ISC](https://github.com/meriyah/meriyah/blob/main/LICENSE.md) components.
291
291
 
292
292
  A JavaScript runtime/engine like [**deno**](https://deno.land) (recommended), [**node.js**](https://nodejs.org), [**bun**](https://bun.sh), or [**QuickJS**](https://bellard.org/quickjs/) is also required to run yt-dlp-ejs. See [the wiki](https://github.com/yt-dlp/yt-dlp/wiki/EJS).
293
293
 
@@ -1934,7 +1934,7 @@ The following extractors use this feature:
1934
1934
  #### youtube
1935
1935
  * `lang`: Prefer translated metadata (`title`, `description` etc) of this language code (case-sensitive). By default, the video primary language metadata is preferred, with a fallback to `en` translated. See [youtube/_base.py](https://github.com/yt-dlp/yt-dlp/blob/415b4c9f955b1a0391204bd24a7132590e7b3bdb/yt_dlp/extractor/youtube/_base.py#L402-L409) for the list of supported content language codes
1936
1936
  * `skip`: One or more of `hls`, `dash` or `translated_subs` to skip extraction of the m3u8 manifests, dash manifests and [auto-translated subtitles](https://github.com/yt-dlp/yt-dlp/issues/4090#issuecomment-1158102032) respectively
1937
- * `player_client`: Clients to extract video data from. The currently available clients are `web`, `web_safari`, `web_embedded`, `web_music`, `web_creator`, `mweb`, `ios`, `android`, `android_sdkless`, `android_vr`, `tv`, `tv_simply`, `tv_downgraded`, and `tv_embedded`. By default, `android_sdkless,web,web_safari` is used. If no JavaScript runtime/engine is available, then only `android_sdkless` is used. If logged-in cookies are passed to yt-dlp, then `tv_downgraded,web,web_safari` is used for free accounts and `tv_downgraded,web_creator,web` is used for premium accounts. The `web_music` client is added for `music.youtube.com` URLs when logged-in cookies are used. The `web_embedded` client is added for age-restricted videos but only works if the video is embeddable. The `tv_embedded` and `web_creator` clients are added for age-restricted videos if account age-verification is required. Some clients, such as `web` and `web_music`, require a `po_token` for their formats to be downloadable. Some clients, such as `web_creator`, will only work with authentication. Not all clients support authentication via cookies. You can use `default` for the default clients, or you can use `all` for all clients (not recommended). You can prefix a client with `-` to exclude it, e.g. `youtube:player_client=default,-ios`
1937
+ * `player_client`: Clients to extract video data from. The currently available clients are `web`, `web_safari`, `web_embedded`, `web_music`, `web_creator`, `mweb`, `ios`, `ios_downgraded`, `android`, `android_vr`, `tv`, `tv_simply`, `tv_downgraded`, and `tv_embedded`. By default, `android_vr,ios_downgraded,web,web_safari` is used. If no JavaScript runtime/engine is available, then `android_vr,ios_downgraded` is used. If logged-in cookies are passed to yt-dlp, then `tv_downgraded,web,web_safari` is used for free accounts and `tv_downgraded,web_creator,web` is used for premium accounts. The `web_music` client is added for `music.youtube.com` URLs when logged-in cookies are used. The `web_embedded` client is added for age-restricted videos but only works if the video is embeddable. The `tv_embedded` and `web_creator` clients are added for age-restricted videos if account age-verification is required. Some clients, such as `web` and `web_music`, require a `po_token` for their formats to be downloadable. Some clients, such as `web_creator`, will only work with authentication. Not all clients support authentication via cookies. You can use `default` for the default clients, or you can use `all` for all clients (not recommended). You can prefix a client with `-` to exclude it, e.g. `youtube:player_client=default,-ios`
1938
1938
  * `player_skip`: Skip some network requests that are generally needed for robust extraction. One or more of `configs` (skip client configs), `webpage` (skip initial webpage), `js` (skip js player), `initial_data` (skip initial data/next ep request). While these options can help reduce the number of requests needed or avoid some rate-limiting, they could cause issues such as missing formats or metadata. See [#860](https://github.com/yt-dlp/yt-dlp/pull/860) and [#12826](https://github.com/yt-dlp/yt-dlp/issues/12826) for more details
1939
1939
  * `webpage_skip`: Skip extraction of embedded webpage data. One or both of `player_response`, `initial_data`. These options are for testing purposes and don't skip any network requests
1940
1940
  * `player_params`: YouTube player parameters to use for player requests. Will overwrite any default ones set by yt-dlp.
@@ -2046,7 +2046,7 @@ The following extractors use this feature:
2046
2046
  * `backend`: Backend API to use for extraction - one of `streaks` (default) or `brightcove` (deprecated)
2047
2047
 
2048
2048
  #### vimeo
2049
- * `client`: Client to extract video data from. The currently available clients are `android`, `ios`, and `web`. Only one client can be used. The `web` client is used by default. The `web` client only works with account cookies or login credentials. The `android` and `ios` clients only work with previously cached OAuth tokens
2049
+ * `client`: Client to extract video data from. The currently available clients are `android`, `ios`, `macos` and `web`. Only one client can be used. The `macos` client is used by default, but the `web` client is used when logged-in. The `web` client only works with account cookies or login credentials. The `android` and `ios` clients only work with previously cached OAuth tokens
2050
2050
  * `original_format_policy`: Policy for when to try extracting original formats. One of `always`, `never`, or `auto`. The default `auto` policy tries to avoid exceeding the web client's API rate-limit by only making an extra request when Vimeo publicizes the video's downloadability
2051
2051
 
2052
2052
  **Note**: These options may be changed/removed in the future without concern for backward compatibility
@@ -1,4 +1,4 @@
1
- yt_dlp/YoutubeDL.py,sha256=nk4plDMtrPHOUodTf6_pD_1JeIW6kXIvod-pQjpZzl8,216649
1
+ yt_dlp/YoutubeDL.py,sha256=Qb5Q7fIQrSeVJ16kIISrqlRnrJl4wJNHswEyhodwM60,216827
2
2
  yt_dlp/__init__.py,sha256=Nyir0qVukv9-pdfRtHPVm3EDOYDvwa1AXHOIX9oR0ps,47897
3
3
  yt_dlp/__main__.py,sha256=DzqMhNY2y89eqs0Hnd4hOhjMfW9OhnhdhJdDH9yizmw,367
4
4
  yt_dlp/aes.py,sha256=OU2t7oHbaKSIT-evc75vU58XK20b6wqgJvNlG_fois0,22033
@@ -11,7 +11,7 @@ yt_dlp/options.py,sha256=-PQ5DyRSIU9YBSG2oh0RTHC-eg4EewNt4zewTZTuERM,100632
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=9E2_jbxBwIFxhCmOpJUx2QQhUKqHsBbQavj_0Gb0K7U,360
14
+ yt_dlp/version.py,sha256=C2t8S3dwqjc1upr4DqKcq8qoBim7o6yi_RTxv1ZPF0Y,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
@@ -848,7 +848,7 @@ yt_dlp/extractor/syvdk.py,sha256=odhjQTYIDxWj2lS9Yr_MyFGfWmstxCeOSI7xUrYavs8,124
848
848
  yt_dlp/extractor/sztvhu.py,sha256=2De4mY-V2E4CZQx8HzxnknL0f4_RIi5CTKdcvr4LV78,1616
849
849
  yt_dlp/extractor/tagesschau.py,sha256=D6bXCOYeuXu6BW5hP8Yq5SzWVxMiGXcTennsszi7sZg,6189
850
850
  yt_dlp/extractor/taptap.py,sha256=cI9Y1dSb_glOJlI6S_ttcXHsjwAC7XOPrSnzxGxulz8,10513
851
- yt_dlp/extractor/tarangplus.py,sha256=66U7huxpnbHHqDs5fz3xiZ41aUeYWTqPkDTEw5gLJmA,8993
851
+ yt_dlp/extractor/tarangplus.py,sha256=Gx4XQ55DJ7rFl168aqE09abBlq9hemSZKKAuGzocygg,9018
852
852
  yt_dlp/extractor/tass.py,sha256=a5-1HR_xouhR8MEhNxMtzns_bR2LeP-6o4vOohmxIm8,1944
853
853
  yt_dlp/extractor/tbs.py,sha256=QAjno1ds3lzjv8RTrCKGgWqxCsOrxfQ4I6WTlnMCWbc,7851
854
854
  yt_dlp/extractor/tbsjp.py,sha256=FSSpDtu7QkK8c4TwSz5rYVWBD_L4SKZjQRtN8zs4LZw,7536
@@ -983,7 +983,7 @@ yt_dlp/extractor/vidly.py,sha256=rqjJ1NiJmTnWOD1Ix-FPLcKbEt0q-rgQ1CjMKt6Qm5Y,306
983
983
  yt_dlp/extractor/vidyard.py,sha256=Ip42AQN8yZKuBWBQ8uB1fw2fmik8puRTAOoEgOipvpc,19785
984
984
  yt_dlp/extractor/viewlift.py,sha256=DeUfC8fSOHDeafsR43WA-FnVW27m9WrTYpcCWJrWCEY,15349
985
985
  yt_dlp/extractor/viidea.py,sha256=pwaElPc66lGySrDfwg1DYe6lS9i-3gPYUt2aSrZfCOo,7284
986
- yt_dlp/extractor/vimeo.py,sha256=xDFd0CgrKvVXDblKixlGxOlvkHZwF6Kv2sGlxkguLUE,101314
986
+ yt_dlp/extractor/vimeo.py,sha256=g-YFKAkwLP-ECul8d2Y2ImRv0CIH5z_pLvMFnN9_Cb0,102453
987
987
  yt_dlp/extractor/vimm.py,sha256=qaKwh13PsSKEqO5CysAER4JDw-LLPiHNHLeayJqRwDs,2154
988
988
  yt_dlp/extractor/viously.py,sha256=hX4RBtp3zQSZf1CyWocoG4rYi7y7NHdSEpRgmM38qag,2573
989
989
  yt_dlp/extractor/viqeo.py,sha256=xzl-wjB88toMmyaEEx2OONytYbwEjK7hypI4hSWSby8,3498
@@ -1014,7 +1014,7 @@ yt_dlp/extractor/weverse.py,sha256=zFFq7PJU3a6NWSBbMHcYXdqop0C2yCj0fPgk6iUeqC8,3
1014
1014
  yt_dlp/extractor/wevidi.py,sha256=ylpKfJ1aEGDRYF0x9O2KgaeGeN_BxYN2phRvGao2nF8,4159
1015
1015
  yt_dlp/extractor/weyyak.py,sha256=YlBPciN_7tMuQknRooSxKuhEiGLOiDUmVn6fBMgXc2A,3497
1016
1016
  yt_dlp/extractor/whowatch.py,sha256=q0ZawsjFxkIbsIpnCL-RkwkMdJNgRD6-WDsJajyfVrY,3860
1017
- yt_dlp/extractor/whyp.py,sha256=Q4Fsijw0Ar7PpBfA0J_xBx2BmvpsSube-zsMT0JxtzA,1719
1017
+ yt_dlp/extractor/whyp.py,sha256=JPvShwyZVp318APJZ_3XpwoIjpZZscWmLubp05Qg4Ck,1933
1018
1018
  yt_dlp/extractor/wikimedia.py,sha256=0FSysi1ciIjb7bF8LC_7-5w6IJUqiHmueVhZEVWamo0,2323
1019
1019
  yt_dlp/extractor/wimbledon.py,sha256=cJ_VJ5CEvxOAIENTQETJJlXdyQqdozgRYWVJgtbvZqk,2285
1020
1020
  yt_dlp/extractor/wimtv.py,sha256=K8HWMvB0uGcppnkMpzH9AGvl-wBnhuR8Izju0rBs7lo,5777
@@ -1061,14 +1061,14 @@ yt_dlp/extractor/zingmp3.py,sha256=KHD-f-1vUPy18Xk-_F_H_LfFR9N7-bONFYWeNRvJ1Z4,2
1061
1061
  yt_dlp/extractor/zoom.py,sha256=7FwI0aJRG3evlKmCC97Ndc7oFRrFT3LHiHye__QZ7Do,7305
1062
1062
  yt_dlp/extractor/zype.py,sha256=e3_07aMl65x-ziI5Ge_Ph_lCV4q67DnqeRq2PjIKZj4,5507
1063
1063
  yt_dlp/extractor/youtube/__init__.py,sha256=3F72z6WHXlv41giIdmmVY7Fws-bAnkiWz8Eh3A19004,1454
1064
- yt_dlp/extractor/youtube/_base.py,sha256=8FeAee7rRfL4qhC10JZWmeNHj0vx3HxqoVJBJ5qMKUE,55551
1064
+ yt_dlp/extractor/youtube/_base.py,sha256=X6-smdV2ww_L-C64UKVOCMJ0OVWkjKGlEMc9lCd-mpo,55635
1065
1065
  yt_dlp/extractor/youtube/_clip.py,sha256=__EJUrb6iUCIURupsaa-ixn51q4esfok09znrpvdD88,3073
1066
1066
  yt_dlp/extractor/youtube/_mistakes.py,sha256=bLrxlAYqdR0mTuCLoMmJHh15BHuhxfHXeQFTVBRX9Lk,2142
1067
1067
  yt_dlp/extractor/youtube/_notifications.py,sha256=1nhavzW0e2QWFAWHkfbTU4sSXNp4vUbGFygYNSgbxBE,4585
1068
1068
  yt_dlp/extractor/youtube/_redirect.py,sha256=WWWnGEkfSGBXpZFi_bWY4XcHZ8PDeK7UsndDaTYYhQg,9005
1069
1069
  yt_dlp/extractor/youtube/_search.py,sha256=E9raTPGjUD6mm81WBpT4AsaxyiTBHdNssgzeHwVeNOE,6552
1070
1070
  yt_dlp/extractor/youtube/_tab.py,sha256=MiQGWZdHENOz8Ac-OAuAgqMWJ6gC-PZKJWPDG80QY6E,115490
1071
- yt_dlp/extractor/youtube/_video.py,sha256=iseiuuVtT2r3UglxYnYjseOWfoW1gmw0ZMorUv7UYto,214695
1071
+ yt_dlp/extractor/youtube/_video.py,sha256=w7S3fLYbrdOWu7m7JsdMRwfxTJb7EGALGMgAAkv-Lck,215219
1072
1072
  yt_dlp/extractor/youtube/jsc/__init__.py,sha256=HaVFP8ikrLaE-ClAh39-S28WCF4S2KTRaSu7QvA28E8,289
1073
1073
  yt_dlp/extractor/youtube/jsc/_director.py,sha256=92pB-KVSs6plmE5R8gpjkZL9aeoWNR0XTnGOBXMy9go,13167
1074
1074
  yt_dlp/extractor/youtube/jsc/_registry.py,sha256=Vg9GkHKHKKPeRfUQ-XSw01mfx_2Xyodh0SJpwjawYCA,102
@@ -1080,9 +1080,9 @@ yt_dlp/extractor/youtube/jsc/_builtin/ejs.py,sha256=88BQ63l7HuXNhzbyYsQWpzxALYvC
1080
1080
  yt_dlp/extractor/youtube/jsc/_builtin/node.py,sha256=2D7mNEeWRVw2hD4rpydjWGHsOzccxDMwGJvx0eWNq3Q,2300
1081
1081
  yt_dlp/extractor/youtube/jsc/_builtin/quickjs.py,sha256=y1FSPGgrjcUbsiwC6rOcbOsK0BbLWlzfZwl8VjT7MdA,2233
1082
1082
  yt_dlp/extractor/youtube/jsc/_builtin/vendor/__init__.py,sha256=aLGEcFSHt-ub1H21jHp52rJTDKZmWXV-PJd_0hVCcio,518
1083
- yt_dlp/extractor/youtube/jsc/_builtin/vendor/_info.py,sha256=i5nCP-v40uoRQZ7WPlGMinuseXSffVqaiGmSSF197Is,1056
1083
+ yt_dlp/extractor/youtube/jsc/_builtin/vendor/_info.py,sha256=PnvFGY6BNQX3b1fBtHmLxDbQ1aDjdLMmaEjz3eDbFxI,1056
1084
1084
  yt_dlp/extractor/youtube/jsc/_builtin/vendor/yt.solver.bun.lib.js,sha256=ZfLzSdQETBfPWniQsgtce3zyeYeBIr95s7M_f0v2LNQ,237
1085
- yt_dlp/extractor/youtube/jsc/_builtin/vendor/yt.solver.core.js,sha256=WM1Xb6fCNxVU_ELUONasGs5fPNHnHW5p9u1irRMRPyM,17016
1085
+ yt_dlp/extractor/youtube/jsc/_builtin/vendor/yt.solver.core.js,sha256=kUb6amVew1BI99KPKEvcLNzNLHtB86VoYFhMlKJZw8k,18395
1086
1086
  yt_dlp/extractor/youtube/jsc/_builtin/vendor/yt.solver.deno.lib.js,sha256=6DFMNBXVnY31f9GSysXuQKziVjN-qfUZn0xwAv5Ozs8,245
1087
1087
  yt_dlp/extractor/youtube/pot/__init__.py,sha256=bPX3iJSKBoG720Td3XfQxbLgb8SEa45Nv4-jE871eiU,194
1088
1088
  yt_dlp/extractor/youtube/pot/_director.py,sha256=CWGZUzOtVs3vB9Xt9pS0ahmW0W4Fr28iwpKEihEKhs4,20469
@@ -1124,13 +1124,13 @@ yt_dlp/utils/progress.py,sha256=t9kVvJ0oWuEqRzo9fdFbIhHUBtO_8mg348QwZ1faqLo,3261
1124
1124
  yt_dlp/utils/traversal.py,sha256=64E3RcZ56iSX50RI_HbKdDNftkETMLBaEPX791_b7yQ,18265
1125
1125
  yt_dlp/utils/jslib/__init__.py,sha256=CbdJiRA7Eh5PnjF2V4lDTcg0J0XjBMaaq0H4pCfq9Tk,87
1126
1126
  yt_dlp/utils/jslib/devalue.py,sha256=UtcQ1IEzt6HWBjB9Z_6rJMb3y2pFrbHXDNu1rrxXF1c,5583
1127
- yt_dlp-2026.1.27.233257.dev0.data/data/share/bash-completion/completions/yt-dlp,sha256=KKMwJ7JkH-B2rXIR9n4wAHTqn5waHyxzPtVmsMoYkDI,6009
1128
- yt_dlp-2026.1.27.233257.dev0.data/data/share/doc/yt_dlp/README.txt,sha256=ZT_UKIUjR5lFVtB7ctKc9FBVWkmnM-cFMNDpeVSwFfg,166159
1129
- yt_dlp-2026.1.27.233257.dev0.data/data/share/fish/vendor_completions.d/yt-dlp.fish,sha256=L0JADRod-4ew2pvmYGiDUuXFgu1Ac8msk-ackiLYHCo,51632
1130
- yt_dlp-2026.1.27.233257.dev0.data/data/share/man/man1/yt-dlp.1,sha256=blBneUC8ngI9Qjm2w4xDUIxeRQOLw6tnwNVs02fJFNM,160804
1131
- yt_dlp-2026.1.27.233257.dev0.data/data/share/zsh/site-functions/_yt-dlp,sha256=VsiR8Dn2RqbVSZHAqQyDtTfrc3BIBdzwgrcaJqux8kQ,6005
1132
- yt_dlp-2026.1.27.233257.dev0.dist-info/METADATA,sha256=0SG_mKaiU30MM9-0DOGVAifqzqwm5R_bBukf46yueco,181945
1133
- yt_dlp-2026.1.27.233257.dev0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
1134
- yt_dlp-2026.1.27.233257.dev0.dist-info/entry_points.txt,sha256=vWfetvzYgZIwDfMW6BjCe0Cy4pmTZEXRNzxAkfYlRJA,103
1135
- yt_dlp-2026.1.27.233257.dev0.dist-info/licenses/LICENSE,sha256=fhLl30uuEsshWBuhV87SDhmGoFCN0Q0Oikq5pM-U6Fw,1211
1136
- yt_dlp-2026.1.27.233257.dev0.dist-info/RECORD,,
1127
+ yt_dlp-2026.1.29.165626.dev0.data/data/share/bash-completion/completions/yt-dlp,sha256=KKMwJ7JkH-B2rXIR9n4wAHTqn5waHyxzPtVmsMoYkDI,6009
1128
+ yt_dlp-2026.1.29.165626.dev0.data/data/share/doc/yt_dlp/README.txt,sha256=4T6_JYCi7J-bEo_VHyLoj8D2wr3RRjhzCxbY13qZrsI,166216
1129
+ yt_dlp-2026.1.29.165626.dev0.data/data/share/fish/vendor_completions.d/yt-dlp.fish,sha256=L0JADRod-4ew2pvmYGiDUuXFgu1Ac8msk-ackiLYHCo,51632
1130
+ yt_dlp-2026.1.29.165626.dev0.data/data/share/man/man1/yt-dlp.1,sha256=m1y5ya1IKD1_33TmVEpP3p1HYZH1KhKrJRVZ_3Ci54M,160877
1131
+ yt_dlp-2026.1.29.165626.dev0.data/data/share/zsh/site-functions/_yt-dlp,sha256=VsiR8Dn2RqbVSZHAqQyDtTfrc3BIBdzwgrcaJqux8kQ,6005
1132
+ yt_dlp-2026.1.29.165626.dev0.dist-info/METADATA,sha256=n3GkVxGaKMMBOXhuLen5tHnqUPpqZCAhismW0zcvjGs,181977
1133
+ yt_dlp-2026.1.29.165626.dev0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
1134
+ yt_dlp-2026.1.29.165626.dev0.dist-info/entry_points.txt,sha256=vWfetvzYgZIwDfMW6BjCe0Cy4pmTZEXRNzxAkfYlRJA,103
1135
+ yt_dlp-2026.1.29.165626.dev0.dist-info/licenses/LICENSE,sha256=fhLl30uuEsshWBuhV87SDhmGoFCN0Q0Oikq5pM-U6Fw,1211
1136
+ yt_dlp-2026.1.29.165626.dev0.dist-info/RECORD,,