Go to file
JSLMPR 8c0ddc1796 perf(vision): add resident llama-server backend (model loads once)
The CLI backend reloads the ~3GB model per frame (~2min/frame). Add a SERVER mode:
when LLAMACPP_SERVER_BIN is set, start llama-server once, POST base64 frames to its
OpenAI /v1/chat/completions endpoint on loopback, stop it at the end. Same answers,
~3x faster on a full clip (measured: 3 frames 181s incl. one-time load vs ~6-8min).
CLI mode (LLAMACPP_MTMD_BIN) remains the simple fallback.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-26 17:49:36 +02:00
.claude feat(cinematic): R10–R14 grade/cadence/edit rules + 420p compat fix 2026-07-25 12:36:18 +02:00
.github/workflows Add Maven Wrapper (pin Maven 3.9.9); CI uses ./mvnw 2026-07-24 15:41:17 +02:00
.idea I added an importable Grafana dashboard at dashboards/video-clipping-overview-grafana.json:1 and the companion setup note in docs/dashboards.md:1. The dashboard covers queue backlog and age, DLQ and processing counts, API 2026-07-10 00:14:13 +02:00
.mvn/wrapper Add Maven Wrapper (pin Maven 3.9.9); CI uses ./mvnw 2026-07-24 15:41:17 +02:00
Ultralytics feat(cinematic): R10–R14 grade/cadence/edit rules + 420p compat fix 2026-07-25 12:36:18 +02:00
dashboards I added an importable Grafana dashboard at dashboards/video-clipping-overview-grafana.json:1 and the companion setup note in docs/dashboards.md:1. The dashboard covers queue backlog and age, DLQ and processing counts, API 2026-07-10 00:14:13 +02:00
docs fix(vision): Qwen2.5-VL llama.cpp backend — verified to break the moondream ceiling 2026-07-25 23:50:12 +02:00
input/source • Added missing tests and a 100% coverage gate for the new folder scheduler package. 2026-07-10 01:02:08 +02:00
output - Implement end-to-end cinematic highlight rendering pipeline 2026-07-12 01:20:18 +02:00
src fix(vision): overlay describes the chosen peak, not the trailing outcome 2026-07-26 16:49:22 +02:00
tools perf(vision): add resident llama-server backend (model loads once) 2026-07-26 17:49:36 +02:00
.dockerignore Add Dockerfile + .dockerignore (app image; models mounted at runtime) 2026-07-24 15:13:29 +02:00
.gitignore Fix local CV visual-analysis client (HTTP/1.1) to enable YOLO selection 2026-07-22 11:14:48 +02:00
AGENTS.md feat(cinematic): R10–R14 grade/cadence/edit rules + 420p compat fix 2026-07-25 12:36:18 +02:00
Dockerfile Add Dockerfile + .dockerignore (app image; models mounted at runtime) 2026-07-24 15:13:29 +02:00
README.md feat(cinematic): R10–R14 grade/cadence/edit rules + 420p compat fix 2026-07-25 12:36:18 +02:00
mvnw Add Maven Wrapper (pin Maven 3.9.9); CI uses ./mvnw 2026-07-24 15:41:17 +02:00
mvnw.cmd Add Maven Wrapper (pin Maven 3.9.9); CI uses ./mvnw 2026-07-24 15:41:17 +02:00
pom.xml Configure folder scheduler in YAML 2026-07-10 12:24:16 +02:00

README.md

Video Editing Service — local cinematic highlight generator

Turn a single source video into a cinematic highlight entirely with local, offline models: it selects the moment, cuts a story-structured montage, generates the music/SFX/voiceover, applies a cinematic grade, and masters the audio — no external AI services, no runtime downloads.

Status: a working, source-adaptive proof of concept. The cinematic quality ruleset (R1R9, below) is complete and content-agnostic. It is not yet production-hardened (no auth on the render endpoint, no containers/PostgreSQL/no-egress certification, and the local models are non-commercially licensed — see Limitations). Do not deploy as-is.

What it does

For one source clip the single-source highlight pipeline runs, fully offline:

ingest ─► analyze (ffprobe, scenes, audio, frames)
       ─► candidates + category
       ─► DIRECTOR (auto):
            Tier 1  measure motion (YDIF) + audio (RMS) ─► story-structured shot list
            Tier 2  local VLM (moondream2) captions beats ─► semantic payoff selection + overlay + music mood
       ─► generate assets (Piper voice · MusicGen music · AudioLDM2 SFX)
       ─► render (portrait/landscape-aware, exposure-normalized, push-in, crossfades, slow-mo ramp,
                  bold overlay, ducked source under a swelling score)
       ─► master loudness ─► QA probes ─► final.mp4

Rendering is gated: it stays off by default and requires an explicit approval flag per project.

Cinematic quality rules (R1R9)

Every rule is source-adaptive — it measures the source and adapts, rather than hard-coding constants. Full detail in docs/cinematic-quality-rules.md.

# Rule Measure → adapt
R1 Exposure frame luma → normalize; grade never crushes the subject
R2 Orientation source rotation → portrait/landscape output, no distortion
R3 Audio balance + loudness score leads, source ducked; measured loudness corrected to 16 LUFS
R4 Duration any length, story-driven
R5 Motion push-in per-shot motion (YDIF) → adaptive in-shot zoompan
R6 Transitions cross-dissolves between beats + ease into slow-motion
R7 Overlays bold, outlined, animated entrance
R8 Music dynamics volume swell builds into the payoff
R9 Show the action Tier-1 measured + Tier-2 VLM caption-driven selection
R10 Cinematic cadence 24 fps film-standard output (was 30)
R11 Filmic grade filmic tone S-curve (lifted toe + highlight roll-off) + optional licensed lut3d
R12 Motion blur shutter-angle frame blend on styled shots (toggle)
R13 Beat-synced cuts snap cut boundaries onto the score's beat grid (librosa; toggle)
R14 Subject-tracking reframe follow the detected subject vs. static crop (YOLO/AGPL; toggle)

Build & test

Requires JDK 21 and ffmpeg/ffprobe on the PATH.

mvn -B verify          # compile, run all tests, JaCoCo gate

CI (.github/workflows/ci.yml) runs this on every push.

Run the highlight pipeline (local PoC)

The localpoc Spring profile wires the pipeline to pre-provisioned local model paths, isolates its input/output trees, keeps rendering disabled + approval-required, and never starts a network-capable bootstrap. The end-to-end command sequence (stage source → analyze → auto-direct → approve → render) is in docs/RUNBOOK-highlight-e2e.md. Outputs land under output/localpoc/highlight-projects/<project>/final.mp4.

Local models used (provisioning + version traps in docs/LOCAL-MODELS.md; each needs a provenance sidecar under models/):

Model Role License
Piper (en_US-lessac-medium) voiceover MIT / Blizzard dataset
MusicGen small music CC-BY-NC
AudioLDM2 SFX CC-BY-NC-SA
moondream2 Tier-2 vision director Apache-2.0
YOLOv8n (optional CV) visual analysis AGPL-3.0

Non-negotiable constraints

  • No automatic dependency/model downloads at runtime; models load offline from models/ + the local cache.
  • No external AI services in the media path.
  • No unlicensed assets; no placeholder silence/tones passed off as generated audio (the pipeline fails closed).
  • No rendering without an explicit approval flag.

Limitations

  • Licensing: MusicGen (CC-BY-NC), AudioLDM2 (CC-BY-NC-SA) and YOLOv8 (AGPL) are non-commercial/copyleft. Commercial use requires swapping in commercially-licensed models/assets.
  • Not production-hardened: no Spring Security/authN, no container/K8s/deployment manifests, REST persistence defaults to in-memory, and no-egress operation is not yet certified. POST /v1/edit-projects/{projectId}:render now requires an approved.flag in the project directory, but that is a basic presence gate — not yet an authenticated, digest-bound authorization.
  • VLM quality: on distant/small subjects the small local VLM is only weakly discriminative; a stronger model or closer framing improves Tier-2 selection.
  • A director can only cut what was filmed — it cannot show a moment the camera never captured.

Repository map

  • src/main/java/org/example/videoclips/editing/ — highlight analysis, two-tier director, renderer, QA.
  • tools/ — local model workers (local_asset_worker.py, vision_caption.py).
  • src/main/resources/application-localpoc.yml — the opt-in PoC profile.
  • docs/ — the PoC plan, the cinematic quality rules, acceptance review.