Initial commit: Null DRM Official

Capture, decrypt, and restream toolkit with compiled-in app modules
(RTE, TG4, BBC), on-device MITM proxy, streamd control plane, and www.
BBC module.yaml is published (clear streams); other module values stay local.
This commit is contained in:
404errordeveloper 2026-10-06 00:25:35 +02:00
commit 2fa8f2435f
121 changed files with 17802 additions and 0 deletions

154
README.md Normal file
View file

@ -0,0 +1,154 @@
# DRM-Decryption
Capture Widevine live sessions from Android streaming apps and restream them.
Everything is one Go binary — `drm` — with every app module compiled in. Each
streaming app (RTE, TG4, …) is a Go package under `apps/modules/`; its secrets and
IDs live in a local, gitignored values file that you fill in yourself.
- **[docs/](docs/)** — architecture, module authoring, per-provider setup
- **[docs/quickstart.md](docs/quickstart.md)** — the longer version of what follows
---
## Quick start
### 1. Prerequisites
| Need | Why |
|---|---|
| **Go 1.25+** | builds everything |
| **Python 3.10+** | `apps/wvkey/wvkey.py` talks to the Widevine CDM |
| **adb** (platform-tools) on `PATH` | only for phone capture |
| A `.wvd` Widevine device file | only for fetching keys |
Phone capture additionally needs a rooted Android device (Magisk) so the MITM CA
can be injected into the system trust store. Catalog lookups need no phone.
### 2. Clone and build
```bash
git clone https://git.nulldrm.com/nulldrm/Null-DRM-Official.git
cd Null-DRM-Official
# Linux / macOS
go -C apps/cli build -o ../../bin/drm .
# Windows
go -C apps/cli build -o ../../bin/drm.exe .
```
Check it:
```bash
./bin/drm help
./bin/drm modules # which app modules this build contains
```
`drm modules` works immediately, but channel lists stay empty until you add
values — that is the next step.
### 3. Python CDM helper
```bash
python -m venv .venv
.venv/bin/pip install -r apps/wvkey/requirements.txt # Windows: .venv\Scripts\pip
```
Put your Widevine device file in `data/` (gitignored), e.g. `data/device.wvd`.
### 4. Fill in a module's values
Compiled-in module code carries **no** account IDs, policy keys, video IDs,
license URLs or key IDs. Those go in a gitignored file per module, which you create:
```text
apps/modules/tg4/module.yaml
apps/modules/rte/module.yaml
```
Where each value comes from:
- **[docs/providers/tg4.md](docs/providers/tg4.md)** — Brightcove account ID, policy key, video IDs
- **[docs/providers/rte.md](docs/providers/rte.md)** — license URL, origin hosts, channel KIDs
- **[docs/capture.md](docs/capture.md)** — how to discover all of it for a *new* app
Any value can be passed per-run instead of stored:
```bash
./bin/drm catalog --app tg4 --channel ioi --tg4.policy-key 'BCpkAD...'
TG4_POLICY_KEY='BCpkAD...' ./bin/drm catalog --app tg4 --channel ioi
```
### 5. Run something
```bash
# keys from a public catalog — no phone needed
./bin/drm catalog --app tg4 --channel ioi --keys --wvd data/device.wvd
# phone capture: launch the app, drive it to a channel, grab license + keys
./bin/drm proxy build # once: cross-compile the on-device MITM
./bin/drm capture --app rte --channel rteone --auto-play --wvd data/device.wvd
# control plane + dashboard on http://127.0.0.1:8083
./bin/drm serve --bind 127.0.0.1:8083 --data .cache/streamd --token SECRET
# always-on refresher: watches streamd, re-captures dead channels
STREAMD_TOKEN=SECRET ./bin/drm agent run --config apps/agent/agent.yaml
```
Results land in `outputs/<app>/<timestamp>/`, with `latest/` kept as a copy.
---
## Subcommands
| Command | What it does |
|---|---|
| `drm modules` | list compiled-in app modules, their channels and config source |
| `drm capture` | one-shot phone MITM capture → `outputs/<app>/<stamp>/` |
| `drm catalog` | resolve a channel from its public catalog, no phone |
| `drm serve` | streamd: REST API + dashboard + media supervisor |
| `drm agent` | `run` / `status` / `devices` / `enqueue` / `cancel` |
| `drm proxy` | `build` / `push` / `install-ca` / `start` / `stop` / `discover` / `pull` |
Run any of them with `--help`.
## Layout
```text
apps/cli/ the binary -> bin/drm
apps/modules/ app modules: Go (tracked) + module.yaml (gitignored)
apps/pkg/ shared, provider-neutral libraries
apps/capture/ phone capture command
apps/agent/ always-on key refresher
apps/streamd/ control plane: API, SQLite, dashboard, supervisor
apps/proxy/ MITM host CLI + on-device proxy source
apps/wvkey/ wvkey.py — CDM only
docs/ architecture, authoring, provider setup
data/ secrets: .wvd, CA (gitignored)
outputs/ capture sessions (gitignored)
bin/ built binaries (gitignored)
www/ static site
```
## Tests
```bash
go -C apps/pkg test ./...
go -C apps/modules test ./...
go -C apps/streamd test ./...
```
Tests that hit a live origin are behind a build tag, so they stay out of the
normal run:
```bash
go -C apps/modules test -tags live ./rte/ -v
```
## Scope
For use only on services you are authorised to access, with content you have the
right to decrypt. [docs/architecture.md](docs/architecture.md) describes what the
system does and where it stops.