Skip to content

[server] Mint WebPO tokens from the homepage challenge + ytcfg (fixes #242) - #243

Open
brianstanley wants to merge 1 commit into
Brainicism:masterfrom
brianstanley:fix-att-get-rejection-242
Open

[server] Mint WebPO tokens from the homepage challenge + ytcfg (fixes #242)#243
brianstanley wants to merge 1 commit into
Brainicism:masterfrom
brianstanley:fix-att-get-rejection-242

Conversation

@brianstanley

Copy link
Copy Markdown

Problem

Since late July 2026, YouTube binds the initial BotGuard attestation challenge to the webpage session (yt.config_.EVENT_ID) and rejects WebPO tokens minted from /att/get challenges when the session is enrolled in the experiment — see LuanRT/BgUtils#44 (fixed there in v4.0.3). Symptom, as reported in #242: player requests succeed, then googlevideo rejects the download with HTTP 403. Enforcement looks probabilistic (A/B rollout), so failures are intermittent and provider/IP-independent — I reproduced identical 403s through two different residential proxy pools.

Fix

Port the approach from LuanRT/BgUtils#44 into SessionManager: before falling back to /att/get, fetch https://www.youtube.com through the caller's proxy and extract a self-consistent pair from that single page:

  • ytcfg → injected as globalThis.yt.config_ (and window.yt) so the BotGuard snapshot sees EVENT_ID
  • the initial window.ytAtN(...) challenge → parsed with parseLooseJSON (vendored from BgUtils v4.0.3, MIT — bumping bgutils-js to 4.x is a breaking import restructure I kept out of scope)

The homepage pair is preferred over plugin-passed webpage challenges because those can't be paired with their originating page's ytcfg. /att/get remains as a last-resort fallback whenever the homepage fetch or extraction fails, so behavior is never worse than before. The extra homepage request happens once per minter creation (minters stay cached), not per token.

Validation

Measured on a production workload (yt-dlp 2026.07.04 + this provider, residential proxies, sticky session rotated and /invalidate_caches called between trials to avoid token-cache contamination; 24 trials, 4 videos, audio downloads):

success rate
stock 1.3.1 (/att/get path) 14/24 (58%)
this patch (homepage pair) 22/24 (92%)

Server logs during the patched run: 29× challenge minted from the homepage; the legacy fallback engaged only when the homepage fetch itself failed through a flaky proxy exit. The remaining failures were ordinary per-IP bot challenges, unrelated to the token path.

npx tsc, eslint --max-warnings=0 and prettier all pass.

Fixes #242

…rainicism#242)

YouTube now binds the initial attestation challenge to the webpage
session (yt.config_.EVENT_ID) and rejects WebPO tokens minted from
/att/get challenges when the session is enrolled in the experiment
(see LuanRT/BgUtils#44). Symptom: player requests pass, googlevideo
403s the download.

Fetch https://www.youtube.com through the caller's proxy and extract a
self-consistent pair from that single page: ytcfg (injected as
globalThis.yt.config_ so the BotGuard snapshot sees EVENT_ID) and the
initial window.ytAtN challenge. Plugin-passed webpage challenges can't
be paired with their originating page's ytcfg, so the homepage pair is
preferred; /att/get remains as a last-resort fallback when the homepage
fetch fails, so behavior is never worse than before.

parseLooseJSON is vendored from LuanRT/BgUtils v4.0.3 (MIT) because
bumping bgutils-js to 4.x is a breaking import restructure out of scope
here.
@nicolaasjan

nicolaasjan commented Aug 14, 2026

Copy link
Copy Markdown

Ok, I tested this commit, but I still get:

yt-dlp -v  --extractor-args "youtube:player-client=mweb" https://www.youtube.com/watch?v=iQZ81MbjKpU
[debug] Command-line config: ['-v', '--extractor-args', 'youtube:player-client=mweb', 'https://www.youtube.com/watch?v=iQZ81MbjKpU']
[debug] User config "/home/nico/.config/yt-dlp/config": ['--rm-cache-dir', '--no-playlist', '-o', '/dev/shm/test-dlp/%(title)s.%(ext)s', '-S', 'res:1080,vcodec:h264,acodec:m4a', '--no-windows-filenames', '--embed-metadata', '--embed-thumbnail', '--convert-thumbnails', 'jpg', '--ppa', 'ffmpeg:-metadata synopsis=""', '--force-ipv4', '--sponsorblock-remove', 'all', '--console-title', '-N', '8']
[debug] Encodings: locale UTF-8, fs utf-8, pref UTF-8, out utf-8, error utf-8, screen utf-8
[debug] yt-dlp version local@2026.08.06 [5d6b8c8cd] (zip)
[debug] Python 3.14.7 (CPython x86_64 64bit) - Linux-5.15.0-187-generic-x86_64-with-glibc2.35 (OpenSSL 3.6.3 9 Jun 2026, glibc 2.35)
[debug] exe versions: ffmpeg N-125972-ge13b2e00e8-Nico-20260806 (fdk,setts), ffprobe N-125972-ge13b2e00e8-Nico-20260806, rtmpdump 2.4
[debug] Optional libraries: Cryptodome-3.23.0, brotli-1.2.0, certifi-2026.07.22, curl_cffi-0.15.0, mutagen-1.48.1, requests-2.34.2, secretstorage-3.5.0, sqlite3-3.37.2, urllib3-2.7.0, websockets-17.0.1, yt_dlp_ejs-0.8.0
[debug] JS runtimes: deno-2.9.5
[debug] Proxy map: {}
[debug] Request Handlers: urllib, requests, websockets, curl_cffi
[debug] Plugin directories: /home/nico/.config/yt-dlp/plugins/bgutil-ytdlp-pot-provider/yt_dlp_plugins
[debug] Loaded 1744 extractors
Removing cache dir /home/nico/.cache/yt-dlp ..
[debug] [youtube] [pot:bgutil:script-node] No server_home or script_path passed, defaulting to /home/nico/bgutil-ytdlp-pot-provider/server
[debug] [youtube] [pot:bgutil:script-deno] No server_home or script_path passed, defaulting to /home/nico/bgutil-ytdlp-pot-provider/server
[debug] [youtube] [pot] PO Token Providers: bgutil:http-1.3.1 (external), bgutil:script-node-1.3.1 (external), bgutil:script-deno-1.3.1 (external)
[debug] [youtube] [pot] PO Token Cache Providers: memory
[debug] [youtube] [pot] PO Token Cache Spec Providers: webpo
[debug] [youtube] [jsc] JS Challenge Providers: bun (unavailable), deno, node (unavailable), quickjs (unavailable)
[youtube] Extracting URL: https://www.youtube.com/watch?v=iQZ81MbjKpU
[youtube] iQZ81MbjKpU: Downloading webpage
[youtube] iQZ81MbjKpU: Downloading mweb client config
[debug] [youtube] Forcing "main" player JS variant for player b0d2d49a
        original url = /s/player/b0d2d49a/player_es6.vflset/en_US/base.js
[debug] [youtube] iQZ81MbjKpU: Detected experiment to bind GVS PO Token to video ID for mweb client
[youtube] iQZ81MbjKpU: Downloading mweb player API JSON
[debug] [youtube] iQZ81MbjKpU: Detected a 6s ad for mweb
[debug] [youtube] [pot:bgutil:http] No base_url provided, defaulting to http://127.0.0.1:4416
[youtube] [pot:bgutil:http] Generating a gvs PO Token for mweb client via bgutil HTTP server
[debug] [youtube] iQZ81MbjKpU: Retrieved a gvs PO Token for mweb client
[youtube] iQZ81MbjKpU: Downloading player b0d2d49a-main
[youtube] [jsc:deno] Solving JS challenges using deno
[debug] [youtube] [jsc:deno] Using challenge solver lib script v0.8.0 (source: python package, variant: minified)
[debug] [youtube] [jsc:deno] Using challenge solver core script v0.8.0 (source: python package, variant: minified)
[debug] [youtube] [jsc:deno] Running deno: deno run --ext=js --no-code-cache --no-prompt --no-remote --no-lock --node-modules-dir=none --no-config --no-npm --cached-only -
[debug] [youtube] iQZ81MbjKpU: Retrieved a subs PO Token for mweb client
[debug] Sort order given by user: res:1080, vcodec:h264, acodec:m4a
[debug] Sort order given by extractor: quality, res, fps, hdr:12, source, vcodec, channels, acodec, lang, proto
[debug] Formats sorted by: hasvid, ie_pref, res:1080(1080.0), vcodec:h264(7), acodec:m4a(9), quality, fps, hdr:12(7), source, channels, lang, proto, size, br, asr, vext, aext, hasaud, id
[SponsorBlock] Fetching SponsorBlock segments
[debug] SponsorBlock query: https://sponsor.ajay.app/api/skipSegments/da04?service=YouTube&categories=%5B%22interaction%22%2C+%22preview%22%2C+%22intro%22%2C+%22hook%22%2C+%22music_offtopic%22%2C+%22sponsor%22%2C+%22filler%22%2C+%22outro%22%2C+%22selfpromo%22%5D&actionTypes=%5B%22skip%22%2C+%22poi%22%2C+%22chapter%22%5D
[SponsorBlock] Found 2 segments in the SponsorBlock database
[debug] Default format spec: bestvideo*+bestaudio/best
[info] iQZ81MbjKpU: Downloading 1 format(s): 137+140
[info] Downloading video thumbnail 42 ...
[info] Writing video thumbnail 42 to: /dev/shm/test-dlp/grep isn't what you think it means....webp
[ThumbnailsConvertor] Converting thumbnail "/dev/shm/test-dlp/grep isn't what you think it means....webp" to jpg
[debug] ffmpeg command line: ffmpeg -y -loglevel repeat+info -f image2 -pattern_type none -i 'file:/dev/shm/test-dlp/grep isn'"'"'t what you think it means....webp' -update 1 -qmin 1 -q:v 1 -pix_fmt yuv444p -bsf:v mjpeg2jpeg -movflags +faststart -metadata synopsis= 'file:/dev/shm/test-dlp/grep isn'"'"'t what you think it means....jpg'
Deleting original file /dev/shm/test-dlp/grep isn't what you think it means....webp (pass -k to keep)
[debug] Invoking http downloader on "https://rr3---sn-oj5hn5-55.googlevideo.com/videoplayback?expire=1786739171&ei=gyV_atXgBvDN6dsPr8mhoQY&ip=<REDACTED> &id=o-AK-urY-lbK2XrDMTa3Azj5MufLgVa0C7CZ1aasLs-E-2&itag=137&aitags=133%2C134%2C135%2C136%2C137%2C160%2C242%2C243%2C244%2C247%2C248%2C271%2C278%2C313%2C394%2C395%2C396%2C397%2C398%2C399%2C400%2C401%2C598&source=youtube&requiressl=yes&xpc=EgVo2aDSNQ%3D%3D&cps=365&met=1786717571%2C&mh=Y3&mm=31%2C26&mn=sn-oj5hn5-55%2Csn-4g5lznld&ms=au%2Conr&mv=m&mvi=3&pl=19&rms=au%2Cau&initcwndbps=3776250&bui=AZFlqhNvkjP_99BBSwpBf1n7ona4OR-Q1ciiGpxTj_ZYZzFFeRu7ELclprTxKWCNn3to0WhM2wuGfsvp&spc=KBGBckS0fSmO4PyabzB0U8QUA_IG-3m8HeKG3a7sbwmUKPfCkG51c9s6TH6C3C92Wu3SQSZo6FHdhWstzyfp7qgSC8g&vprv=1&svpuc=1&mime=video%2Fmp4&ns=k0V7LcDQH_E08gPKDB74Hj0X&rqh=1&gir=yes&clen=135727760&dur=692.358&lmt=1751618554721594&mt=1786717030&fvip=1&keepalive=yes&fexp=51565115%2C51946838%2C51973818%2C52089683&c=MWEB&sefc=1&txp=5532534&n=s36E4BPrwEfm9Q&sparams=expire%2Cei%2Cip%2Cid%2Caitags%2Csource%2Crequiressl%2Cxpc%2Cbui%2Cspc%2Cvprv%2Csvpuc%2Cmime%2Cns%2Crqh%2Cgir%2Cclen%2Cdur%2Clmt&sig=AE0s2JYwRgIhALxB7T9CQ3h4gPvTfUlLXkYDEOWKP0I-p1JNgec-D6ZKAiEAryBpUd5oQmuW-6tEYr-wKBbpnq5uQmqPBNr7wV9Opz4%3D&lsparams=cps%2Cmet%2Cmh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Crms%2Cinitcwndbps&lsig=APaTxxMwRgIhAJJaDQV07z22okOjbUVv0mXAL7Zec1o9W1JEVLeWbDKmAiEA88Kvj1_vFYWZmQOzz4TVT5woN2bObhgO0dBBgw5yWzc%3D&pot=MltljgQLKY-0l2XKZ6iXxCfVkMutAHH87ZM3s9aAPBc6eASYhyAHFUnP4RHnhBHG8YpfyHv3DUQzHAmeS6C2nl60eYGohedEZv5_g4RanDJgURN_CQ0ORa9ab6BE"
[download] Sleeping 6.00 seconds as required by the site...
[download] Destination: /dev/shm/test-dlp/grep isn't what you think it means....f137.mp4
[download]   7.5% of  129.44MiB at    7.39MiB/s ETA 00:16ERROR: unable to download video data: HTTP Error 403: Forbidden
Traceback (most recent call last):
  File "/usr/local/bin/yt-dlp/yt_dlp/YoutubeDL.py", line 3571, in process_info
    partial_success, real_download = self.dl(fname, new_info)
                                     ~~~~~~~^^^^^^^^^^^^^^^^^
  File "/usr/local/bin/yt-dlp/yt_dlp/YoutubeDL.py", line 3324, in dl
    return fd.download(name, new_info, subtitle)
           ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/bin/yt-dlp/yt_dlp/downloader/common.py", line 480, in download
    ret = self.real_download(filename, info_dict)
  File "/usr/local/bin/yt-dlp/yt_dlp/downloader/http.py", line 362, in real_download
    establish_connection()
    ~~~~~~~~~~~~~~~~~~~~^^
  File "/usr/local/bin/yt-dlp/yt_dlp/downloader/http.py", line 119, in establish_connection
    ctx.data = self.ydl.urlopen(request)
               ~~~~~~~~~~~~~~~~^^^^^^^^^
  File "/usr/local/bin/yt-dlp/yt_dlp/YoutubeDL.py", line 4305, in urlopen
    return self._request_director.send(req)
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^
  File "/usr/local/bin/yt-dlp/yt_dlp/networking/common.py", line 117, in send
    response = handler.send(request)
  File "/usr/local/bin/yt-dlp/yt_dlp/networking/_helper.py", line 194, in wrapper
    return func(self, *args, **kwargs)
  File "/usr/local/bin/yt-dlp/yt_dlp/networking/common.py", line 359, in send
    return self._send(request)
           ~~~~~~~~~~^^^^^^^^^
  File "/usr/local/bin/yt-dlp/yt_dlp/networking/_requests.py", line 361, in _send
    raise HTTPError(res, redirect_loop=max_redirects_exceeded)
yt_dlp.networking.exceptions.HTTPError: HTTP Error 403: Forbidden

Am I missing something?

[Edit]
Same with cookies provided.

@brianstanley

Copy link
Copy Markdown
Author

Ok, I tested this commit, but I still get: [...] Am I missing something?

Thanks for testing! Quick question though: your log shows the token came from the HTTP provider at 127.0.0.1:4416. Is that process actually running the patched build? If it's an old process or the official Docker image the patch never ran, and the version string says 1.3.1 in both cases so you can't tell from the yt-dlp side.

The easiest way to check is the server console. When this PR mints a token it prints "Using challenge from the homepage (patched)". If you see "Using challenge from the webpage" or "/att/get" instead, it's not the patched build. Also restart the server (or POST to /invalidate_caches) before retrying, since minters are cached server side and --rm-cache-dir only clears yt-dlp's cache.

FWIW I re-ran the comparison today with your exact video and format (mweb, f137). Stock 1.3.1 got a 403 on the first googlevideo request, this branch downloaded the full 129 MiB. Your log also looks a bit different from #242: the first 10 MiB chunk downloaded fine and it died opening the second one, while the #242 failure rejects the very first request. If your server does print the homepage line and still 403s I'm happy to dig further, but let's rule out the build first.

@nicolaasjan

nicolaasjan commented Aug 14, 2026

Copy link
Copy Markdown

Quick question though: your log shows the token came from the HTTP provider at 127.0.0.1:4416. Is that process actually running the patched build?

Well, I just replaced ./server/src/session_manager.ts with your patched version and opened a new terminal with:
~/bgutil-ytdlp-pot-provider/server$ node build/main.js

[Edit]
But in the terminal I still see:

Started POT server (v1.3.1) on on address [::]:4416
Using challenge from the webpage
Generated IntegrityToken: {"integrityToken":"K4WGxvY22RPwTGYynPdy90HBfa/2bPWLSatI5AVtjTtPM49+I/EXcz7h0ThT0HQ9ZHP4v7qvRtPsbsP2IrS51brrJW8=","estimatedTtlSecs":43200,"mintRefreshThreshold":100}
Generating POT for iQZ81MbjKpU
poToken: MlsDZyG_ZwoCYwMjCjrhzPRV2nTR8wE4npRxkGB-GqX0D_bsaBQv7gcOjlxujOh0IZIUFB9etjJRs3daRcyftbjMRbTN0aT8INe6sptUQmWnZY1Wr1HoT71M51fF

@brianstanley

Copy link
Copy Markdown
Author

Well, I just replaced ./server/src/session_manager.ts with your pathed version and opened a new terminal with:
~/bgutil-ytdlp-pot-provider/server$ node build/main.js

Hmm I think that might be it. node build/main.js runs the compiled JS from build/, so swapping the .ts source doesn't do anything until you recompile. Try this in the server dir:

npx tsc
node build/main.js

After that the server console should print "Using challenge from the homepage (patched)" when it mints the token. Curious to hear how it goes.

@nicolaasjan

nicolaasjan commented Aug 14, 2026

Copy link
Copy Markdown

How stupid of me.
After recompile it worked and the download proceeded without error:

nico@nico-desktop:~/bgutil-ytdlp-pot-provider/server$ npx tsc
npm notice
npm notice New major version of npm available! 11.17.0 -> 12.0.2
npm notice Changelog: https://github.com/npm/cli/releases/tag/v12.0.2
npm notice To update run: npm install -g npm@12.0.2
npm notice
nico@nico-desktop:~/bgutil-ytdlp-pot-provider/server$ node build/main.js
Started POT server (v1.3.1) on on address [::]:4416
Using challenge from the homepage (patched)
Using challenge from the webpage
Generated IntegrityToken: {"integrityToken":"O9DaBMZftrUT7MhCDTyiiv8UFm/s+Sc6TbNwBz598NCLevov4fXYAGEfX0FKiBZB/FM/5Q1nBur2wQC4uMyd/g==","estimatedTtlSecs":43200,"mintRefreshThreshold":100}
Generating POT for iQZ81MbjKpU
poToken: MleQF65UW78ebpBXlYSBu9gxJqK9uJP9E1IynVFATdDyl7ct4-cruCATYMclLqGQ_5tIF89LBP5U5oZWUgdkWhMJlv1YlVsHpqIN6ZJbq8h4p2yhYtY1w_U=
yt-dlp -v
yt-dlp -v -f 136+140  --extractor-args "youtube:player-client=mweb" https://www.youtube.com/watch?v=iQZ81MbjKpU
[debug] Command-line config: ['-v', '-f', '136+140', '--extractor-args', 'youtube:player-client=mweb', 'https://www.youtube.com/watch?v=iQZ81MbjKpU']
[debug] User config "/home/nico/.config/yt-dlp/config": ['--rm-cache-dir', '--no-playlist', '-o', '/dev/shm/test-dlp/%(title)s.%(ext)s', '-S', 'res:1080,vcodec:h264,acodec:m4a', '--no-windows-filenames', '--embed-metadata', '--embed-thumbnail', '--convert-thumbnails', 'jpg', '--ppa', 'ffmpeg:-metadata synopsis=""', '--force-ipv4', '--sponsorblock-remove', 'all', '--console-title', '-N', '8']
[debug] Encodings: locale UTF-8, fs utf-8, pref UTF-8, out utf-8, error utf-8, screen utf-8
[debug] yt-dlp version local@2026.08.06 [5d6b8c8cd] (zip)
[debug] Python 3.14.7 (CPython x86_64 64bit) - Linux-5.15.0-187-generic-x86_64-with-glibc2.35 (OpenSSL 3.6.3 9 Jun 2026, glibc 2.35)
[debug] exe versions: ffmpeg N-125972-ge13b2e00e8-Nico-20260806 (fdk,setts), ffprobe N-125972-ge13b2e00e8-Nico-20260806, rtmpdump 2.4
[debug] Optional libraries: Cryptodome-3.23.0, brotli-1.2.0, certifi-2026.07.22, curl_cffi-0.15.0, mutagen-1.48.1, requests-2.34.2, secretstorage-3.5.0, sqlite3-3.37.2, urllib3-2.7.0, websockets-17.0.1, yt_dlp_ejs-0.8.0
[debug] JS runtimes: deno-2.9.5
[debug] Proxy map: {}
[debug] Request Handlers: urllib, requests, websockets, curl_cffi
[debug] Plugin directories: /home/nico/.config/yt-dlp/plugins/bgutil-ytdlp-pot-provider/yt_dlp_plugins
[debug] Loaded 1744 extractors
Removing cache dir /home/nico/.cache/yt-dlp ..
[debug] [youtube] [pot:bgutil:script-node] No server_home or script_path passed, defaulting to /home/nico/bgutil-ytdlp-pot-provider/server
[debug] [youtube] [pot:bgutil:script-deno] No server_home or script_path passed, defaulting to /home/nico/bgutil-ytdlp-pot-provider/server
[debug] [youtube] [pot] PO Token Providers: bgutil:http-1.3.1 (external), bgutil:script-node-1.3.1 (external), bgutil:script-deno-1.3.1 (external)
[debug] [youtube] [pot] PO Token Cache Providers: memory
[debug] [youtube] [pot] PO Token Cache Spec Providers: webpo
[debug] [youtube] [jsc] JS Challenge Providers: bun (unavailable), deno, node (unavailable), quickjs (unavailable)
[youtube] Extracting URL: https://www.youtube.com/watch?v=iQZ81MbjKpU
[youtube] iQZ81MbjKpU: Downloading webpage
[youtube] iQZ81MbjKpU: Downloading mweb client config
[debug] [youtube] Forcing "main" player JS variant for player b0d2d49a
        original url = /s/player/b0d2d49a/player_es6.vflset/en_US/base.js
[debug] [youtube] iQZ81MbjKpU: Detected experiment to bind GVS PO Token to video ID for mweb client
[youtube] iQZ81MbjKpU: Downloading mweb player API JSON
[debug] [youtube] iQZ81MbjKpU: Detected a 6s ad for mweb
[debug] [youtube] [pot:bgutil:http] No base_url provided, defaulting to http://127.0.0.1:4416
[youtube] [pot:bgutil:http] Generating a gvs PO Token for mweb client via bgutil HTTP server
[debug] [youtube] iQZ81MbjKpU: Retrieved a gvs PO Token for mweb client
[youtube] iQZ81MbjKpU: Downloading player b0d2d49a-main
[youtube] [jsc:deno] Solving JS challenges using deno
[debug] [youtube] [jsc:deno] Using challenge solver lib script v0.8.0 (source: python package, variant: minified)
[debug] [youtube] [jsc:deno] Using challenge solver core script v0.8.0 (source: python package, variant: minified)
[debug] [youtube] [jsc:deno] Running deno: deno run --ext=js --no-code-cache --no-prompt --no-remote --no-lock --node-modules-dir=none --no-config --no-npm --cached-only -
[debug] [youtube] iQZ81MbjKpU: Retrieved a subs PO Token for mweb client
[debug] Sort order given by user: res:1080, vcodec:h264, acodec:m4a
[debug] Sort order given by extractor: quality, res, fps, hdr:12, source, vcodec, channels, acodec, lang, proto
[debug] Formats sorted by: hasvid, ie_pref, res:1080(1080.0), vcodec:h264(7), acodec:m4a(9), quality, fps, hdr:12(7), source, channels, lang, proto, size, br, asr, vext, aext, hasaud, id
[SponsorBlock] Fetching SponsorBlock segments
[debug] SponsorBlock query: https://sponsor.ajay.app/api/skipSegments/da04?service=YouTube&categories=%5B%22outro%22%2C+%22selfpromo%22%2C+%22hook%22%2C+%22sponsor%22%2C+%22preview%22%2C+%22filler%22%2C+%22interaction%22%2C+%22music_offtopic%22%2C+%22intro%22%5D&actionTypes=%5B%22skip%22%2C+%22poi%22%2C+%22chapter%22%5D
[SponsorBlock] Found 2 segments in the SponsorBlock database
[info] iQZ81MbjKpU: Downloading 1 format(s): 136+140
[info] Downloading video thumbnail 42 ...
[info] Writing video thumbnail 42 to: /dev/shm/test-dlp/grep isn't what you think it means....webp
[ThumbnailsConvertor] Converting thumbnail "/dev/shm/test-dlp/grep isn't what you think it means....webp" to jpg
[debug] ffmpeg command line: ffmpeg -y -loglevel repeat+info -f image2 -pattern_type none -i 'file:/dev/shm/test-dlp/grep isn'"'"'t what you think it means....webp' -update 1 -qmin 1 -q:v 1 -pix_fmt yuv444p -bsf:v mjpeg2jpeg -movflags +faststart -metadata synopsis= 'file:/dev/shm/test-dlp/grep isn'"'"'t what you think it means....jpg'
Deleting original file /dev/shm/test-dlp/grep isn't what you think it means....webp (pass -k to keep)
[debug] Invoking http downloader on "https://rr2---sn-u15hn5-51.googlevideo.com/videoplayback?expire=1786743786&ei=ijd_aqCxE7bHi9oPjeKn8Q4&ip=<REDACTED> &id=o-AOLJIl2hQCuKZswlPYibTEqmOpGrB55nl_kY4koxHqDQ&itag=136&aitags=133%2C134%2C135%2C136%2C137%2C160%2C242%2C243%2C244%2C247%2C248%2C271%2C278%2C313%2C394%2C395%2C396%2C397%2C398%2C399%2C400%2C401%2C598&source=youtube&requiressl=yes&xpc=EgVo2aDSNQ%3D%3D&cps=289&met=1786722186%2C&mh=Y3&mm=31%2C26&mn=sn-u15hn5-51%2Csn-4g5lznld&ms=au%2Conr&mv=m&mvi=2&pl=19&rms=au%2Cau&initcwndbps=3966250&bui=AZFlqhOJ4B3GCiH_8XAzcICv8s8-odUSVsTXZUP_YqlYWJgelIv9uFx-PiEEqy1zpYA9UcWIZ3Mz7-is&spc=KBGBcuzLatakgBYTQqBphhfQMkk06QtaK17532C-4t3YCyoTR3mlP7-KV1fg2w2JN1aExW2lZC0BPMk0GXrCCwbUAmY&vprv=1&svpuc=1&mime=video%2Fmp4&ns=hye069UmajocsZCAf1vi-eYX&rqh=1&gir=yes&clen=50230019&dur=692.358&lmt=1751618786640314&mt=1786721845&fvip=1&keepalive=yes&fexp=51565116%2C51946837%2C51973818%2C52089683&c=MWEB&sefc=1&txp=5532534&n=7S7lca2tpf0L_Q&sparams=expire%2Cei%2Cip%2Cid%2Caitags%2Csource%2Crequiressl%2Cxpc%2Cbui%2Cspc%2Cvprv%2Csvpuc%2Cmime%2Cns%2Crqh%2Cgir%2Cclen%2Cdur%2Clmt&sig=AE0s2JYwRQIhAKEUabOk4R7i4_g6WAN-zIwlZd7S3TMYBTyZ40VhGE2ZAiA9Ep9or9vj7iQNV-AymlZUwyRab-urepffQCI3o-HUGw%3D%3D&lsparams=cps%2Cmet%2Cmh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Crms%2Cinitcwndbps&lsig=APaTxxMwRAIgAf_0fHJkzhghnA-GbUgDmP0cTj2IDx-hv1AyAA362uwCICrcl0AGWX6vEepflEOaS0BzRX2MMQqMaPweVK8HOtYd&pot=MleQF65UW78ebpBXlYSBu9gxJqK9uJP9E1IynVFATdDyl7ct4-cruCATYMclLqGQ_5tIF89LBP5U5oZWUgdkWhMJlv1YlVsHpqIN6ZJbq8h4p2yhYtY1w_U%3D"
[download] Sleeping 5.00 seconds as required by the site...
[download] Destination: /dev/shm/test-dlp/grep isn't what you think it means....f136.mp4
[download] 100% of   47.90MiB in 00:00:06 at 7.33MiB/s
[debug] Invoking http downloader on "https://rr2---sn-u15hn5-51.googlevideo.com/videoplayback?expire=1786743786&ei=ijd_aqCxE7bHi9oPjeKn8Q4&ip=<REDACTED> &id=o-AOLJIl2hQCuKZswlPYibTEqmOpGrB55nl_kY4koxHqDQ&itag=140&source=youtube&requiressl=yes&xpc=EgVo2aDSNQ%3D%3D&cps=289&met=1786722186%2C&mh=Y3&mm=31%2C26&mn=sn-u15hn5-51%2Csn-4g5lznld&ms=au%2Conr&mv=m&mvi=2&pl=19&rms=au%2Cau&initcwndbps=3966250&bui=AZFlqhOJ4B3GCiH_8XAzcICv8s8-odUSVsTXZUP_YqlYWJgelIv9uFx-PiEEqy1zpYA9UcWIZ3Mz7-is&spc=KBGBcuzLatakgBYTQqBphhfQMkk06QtaK17532C-4t3YCyoTR3mlP7-KV1fg2w2JN1aExW2lZC0BPMk0GXrCCwbUAmY&vprv=1&svpuc=1&mime=audio%2Fmp4&ns=hye069UmajocsZCAf1vi-eYX&rqh=1&gir=yes&clen=11206859&dur=692.419&lmt=1751616540112306&mt=1786721845&fvip=1&keepalive=yes&fexp=51565116%2C51946837%2C51973818%2C52089683&c=MWEB&sefc=1&txp=5532534&n=7S7lca2tpf0L_Q&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cxpc%2Cbui%2Cspc%2Cvprv%2Csvpuc%2Cmime%2Cns%2Crqh%2Cgir%2Cclen%2Cdur%2Clmt&sig=AE0s2JYwRQIhAPtYxgWmxZrswvxD7ejsXM9So-NQ_OHg4kmVZYkJIcqzAiAHxwzKdIMr6qz3Q2Up22tNwnYFgMtQUhFtFZdRwCeUTQ%3D%3D&lsparams=cps%2Cmet%2Cmh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Crms%2Cinitcwndbps&lsig=APaTxxMwRAIgAf_0fHJkzhghnA-GbUgDmP0cTj2IDx-hv1AyAA362uwCICrcl0AGWX6vEepflEOaS0BzRX2MMQqMaPweVK8HOtYd&pot=MleQF65UW78ebpBXlYSBu9gxJqK9uJP9E1IynVFATdDyl7ct4-cruCATYMclLqGQ_5tIF89LBP5U5oZWUgdkWhMJlv1YlVsHpqIN6ZJbq8h4p2yhYtY1w_U%3D"
[download] Destination: /dev/shm/test-dlp/grep isn't what you think it means....f140.m4a
[download] 100% of   10.69MiB in 00:00:02 at 4.70MiB/s
[Merger] Merging formats into "/dev/shm/test-dlp/grep isn't what you think it means....mp4"
[debug] ffmpeg command line: ffmpeg -y -loglevel repeat+info -i 'file:/dev/shm/test-dlp/grep isn'"'"'t what you think it means....f136.mp4' -i 'file:/dev/shm/test-dlp/grep isn'"'"'t what you think it means....f140.m4a' -c copy -map 0:v:0 -map 1:a:0 -movflags +faststart -metadata synopsis= 'file:/dev/shm/test-dlp/grep isn'"'"'t what you think it means....temp.mp4'
Deleting original file /dev/shm/test-dlp/grep isn't what you think it means....f136.mp4 (pass -k to keep)
Deleting original file /dev/shm/test-dlp/grep isn't what you think it means....f140.m4a (pass -k to keep)
[debug] ffprobe command line: ffprobe -hide_banner -show_format -show_streams -print_format json 'file:/dev/shm/test-dlp/grep isn'"'"'t what you think it means....mp4'
[debug] Concat spec = 26.490000-673.680000, 685.848000-inf
[ModifyChapters] Removing chapters from /dev/shm/test-dlp/grep isn't what you think it means....mp4
[debug] Writing concat spec to /dev/shm/test-dlp/grep isn't what you think it means....temp.mp4.concat
[debug] ffmpeg command line: ffmpeg -y -loglevel repeat+info -hide_banner -nostdin -f concat -safe 0 -i 'file:/dev/shm/test-dlp/grep isn'"'"'t what you think it means....temp.mp4.concat' -map 0 -dn -ignore_unknown -c copy -c:s mov_text -movflags +faststart -metadata synopsis= 'file:/dev/shm/test-dlp/grep isn'"'"'t what you think it means....temp.mp4'
Deleting original file /dev/shm/test-dlp/grep isn't what you think it means....uncut.mp4 (pass -k to keep)
[Metadata] Adding metadata to "/dev/shm/test-dlp/grep isn't what you think it means....mp4"
[debug] ffmpeg command line: ffmpeg -y -loglevel repeat+info -i 'file:/dev/shm/test-dlp/grep isn'"'"'t what you think it means....mp4' -i 'file:/dev/shm/test-dlp/grep isn'"'"'t what you think it means....meta' -map 0 -dn -ignore_unknown -c copy -map_metadata 1 -write_id3v1 1 -metadata 'title=grep isn'"'"'t what you think it means...' -metadata date=20250701 -metadata 'description=Ever wonder why your favorite UNIX command is called "grep"?  And what the heck does it have to do with the Founding Fathers?

Join me as we discuss linguistics research, Bell Labs, the American Revolution, and how it all resulted in the linux tool we all depend upon!

---

Timestamps
00:00 The Phone Call that Created grep
01:05 Linguistic fingerprinting
02:55 A Historical Mystery...
05:00 PDP-7 Limitations
07:40 Ken Thompson'"'"'s Overnight Hack
10:27 Essential Tool or Unix Junk?

---

Follow LaurieWired on Social Media:
►https://linktr.ee/lauriewired

---

Works Cited:

Unix: An Oral History (Princeton):
https://web.archive.org/web/20200803035038/https://www.princeton.edu/~hos/frs122/unixhist/finalhis.htm

The Federalist Papers (Library of Congress):
https://guides.loc.gov/federalist-papers/full-text

The History of grep (Rualthanzauva):
https://medium.com/@rualthanzauva/grep-was-a-private-command-of-mine-for-quite-a-while-before-i-made-it-public-ken-thompson-a40e24a5ef48' -metadata 'synopsis=Ever wonder why your favorite UNIX command is called "grep"?  And what the heck does it have to do with the Founding Fathers?

Join me as we discuss linguistics research, Bell Labs, the American Revolution, and how it all resulted in the linux tool we all depend upon!

---

Timestamps
00:00 The Phone Call that Created grep
01:05 Linguistic fingerprinting
02:55 A Historical Mystery...
05:00 PDP-7 Limitations
07:40 Ken Thompson'"'"'s Overnight Hack
10:27 Essential Tool or Unix Junk?

---

Follow LaurieWired on Social Media:
►https://linktr.ee/lauriewired

---

Works Cited:

Unix: An Oral History (Princeton):
https://web.archive.org/web/20200803035038/https://www.princeton.edu/~hos/frs122/unixhist/finalhis.htm

The Federalist Papers (Library of Congress):
https://guides.loc.gov/federalist-papers/full-text

The History of grep (Rualthanzauva):
https://medium.com/@rualthanzauva/grep-was-a-private-command-of-mine-for-quite-a-while-before-i-made-it-public-ken-thompson-a40e24a5ef48' -metadata 'purl=https://www.youtube.com/watch?v=iQZ81MbjKpU' -metadata 'comment=https://www.youtube.com/watch?v=iQZ81MbjKpU' -metadata artist=LaurieWired -metadata 'genre=Science & Technology' -metadata:s:1 language=eng -movflags +faststart -metadata synopsis= 'file:/dev/shm/test-dlp/grep isn'"'"'t what you think it means....temp.mp4'
[EmbedThumbnail] mutagen: Adding thumbnail to "/dev/shm/test-dlp/grep isn't what you think it means....mp4"

Btw, is it safe to update npm?

[Edit]
I think I'll leave npm at its current version, which is installed in:
/opt/node/lib/node_modules/npm

@brianstanley

Copy link
Copy Markdown
Author

Nice, glad it works! Thanks for taking the time to test it.

About npm, I think it's fine to update, that notice pops up on every npm command and has nothing to do with this project. Just check your Node version first, I believe npm 12 wants Node 22.22+. On older Node I'd stay on npm 11, works fine either way.

@ionenwks

ionenwks commented Aug 16, 2026

Copy link
Copy Markdown

Just to say that I've been using this PR for 2 weeks w/ mweb and it seems to be working perfectly, all the random failures I kept having haven't happened once since. Not to say I may not just have been lucky if I did something wrong / misunderstood this.

(personally using it without a server running the script directly, built and used it with deno)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Occasionally not getting valid YouTube playback tokens

3 participants