feat(downloads): automatic PO-token provider (bgutil sidecar) to beat YouTube bot-detection
YouTube increasingly demands a Proof-of-Origin token (or shows 'confirm you're not a bot'). Instead of manual cookies, run the bgutil POT provider as a sidecar that mints tokens on demand: - compose: bgutil-pot service (brainicism/bgutil-ytdlp-pot-provider:1.3.1, port 4416, init) - requirements: bgutil-ytdlp-pot-provider==1.3.1 plugin (version pinned to the image) - config: DOWNLOAD_POT_BASE_URL (http://bgutil-pot:4416) + DOWNLOAD_PLAYER_CLIENTS (web_safari,web,tv — POT-capable; the default android_vr client never requests a token) - formats.build_ydl_opts wires extractor_args youtube:player_client + youtubepot-bgutilhttp:base_url Verified: the sidecar mints a valid PO token (BotGuard challenge solved) and yt-dlp fetches it from the provider. NOTE: end-to-end download couldn't be confirmed here because the test IP got hard-flagged by YouTube from heavy testing (~16 GB + dozens of extractions) — a hard abuse block needs cooldown/cookies, which POT doesn't lift; POT bypasses the normal soft bot-check.
This commit is contained in:
parent
d7fe3c34e8
commit
03a1865aa8
5 changed files with 58 additions and 4 deletions
|
|
@ -81,8 +81,17 @@ def target_ext(spec: dict) -> str:
|
|||
return s["container"] or "mp4"
|
||||
|
||||
|
||||
def build_ydl_opts(spec: dict, outtmpl: str, progress_hook) -> dict:
|
||||
"""Assemble yt-dlp options for a single download to `outtmpl` (a full path template)."""
|
||||
def build_ydl_opts(
|
||||
spec: dict,
|
||||
outtmpl: str,
|
||||
progress_hook,
|
||||
pot_base_url: str | None = None,
|
||||
player_clients: list[str] | None = None,
|
||||
) -> dict:
|
||||
"""Assemble yt-dlp options for a single download to `outtmpl` (a full path template).
|
||||
|
||||
`pot_base_url` points the bgutil PO-token provider plugin at the sidecar server;
|
||||
`player_clients` picks which YouTube clients to use (POT-capable ones like web use the token)."""
|
||||
s = normalize(spec)
|
||||
h = s["max_height"]
|
||||
opts: dict = {
|
||||
|
|
@ -107,6 +116,17 @@ def build_ydl_opts(spec: dict, outtmpl: str, progress_hook) -> dict:
|
|||
"socket_timeout": 30,
|
||||
}
|
||||
|
||||
# Extractor args: which YouTube clients to use + where the bgutil PO-token sidecar lives
|
||||
# (== --extractor-args "youtube:player_client=…;youtubepot-bgutilhttp:base_url=…"). Values
|
||||
# are lists in the Python API.
|
||||
ea: dict = {}
|
||||
if player_clients:
|
||||
ea["youtube"] = {"player_client": player_clients}
|
||||
if pot_base_url:
|
||||
ea["youtubepot-bgutilhttp"] = {"base_url": [pot_base_url]}
|
||||
if ea:
|
||||
opts["extractor_args"] = ea
|
||||
|
||||
if s["mode"] == "a":
|
||||
opts["format"] = "bestaudio/best"
|
||||
opts["postprocessors"].append(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue