# Dragonflight

Self-hosted broadcast media-asset management. Replaces Grass Valley AMPP
FramelightX. SDI / SRT / RTMP ingest, growing-file editing via Premiere
Pro, S3-compatible storage, scheduling, and a queue-driven proxy pipeline.

> Repo renamed from `wild-dragon` → `dragonflight` (2026-05-23). The old
> URL still redirects.

## Features

- **Ingest** — SRT (caller + listener), RTMP, and SDI capture via
  Blackmagic DeckLink cards (FFmpeg patched against SDK 16.x); per-recorder
  codec settings (ProRes / H.264 / DNxHR / HEVC) and audio routing
- **Growing-file editing** — capture writes the hi-res master to a local
  SMB landing zone; editors can mount the share in Premiere Pro and edit
  the live file via the included CEP panel, then relink to the final S3
  master after promotion
- **Recorder scheduler** — one-shot, daily, or weekly windows; a 15s tick
  loop fires the existing /recorders/:id/start + /stop endpoints
- **Library** — projects, bins, asset detail with frame-anchored
  persistent comments, right-click context menu (move-to-bin, rename,
  delete), and a global cmd/ctrl-K search across assets / projects /
  recorders / jobs / users
- **Jobs** — BullMQ-backed proxy + thumbnail queue with per-job retry,
  bulk "retry all failed", and inline error messages
- **Settings** — S3 (with env-var fallback), global proxy encoder
  (CPU/libx264 or GPU/NVENC/VAAPI), growing-files config, capture SDK
  uploader (Blackmagic / AJA / Deltacast)
- **Cluster** — primary + worker topology with heartbeat health, remote
  node-agent for off-host DeckLink capture
- **API** — `deploy/api-smoke.sh` exercises every endpoint (27 routes,
  pass/fail summary)

## Services

| Service | Port | Description |
|---------|------|-------------|
| **web-ui** | 47434 | Browser SPA + capture controls |
| **mam-api** | 47432 | REST API + recorder orchestration + scheduler tick |
| **capture** | 47433 / 9000 / 1935 | DeckLink/SRT/RTMP capture sidecar |
| **worker** | — | BullMQ proxy + thumbnail workers |
| **db** | 5432 | PostgreSQL 16 |
| **queue** | 6379 | Redis 7 |

## Quick start

```bash
# Clone (repo renamed; old URL still redirects)
git clone https://forge.wilddragon.net/zgaetano/dragonflight.git
cd dragonflight

# Configure
cp .env.example .env
# Edit .env — S3 credentials + SESSION_SECRET at minimum

# Launch
docker compose up -d

# Open
open http://localhost:47434
```

## Architecture

```
SDI / SRT / RTMP ──► capture (FFmpeg)
                       ├─ HLS preview tee ──► /live/<assetId>/index.m3u8
                       └─ master output
                            ├─ growing_enabled=true:
                            │    /growing/<projectId>/<clip>.mov
                            │      (Premiere mounts SMB, edits live)
                            │      └─► promotion worker uploads to S3
                            │
                            └─ growing_enabled=false:
                                 multipart stream → S3

assets POST ──► proxy job ──► worker
                                ├─ libx264 (CPU) or NVENC/VAAPI (GPU)
                                ├─ thumbnail job
                                └─ status: ingesting → processing → ready
```

## Tech stack

- **Runtime:** Node.js 22, Docker Compose
- **Backend:** Express, PostgreSQL 16, Redis 7 + BullMQ
- **Frontend:** Vanilla React via in-browser Babel (no bundler), hls.js
- **Media:** FFmpeg 7.1 with SDK 16 DeckLink patches; ProRes, H.264, HEVC,
  DNxHR, MOV/MP4/MXF containers
- **Storage:** S3-compatible (RustFS) for masters + proxies + thumbnails

## Operations

- `deploy/api-smoke.sh` — verify every API endpoint after a deploy
- `deploy/onboard-node.sh` — provision a remote worker host (DeckLink
  cards on a separate machine)
- `deploy/test-cluster.sh` — primary↔worker connectivity smoke
- `docs/GROWING_FILES_QUICKSTART.md` — Premiere CEP panel install +
  growing-file capture flow

## License

Proprietary — Wild Dragon LLC, all rights reserved.
