Dragonflight - self-hosted broadcast media asset management. SRT/RTMP/SDI ingest via Blackmagic DeckLink, FFmpeg proxy generation, growing-file editing via SMB + Premiere Pro CEP panel, BullMQ job queue, S3-compatible storage (RustFS). Replaces Grass Valley AMPP FramelightX.
Find a file
Zac Gaetano 3ffffd5b32 feat(schedule): right-click menu + drag-to-resize on EPG event blocks
Right-click any event block to open a context menu (Edit, Cancel,
Copy schedule ID, Delete) — actions per status mirror the List view so
the two surfaces stay in lockstep. Menu is viewport-clamped and
dismisses on outside click / scroll, same pattern as the asset menu in
the Library.

Drag-to-resize works for pending schedules only (the schedules PUT
rejects edits to running rows, and terminal statuses are read-only):
- Drag the left edge to move the start time
- Drag the right edge to move the end time
- Drag the body to shift the whole block in time
All gestures snap to 15-minute increments to match the new-schedule
click snap. Minimum duration is clamped to 5 minutes; the block clamps
to the visible day on both edges. While dragging the title shows the
preview range ("Start time → end time") and the block lifts with a
project-tinted shadow.

A short pointer click (< 4px travel) still opens the edit modal — the
click and drag share the same pointerdown so the operator never has
to know which gesture they made first.

Implementation: replaces the <button> block with a <div> hosting three
zones (left handle / body / right handle). Pointer events with
setPointerCapture so drags survive losing the cursor over the block,
and pointerup demotes back to click if travel was below threshold.
Optimistic local update on resize, PUT /schedules/:id with just the
two changed time fields, refetch to reconcile.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 16:33:57 -04:00
deploy test: deploy/api-smoke.sh — exercises every API surface 2026-05-23 04:24:10 +00:00
docs docs: design spec for YouTube importer 2026-05-23 16:04:28 -04:00
services feat(schedule): right-click menu + drag-to-resize on EPG event blocks 2026-05-23 16:33:57 -04:00
.env.example fix(infra+workers): S3 creds, ffprobe, BullMQ awaits, thumbnail seek, bin optional, docker-compose vars, jobs Redis, recorders stop codes: .env.example 2026-05-16 00:29:45 -04:00
.gitignore capture: custom FFmpeg 7.1 build with DeckLink + D-Bus mounts + SDI deinterlace 2026-05-22 00:01:43 +00:00
DESIGN.md feat(schedule): EPG stylesheet + impeccable context (PRODUCT/DESIGN.md) 2026-05-23 16:19:25 -04:00
docker-compose.gpu.yml feat: docker-compose.gpu.yml overlay — NVIDIA GPU pass-through + NVENC worker 2026-05-20 14:19:02 -04:00
docker-compose.worker.yml fix(decklink): mount /dev/blackmagic in sidecar + remote node routing via node-agent 2026-05-21 18:51:11 -04:00
docker-compose.yml feat: SDK deployment UI, proxy encoding global settings, S3 env fallback 2026-05-23 02:58:32 +00:00
PRODUCT.md feat(schedule): EPG stylesheet + impeccable context (PRODUCT/DESIGN.md) 2026-05-23 16:19:25 -04:00
README.md polish: schedule edit + README refresh 2026-05-23 04:26:03 +00:00
setup-repo.sh add setup-repo.sh 2026-04-07 21:58:16 -04:00

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-dragondragonflight (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
  • APIdeploy/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

# 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.