Skip to content
Media · EME · Widevine L3

Widevine DRM for automated Chromium

Open-source Chromium builds ship without the Widevine CDM, so DRM video fails and requestMediaKeySystemAccess('com.widevine.alpha') rejects, where a stock desktop Chrome normally resolves it. Pass widevine when you launch and the SDK fetches the CDM from Google's component server, checks it and switches it on.

In every tier, opt-in.

One launch option

from clearcote import launch_persistent_context

ctx = launch_persistent_context("./profile-drm", widevine=True)   # fetch, verify, enable
page = ctx.pages[0] if ctx.pages else ctx.new_page()
page.goto("https://your-drm-site.example")
# navigator.requestMediaKeySystemAccess('com.widevine.alpha') now resolves

Highlights

Fetched the way Chrome gets it

The CDM comes from Google's own component server, the way stock Chrome receives it, and is downloaded once per version. Clearcote never distributes it.

Verified before use

The download is SHA-256 checked, and a missing hash is refused outright, because the CDM is a native library.

Cached and reusable

Stored under ~/.clearcote/WidevineCdm, so it downloads once per version. Fetch it ahead of time with fetchWidevine() to keep the download out of your first launch; each launch still makes one quick version check to Google, directly from this machine.

A coherent EME answer

A real Chrome resolves the Widevine key-system query. With the CDM in place, so does Clearcote.

Fails soft

If the CDM can't be fetched, the launch carries on without DRM instead of failing.

L3 playback

Software-secure (L3) playback. Hardware-secure L1 is out of scope.

Why it's opt-in

Google's CDM is a closed binary. It can't be part of the open-source open build, and Clearcote doesn't redistribute it with the licensed build either. So the browser ships with the EME plumbing compiled in, but not the CDM, and you trigger the download yourself.

The CDM lives in the profile. In Python it works with launch_persistent_context and with launch(), which runs on a throwaway profile (the sync API; the async launch() is incognito, so use launch_persistent_context there); in Node use launchPersistentContext. The incognito launch (ephemeral_profile=False) can't take it. The SDK re-enables the component updater and, on Windows, forces a quick update scan, so the engine registers the CDM.

It matters beyond video, too. Whether the Widevine key system resolves is one more thing a page can read, and a Chrome that can't answer it doesn't look like Chrome.

What people use it for

Streaming QA

Test playback, entitlements and player UI on your own DRM-protected catalogue.

Media monitoring

Automated checks on pages that play protected video.

A complete Chrome persona

Keep the EME answer consistent with a real Chrome, even when you never play a video.

Clearcote is built for privacy, testing, research and lawful automation. You're responsible for how you use it and for following the terms of the sites you visit.

The diff

38,921 lines between stock Chromium and Clearcote Pro.

That is how far the Pro build is from the Chromium Google ships. Every value a site can read is set where Chromium computes it, so the page, its workers and its iframes all describe the same device.

  • Canvas
  • WebGL
  • WebGPU
  • Audio
  • Fonts
  • Screen and window
  • WebRTC
  • TLS
  • Client hints
  • Input timing
  • Voices and codecs
Read the open build's patches on GitHub

Pro build, counted from its r57 patch stack (Chromium 156.0.8078.47). The free open build is a smaller, public patch set.

Chromium 156.0.8078.47 → Clearcote Pro r57

345 files changed, 35915 insertions(+), 3006 deletions(-)

240 patches

Files changed, by area

  • Rendering engine (Blink)118
  • Browser (chrome/)52
  • Content layer42
  • Components39
  • Network stack22
  • UI and windows14
  • TLS (BoringSSL)11
  • V8 and URL17
  • Everything else30

Which plan includes it

In every tier, opt-in, with software-secure (L3) playback.

Compare plans

FAQ

How do I enable Widevine in Playwright?

Launch with the Clearcote SDK and pass widevine=True (Python: the sync launch() or a persistent context) or widevine: true (Node, launchPersistentContext). It downloads the CDM once, verifies it, seeds it into the profile and enables it. The .NET SDK has no Widevine option yet.

Why doesn't open-source Chromium play DRM video?

The Widevine CDM is proprietary and can't be shipped in an open-source build, so without it, DRM playback and the EME key-system query both fail.

Does Clearcote include the CDM?

No. The CDM is fetched from Google's component server when you opt in, the same way stock Chrome receives it. Clearcote never distributes it.

Which security level is supported?

Software-secure L3. Hardware-secure L1, which some services require for high resolutions, is out of scope.

Do I need a persistent profile?

It needs a profile, but not necessarily a kept one. The CDM is installed into the profile, so in Python the throwaway profile behind the sync launch() works as well as launch_persistent_context (the async launch() is incognito); in Node use launchPersistentContext. Only the incognito launch (ephemeral_profile=False) can't take it.

Go deeper in the docs

Related features

Try Clearcote

A drop-in for Playwright & Puppeteer, coherent down to the TLS handshake, with an open-source build to start from.

Free for one browser: GitHub, a card check or a company Google account. Never charged.