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:
commit
2fa8f2435f
121 changed files with 17802 additions and 0 deletions
154
README.md
Normal file
154
README.md
Normal 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.
|
||||
Loading…
Add table
Add a link
Reference in a new issue