Skip to content

Commit f7acf3c

Browse files
[ie/youtube] Add use_ad_playback_context extractor-arg (yt-dlp#15220)
Closes yt-dlp#15144 Authored by: WhatAmISupposedToPutHere
1 parent 017d76e commit f7acf3c

File tree

3 files changed

+24
-5
lines changed

3 files changed

+24
-5
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1871,6 +1871,7 @@ The following extractors use this feature:
18711871
* `pot_trace`: Enable debug logging for PO Token fetching. Either `true` or `false` (default)
18721872
* `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)
18731873
* `jsc_trace`: Enable debug logging for JS Challenge fetching. Either `true` or `false` (default)
1874+
* `use_ad_playback_context`: Skip preroll ads to eliminate the mandatory wait period before download. Do NOT use this when passing premium account cookies to yt-dlp, as it will result in a loss of premium formats. Only effective with the `web`, `web_safari`, `web_music` and `mweb` player clients. Either `true` or `false` (default)
18741875

18751876
#### youtube-ejs
18761877
* `jitless`: Run suported Javascript engines in JIT-less mode. Supported runtimes are `deno`, `node` and `bun`. Provides better security at the cost of performance/speed. Do note that `node` and `bun` are still considered unsecure. Either `true` or `false` (default)

yt_dlp/extractor/youtube/_base.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ class SubsPoTokenPolicy(BasePoTokenPolicy):
104104
},
105105
'INNERTUBE_CONTEXT_CLIENT_NAME': 1,
106106
'SUPPORTS_COOKIES': True,
107+
'SUPPORTS_AD_PLAYBACK_CONTEXT': True,
107108
**WEB_PO_TOKEN_POLICIES,
108109
},
109110
# Safari UA returns pre-merged video+audio 144p/240p/360p/720p/1080p HLS formats
@@ -117,6 +118,7 @@ class SubsPoTokenPolicy(BasePoTokenPolicy):
117118
},
118119
'INNERTUBE_CONTEXT_CLIENT_NAME': 1,
119120
'SUPPORTS_COOKIES': True,
121+
'SUPPORTS_AD_PLAYBACK_CONTEXT': True,
120122
**WEB_PO_TOKEN_POLICIES,
121123
},
122124
'web_embedded': {
@@ -157,6 +159,7 @@ class SubsPoTokenPolicy(BasePoTokenPolicy):
157159
),
158160
},
159161
'SUPPORTS_COOKIES': True,
162+
'SUPPORTS_AD_PLAYBACK_CONTEXT': True,
160163
},
161164
# This client now requires sign-in for every video
162165
'web_creator': {
@@ -313,6 +316,7 @@ class SubsPoTokenPolicy(BasePoTokenPolicy):
313316
),
314317
},
315318
'SUPPORTS_COOKIES': True,
319+
'SUPPORTS_AD_PLAYBACK_CONTEXT': True,
316320
},
317321
'tv': {
318322
'INNERTUBE_CONTEXT': {
@@ -412,6 +416,7 @@ def build_innertube_clients():
412416
ytcfg.setdefault('SUBS_PO_TOKEN_POLICY', SubsPoTokenPolicy())
413417
ytcfg.setdefault('REQUIRE_AUTH', False)
414418
ytcfg.setdefault('SUPPORTS_COOKIES', False)
419+
ytcfg.setdefault('SUPPORTS_AD_PLAYBACK_CONTEXT', False)
415420
ytcfg.setdefault('PLAYER_PARAMS', None)
416421
ytcfg.setdefault('AUTHENTICATED_USER_AGENT', None)
417422
ytcfg['INNERTUBE_CONTEXT']['client'].setdefault('hl', 'en')

yt_dlp/extractor/youtube/_video.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2629,16 +2629,23 @@ def _get_checkok_params():
26292629
return {'contentCheckOk': True, 'racyCheckOk': True}
26302630

26312631
@classmethod
2632-
def _generate_player_context(cls, sts=None):
2632+
def _generate_player_context(cls, sts=None, use_ad_playback_context=False):
26332633
context = {
26342634
'html5Preference': 'HTML5_PREF_WANTS',
26352635
}
26362636
if sts is not None:
26372637
context['signatureTimestamp'] = sts
2638+
2639+
playback_context = {
2640+
'contentPlaybackContext': context,
2641+
}
2642+
if use_ad_playback_context:
2643+
playback_context['adPlaybackContext'] = {
2644+
'pyv': True,
2645+
}
2646+
26382647
return {
2639-
'playbackContext': {
2640-
'contentPlaybackContext': context,
2641-
},
2648+
'playbackContext': playback_context,
26422649
**cls._get_checkok_params(),
26432650
}
26442651

@@ -2866,7 +2873,13 @@ def _extract_player_response(self, client, video_id, webpage_ytcfg, player_ytcfg
28662873
yt_query['serviceIntegrityDimensions'] = {'poToken': po_token}
28672874

28682875
sts = self._extract_signature_timestamp(video_id, player_url, webpage_ytcfg, fatal=False) if player_url else None
2869-
yt_query.update(self._generate_player_context(sts))
2876+
2877+
use_ad_playback_context = (
2878+
self._configuration_arg('use_ad_playback_context', ['false'])[0] != 'false'
2879+
and traverse_obj(INNERTUBE_CLIENTS, (client, 'SUPPORTS_AD_PLAYBACK_CONTEXT', {bool})))
2880+
2881+
yt_query.update(self._generate_player_context(sts, use_ad_playback_context))
2882+
28702883
return self._extract_response(
28712884
item_id=video_id, ep='player', query=yt_query,
28722885
ytcfg=player_ytcfg, headers=headers, fatal=True,

0 commit comments

Comments
 (0)