npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@javagt/widevine

v1.9.0

Published

Pure TypeScript port of pywidevine — Widevine CDM protocol implementation (ported by DeepSeek V4 Flash)

Readme

@javagt/widevine

Version 1.9.0 — Pure TypeScript port of pywidevine v1.9.0, implemented by DeepSeek V4 Flash.

Version numbers are kept in sync with the original pywidevine releases.

Installation

npm install @javagt/widevine

Library Usage

import { Device, Cdm, PSSH, Key, VERSION } from '@javagt/widevine';

// 1. Load a WVD device file
const device = Device.load('/path/to/device.wvd');

// 2. Create CDM instance from the device
const cdm = Cdm.fromDevice(device);

// 3. Open a session
const sessionId = cdm.open();

// 4. Parse the PSSH box from base64
const pssh = new PSSH('AAAAW3Bzc2g...');

// 5. Build a signed license challenge
const challenge = cdm.getLicenseChallenge(sessionId, pssh);

// 6. Send to license server (any HTTP client)
const response = await fetch(licenseUrl, {
  method: 'POST',
  body: challenge,
  headers: { 'Content-Type': 'application/octet-stream' },
});

// 7. Parse the license response
cdm.parseLicense(sessionId, Buffer.from(await response.arrayBuffer()));

// 8. Extract decrypted content keys
const keys = cdm.getKeys(sessionId, 'CONTENT');
for (const key of keys) {
  console.log(`${key.kid.toString('hex')}:${key.key.toString('hex')}`);
}

// 9. Clean up
cdm.close(sessionId);

ESM Imports

All exports are available as named ESM imports:

import { Device, Cdm, PSSH, Key, Session } from '@javagt/widevine';
import { VERSION } from '@javagt/widevine';
import {
  WidevineError, TooManySessions, InvalidSession,
  InvalidInitData, InvalidLicenseType, InvalidLicenseMessage,
  InvalidContext, SignatureMismatch, NoKeysLoaded,
} from '@javagt/widevine';

API Reference

Device

| Method | Python equivalent | Status | |--------|-------------------|--------| | Device.load(path) | Device.load() | ✅ | | Device.loads(data) | Device.loads() | ✅ | | Device.dump(path) | Device.dump() | ✅ | | Device.dumps() | Device.dumps() | ✅ | | Device.migrate(data) | Device.migrate() | ✅ | | .type / .securityLevel / .systemId / .privateKey / .clientId | same | ✅ |

Cdm

| Method | Python equivalent | Status | |--------|-------------------|--------| | Cdm.fromDevice(device) | Cdm.from_device() | ✅ | | Cdm.open() | Cdm.open() | ✅ | | Cdm.close(sessionId) | Cdm.close() | ✅ | | Cdm.getLicenseChallenge(sessionId, pssh, ...) | Cdm.get_license_challenge() | ✅ | | Cdm.parseLicense(sessionId, licenseMessage) | Cdm.parse_license() | ✅ | | Cdm.getKeys(sessionId, type?) | Cdm.get_keys() | ✅ | | Cdm.setServiceCertificate(sessionId, cert) | Cdm.set_service_certificate() | ✅ | | Cdm.getServiceCertificate(sessionId) | Cdm.get_service_certificate() | ✅ | | Cdm.uuid / Cdm.urn / Cdm.keyFormat | class attributes | ✅ | | Cdm.MAX_NUM_OF_SESSIONS | class attribute | ✅ | | Cdm.serviceCertificateChallenge | class attribute | ✅ | | Static Cdm.encryptClientId() (private in TS) | Cdm.encrypt_client_id() | ⚠️ internal | | Cdm.decrypt() (shaka-packager) | Cdm.decrypt() | ❌ |

PSSH

| Method | Python equivalent | Status | |--------|-------------------|--------| | new PSSH(data) | PSSH(data) | ✅ | | .dump() / .dumps() | same | ✅ | | .initData / .keyIds / .systemId / .version | same | ✅ | | .contentId | (via WidevineCencHeader) | ✅ | | .isWidevine | (via SystemId check) | ✅ | | PSSH.new() factory | PSSH.new() classmethod | ❌ | | .setKeyIds() | PSSH.set_key_ids() | ❌ | | .toWidevine() / .toPlayready() | PSSH.to_widevine() / PSSH.to_playready() | ❌ |

Key

| Method | Python equivalent | Status | |--------|-------------------|--------| | Key.fromKeyContainer(kc, encKey) | Key.from_key_container() | ✅ | | Key.kidToUuid(kid) | Key.kid_to_uuid() | ✅ | | .type / .kid / .key / .permissions | same (kid is Buffer not UUID) | ✅ |

Module-level

| Export | Python equivalent | Status | |--------|-------------------|--------| | DeviceTypes enum | DeviceTypes | ✅ | | Session class | Session | ✅ | | VERSION constant | __version__ | ✅ (synced to v1.9.0) |

What's Missing vs pywidevine 1.9.0

| Feature | Reason | |---------|--------| | Cdm.decrypt() (shaka-packager) | Requires shaka-packager binary; not needed for key-only use | | PSSH.new() / .setKeyIds() / .toWidevine() / .toPlayready() | Not used in practice for key extraction | | RemoteCdm class | Network-based remote CDM; narrow use case | | CLI (pywidevine commands) | Python CLI; unneeded in JS ecosystem | | HTTP server (pywidevine serve) | Python aiohttp server; unneeded in JS ecosystem | | Typed exception classes (10 types) | All errors throw Error with descriptive message | | utils.get_binary_path() | Python-specific PATH utility |

Versioning

This library tracks pywidevine version numbers. Current release matches pywidevine v1.9.0.

License

MIT

Ported from pywidevine (MIT) by DeepSeek V4 Flash.