yt-dlp 2026.1.16.233125.dev0__py3-none-any.whl → 2026.1.19.233146.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/_extractors.py +23 -28
- yt_dlp/extractor/cbc.py +19 -3
- yt_dlp/extractor/ccc.py +20 -2
- yt_dlp/extractor/extractors.py +13 -7
- yt_dlp/extractor/lazy_extractors.py +222 -222
- yt_dlp/extractor/youtube/_base.py +16 -16
- yt_dlp/extractor/youtube/_video.py +173 -153
- yt_dlp/networking/_curlcffi.py +2 -2
- yt_dlp/options.py +6 -1
- yt_dlp/utils/_jsruntime.py +8 -0
- yt_dlp/version.py +3 -3
- {yt_dlp-2026.1.16.233125.dev0.data → yt_dlp-2026.1.19.233146.dev0.data}/data/share/bash-completion/completions/yt-dlp +1 -1
- {yt_dlp-2026.1.16.233125.dev0.data → yt_dlp-2026.1.19.233146.dev0.data}/data/share/doc/yt_dlp/README.txt +31 -15
- {yt_dlp-2026.1.16.233125.dev0.data → yt_dlp-2026.1.19.233146.dev0.data}/data/share/fish/vendor_completions.d/yt-dlp.fish +1 -0
- {yt_dlp-2026.1.16.233125.dev0.data → yt_dlp-2026.1.19.233146.dev0.data}/data/share/man/man1/yt-dlp.1 +27 -6
- {yt_dlp-2026.1.16.233125.dev0.data → yt_dlp-2026.1.19.233146.dev0.data}/data/share/zsh/site-functions/_yt-dlp +1 -1
- {yt_dlp-2026.1.16.233125.dev0.dist-info → yt_dlp-2026.1.19.233146.dev0.dist-info}/METADATA +17 -5
- {yt_dlp-2026.1.16.233125.dev0.dist-info → yt_dlp-2026.1.19.233146.dev0.dist-info}/RECORD +21 -21
- {yt_dlp-2026.1.16.233125.dev0.dist-info → yt_dlp-2026.1.19.233146.dev0.dist-info}/WHEEL +0 -0
- {yt_dlp-2026.1.16.233125.dev0.dist-info → yt_dlp-2026.1.19.233146.dev0.dist-info}/entry_points.txt +0 -0
- {yt_dlp-2026.1.16.233125.dev0.dist-info → yt_dlp-2026.1.19.233146.dev0.dist-info}/licenses/LICENSE +0 -0
yt_dlp/extractor/_extractors.py
CHANGED
|
@@ -1,32 +1,4 @@
|
|
|
1
1
|
# flake8: noqa: F401
|
|
2
|
-
# isort: off
|
|
3
|
-
|
|
4
|
-
from .youtube import ( # Youtube is moved to the top to improve performance
|
|
5
|
-
YoutubeIE,
|
|
6
|
-
YoutubeClipIE,
|
|
7
|
-
YoutubeFavouritesIE,
|
|
8
|
-
YoutubeNotificationsIE,
|
|
9
|
-
YoutubeHistoryIE,
|
|
10
|
-
YoutubeTabIE,
|
|
11
|
-
YoutubeLivestreamEmbedIE,
|
|
12
|
-
YoutubePlaylistIE,
|
|
13
|
-
YoutubeRecommendedIE,
|
|
14
|
-
YoutubeSearchDateIE,
|
|
15
|
-
YoutubeSearchIE,
|
|
16
|
-
YoutubeSearchURLIE,
|
|
17
|
-
YoutubeMusicSearchURLIE,
|
|
18
|
-
YoutubeSubscriptionsIE,
|
|
19
|
-
YoutubeTruncatedIDIE,
|
|
20
|
-
YoutubeTruncatedURLIE,
|
|
21
|
-
YoutubeYtBeIE,
|
|
22
|
-
YoutubeYtUserIE,
|
|
23
|
-
YoutubeWatchLaterIE,
|
|
24
|
-
YoutubeShortsAudioPivotIE,
|
|
25
|
-
YoutubeConsentRedirectIE,
|
|
26
|
-
)
|
|
27
|
-
|
|
28
|
-
# isort: on
|
|
29
|
-
|
|
30
2
|
from .abc import (
|
|
31
3
|
ABCIE,
|
|
32
4
|
ABCIViewIE,
|
|
@@ -2551,6 +2523,29 @@ from .youporn import (
|
|
|
2551
2523
|
YouPornTagIE,
|
|
2552
2524
|
YouPornVideosIE,
|
|
2553
2525
|
)
|
|
2526
|
+
from .youtube import (
|
|
2527
|
+
YoutubeClipIE,
|
|
2528
|
+
YoutubeConsentRedirectIE,
|
|
2529
|
+
YoutubeFavouritesIE,
|
|
2530
|
+
YoutubeHistoryIE,
|
|
2531
|
+
YoutubeIE,
|
|
2532
|
+
YoutubeLivestreamEmbedIE,
|
|
2533
|
+
YoutubeMusicSearchURLIE,
|
|
2534
|
+
YoutubeNotificationsIE,
|
|
2535
|
+
YoutubePlaylistIE,
|
|
2536
|
+
YoutubeRecommendedIE,
|
|
2537
|
+
YoutubeSearchDateIE,
|
|
2538
|
+
YoutubeSearchIE,
|
|
2539
|
+
YoutubeSearchURLIE,
|
|
2540
|
+
YoutubeShortsAudioPivotIE,
|
|
2541
|
+
YoutubeSubscriptionsIE,
|
|
2542
|
+
YoutubeTabIE,
|
|
2543
|
+
YoutubeTruncatedIDIE,
|
|
2544
|
+
YoutubeTruncatedURLIE,
|
|
2545
|
+
YoutubeWatchLaterIE,
|
|
2546
|
+
YoutubeYtBeIE,
|
|
2547
|
+
YoutubeYtUserIE,
|
|
2548
|
+
)
|
|
2554
2549
|
from .zaiko import (
|
|
2555
2550
|
ZaikoETicketIE,
|
|
2556
2551
|
ZaikoIE,
|
yt_dlp/extractor/cbc.py
CHANGED
|
@@ -105,7 +105,7 @@ class CBCIE(InfoExtractor):
|
|
|
105
105
|
# multiple CBC.APP.Caffeine.initInstance(...)
|
|
106
106
|
'url': 'http://www.cbc.ca/news/canada/calgary/dog-indoor-exercise-winter-1.3928238',
|
|
107
107
|
'info_dict': {
|
|
108
|
-
'title': 'Keep Rover active during the deep freeze with doggie pushups and other fun indoor tasks',
|
|
108
|
+
'title': 'Keep Rover active during the deep freeze with doggie pushups and other fun indoor tasks',
|
|
109
109
|
'id': 'dog-indoor-exercise-winter-1.3928238',
|
|
110
110
|
'description': 'md5:c18552e41726ee95bd75210d1ca9194c',
|
|
111
111
|
},
|
|
@@ -134,6 +134,13 @@ class CBCIE(InfoExtractor):
|
|
|
134
134
|
title = (self._og_search_title(webpage, default=None)
|
|
135
135
|
or self._html_search_meta('twitter:title', webpage, 'title', default=None)
|
|
136
136
|
or self._html_extract_title(webpage))
|
|
137
|
+
title = self._search_regex(
|
|
138
|
+
r'^(?P<title>.+?)(?:\s*[|–-]\s*CBC.*)?$',
|
|
139
|
+
title, 'cleaned title', group='title', default=title)
|
|
140
|
+
data = self._search_json(
|
|
141
|
+
r'window\.__INITIAL_STATE__\s*=', webpage,
|
|
142
|
+
'initial state', display_id, default={}, transform_source=js_to_json)
|
|
143
|
+
|
|
137
144
|
entries = [
|
|
138
145
|
self._extract_player_init(player_init, display_id)
|
|
139
146
|
for player_init in re.findall(r'CBC\.APP\.Caffeine\.initInstance\(({.+?})\);', webpage)]
|
|
@@ -143,6 +150,11 @@ class CBCIE(InfoExtractor):
|
|
|
143
150
|
r'<div[^>]+\bid=["\']player-(\d+)',
|
|
144
151
|
r'guid["\']\s*:\s*["\'](\d+)'):
|
|
145
152
|
media_ids.extend(re.findall(media_id_re, webpage))
|
|
153
|
+
media_ids.extend(traverse_obj(data, (
|
|
154
|
+
'detail', 'content', 'body', ..., 'content',
|
|
155
|
+
lambda _, v: v['type'] == 'polopoly_media', 'content', 'sourceId', {str})))
|
|
156
|
+
if content_id := traverse_obj(data, ('app', 'contentId', {str})):
|
|
157
|
+
media_ids.append(content_id)
|
|
146
158
|
entries.extend([
|
|
147
159
|
self.url_result(f'cbcplayer:{media_id}', 'CBCPlayer', media_id)
|
|
148
160
|
for media_id in orderedSet(media_ids)])
|
|
@@ -268,7 +280,7 @@ class CBCPlayerIE(InfoExtractor):
|
|
|
268
280
|
'duration': 2692.833,
|
|
269
281
|
'subtitles': {
|
|
270
282
|
'en-US': [{
|
|
271
|
-
'name': 'English
|
|
283
|
+
'name': r're:English',
|
|
272
284
|
'url': 'https://cbchls.akamaized.net/delivery/news-shows/2024/06/17/NAT_JUN16-00-55-00/NAT_JUN16_cc.vtt',
|
|
273
285
|
}],
|
|
274
286
|
},
|
|
@@ -322,6 +334,7 @@ class CBCPlayerIE(InfoExtractor):
|
|
|
322
334
|
'categories': ['Olympics Summer Soccer', 'Summer Olympics Replays', 'Summer Olympics Soccer Replays'],
|
|
323
335
|
'location': 'Canada',
|
|
324
336
|
},
|
|
337
|
+
'skip': 'Video no longer available',
|
|
325
338
|
'params': {'skip_download': 'm3u8'},
|
|
326
339
|
}, {
|
|
327
340
|
'url': 'https://www.cbc.ca/player/play/video/9.6459530',
|
|
@@ -380,7 +393,8 @@ class CBCPlayerIE(InfoExtractor):
|
|
|
380
393
|
video_id = self._match_id(url)
|
|
381
394
|
webpage = self._download_webpage(f'https://www.cbc.ca/player/play/{video_id}', video_id)
|
|
382
395
|
data = self._search_json(
|
|
383
|
-
r'window\.__INITIAL_STATE__\s*=', webpage,
|
|
396
|
+
r'window\.__INITIAL_STATE__\s*=', webpage,
|
|
397
|
+
'initial state', video_id, transform_source=js_to_json)['video']['currentClip']
|
|
384
398
|
assets = traverse_obj(
|
|
385
399
|
data, ('media', 'assets', lambda _, v: url_or_none(v['key']) and v['type']))
|
|
386
400
|
|
|
@@ -492,12 +506,14 @@ class CBCPlayerPlaylistIE(InfoExtractor):
|
|
|
492
506
|
'info_dict': {
|
|
493
507
|
'id': 'news/tv shows/the national/latest broadcast',
|
|
494
508
|
},
|
|
509
|
+
'skip': 'Playlist no longer available',
|
|
495
510
|
}, {
|
|
496
511
|
'url': 'https://www.cbc.ca/player/news/Canada/North',
|
|
497
512
|
'playlist_mincount': 25,
|
|
498
513
|
'info_dict': {
|
|
499
514
|
'id': 'news/canada/north',
|
|
500
515
|
},
|
|
516
|
+
'skip': 'Playlist no longer available',
|
|
501
517
|
}]
|
|
502
518
|
|
|
503
519
|
def _real_extract(self, url):
|
yt_dlp/extractor/ccc.py
CHANGED
|
@@ -18,23 +18,41 @@ class CCCIE(InfoExtractor):
|
|
|
18
18
|
'id': '1839',
|
|
19
19
|
'ext': 'mp4',
|
|
20
20
|
'title': 'Introduction to Processor Design',
|
|
21
|
-
'
|
|
21
|
+
'creators': ['byterazor'],
|
|
22
22
|
'description': 'md5:df55f6d073d4ceae55aae6f2fd98a0ac',
|
|
23
23
|
'thumbnail': r're:^https?://.*\.jpg$',
|
|
24
24
|
'upload_date': '20131228',
|
|
25
25
|
'timestamp': 1388188800,
|
|
26
26
|
'duration': 3710,
|
|
27
27
|
'tags': list,
|
|
28
|
+
'display_id': '30C3_-_5443_-_en_-_saal_g_-_201312281830_-_introduction_to_processor_design_-_byterazor',
|
|
29
|
+
'view_count': int,
|
|
28
30
|
},
|
|
29
31
|
}, {
|
|
30
32
|
'url': 'https://media.ccc.de/v/32c3-7368-shopshifting#download',
|
|
31
33
|
'only_matching': True,
|
|
34
|
+
}, {
|
|
35
|
+
'url': 'https://media.ccc.de/v/39c3-schlechte-karten-it-sicherheit-im-jahr-null-der-epa-fur-alle',
|
|
36
|
+
'info_dict': {
|
|
37
|
+
'id': '16261',
|
|
38
|
+
'ext': 'mp4',
|
|
39
|
+
'title': 'Schlechte Karten - IT-Sicherheit im Jahr null der ePA für alle',
|
|
40
|
+
'display_id': '39c3-schlechte-karten-it-sicherheit-im-jahr-null-der-epa-fur-alle',
|
|
41
|
+
'description': 'md5:719a5a9a52630249d606219c55056cbf',
|
|
42
|
+
'view_count': int,
|
|
43
|
+
'duration': 3619,
|
|
44
|
+
'thumbnail': 'https://static.media.ccc.de/media/congress/2025/2403-2b5a6a8e-327e-594d-8f92-b91201d18a02.jpg',
|
|
45
|
+
'tags': list,
|
|
46
|
+
'creators': ['Bianca Kastl'],
|
|
47
|
+
'timestamp': 1767024900,
|
|
48
|
+
'upload_date': '20251229',
|
|
49
|
+
},
|
|
32
50
|
}]
|
|
33
51
|
|
|
34
52
|
def _real_extract(self, url):
|
|
35
53
|
display_id = self._match_id(url)
|
|
36
54
|
webpage = self._download_webpage(url, display_id)
|
|
37
|
-
event_id = self._search_regex(r"data-id='(
|
|
55
|
+
event_id = self._search_regex(r"data-id=(['\"])(?P<event_id>\d+)\1", webpage, 'event id', group='event_id')
|
|
38
56
|
event_data = self._download_json(f'https://media.ccc.de/public/events/{event_id}', event_id)
|
|
39
57
|
|
|
40
58
|
formats = []
|
yt_dlp/extractor/extractors.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import itertools
|
|
2
2
|
import os
|
|
3
3
|
|
|
4
4
|
from ..globals import LAZY_EXTRACTORS
|
|
@@ -17,12 +17,18 @@ else:
|
|
|
17
17
|
if not _CLASS_LOOKUP:
|
|
18
18
|
from . import _extractors
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
name
|
|
22
|
-
for name
|
|
23
|
-
if name.endswith('IE')
|
|
24
|
-
|
|
25
|
-
_CLASS_LOOKUP
|
|
20
|
+
members = tuple(
|
|
21
|
+
(name, getattr(_extractors, name))
|
|
22
|
+
for name in dir(_extractors)
|
|
23
|
+
if name.endswith('IE')
|
|
24
|
+
)
|
|
25
|
+
_CLASS_LOOKUP = dict(itertools.chain(
|
|
26
|
+
# Add Youtube first to improve matching performance
|
|
27
|
+
((name, value) for name, value in members if '.youtube' in value.__module__),
|
|
28
|
+
# Add Generic last so that it is the fallback
|
|
29
|
+
((name, value) for name, value in members if name != 'GenericIE'),
|
|
30
|
+
(('GenericIE', _extractors.GenericIE),),
|
|
31
|
+
))
|
|
26
32
|
|
|
27
33
|
# We want to append to the main lookup
|
|
28
34
|
_current = _extractors_context.value
|