feat(widevine): auto-seed CDM hint file for persistent contexts (Linux)

Sideloaded Widevine works on the first launch of a persistent context
instead of needing a manual two-launch hint-file workaround. The wrapper
writes Chromium's CDM hint file into the profile before launch when a
WidevineCdm directory is present next to the binary.

- New cloakbrowser/widevine.py and js/src/widevine.ts: resolve a sideloaded
  CDM (CLOAKBROWSER_WIDEVINE_CDM env var, else next to the binary) and seed
  the hint file. Linux only; no-op elsewhere. CLOAKBROWSER_WIDEVINE=0 disables.
- Never bundles/downloads/copies the CDM (proprietary); seeds only when the
  user-provided CDM is already present.
- Wired into launch_persistent_context[_async] and launchPersistentContext.
- README + js/README: Widevine / DRM section, env vars, FPJS tradeoff note.
- Tests: tests/test_widevine.py, js/tests/widevine.test.ts, persistent-context
  integration assertions.
This commit is contained in:
CloakHQ
2026-05-29 22:59:59 +02:00
parent 14ec2ebf5f
commit dcf9ba55d6
11 changed files with 676 additions and 1 deletions
+3
View File
@@ -11,6 +11,7 @@ import { buildArgs } from "./args.js";
import { ensureBinary } from "./download.js";
import { isSocksProxy, normalizeHttpStringUrl, parseProxyUrl, reconstructHttpUrl, resolveProxyConfig, supportsHttpProxyInlineAuth } from "./proxy.js";
import { maybeResolveGeoip, resolveWebrtcArgs } from "./geoip.js";
import { seedWidevineHint } from "./widevine.js";
/** Resolve binary path, geoip, webrtc, and build final Chrome args. */
async function resolveArgs(options: LaunchOptions): Promise<{ binaryPath: string; args: string[] }> {
@@ -155,6 +156,8 @@ export async function launchPersistentContext(
const { binaryPath, args } = await resolveArgs(options);
const proxyAuth = resolveProxy(options, args);
seedWidevineHint(options.userDataDir, binaryPath);
const browser = await puppeteer.default.launch({
...options.launchOptions,
executablePath: binaryPath,