Commit Graph

4 Commits

Author SHA1 Message Date
JSLMPR 9e401870a1 feat(cinematic): R10–R14 grade/cadence/edit rules + 420p compat fix
Add five source-adaptive cinematic rules, all content-agnostic and
  fail-soft, derived from a web review of the film look and how consumer
  AI editors (DJI LightCut, Insta360) auto-edit:

  - R10: 24fps cinematic cadence (output frame rate 30 -> 24)
  - R11: filmic tone-curve grade (lifted toe + highlight roll-off);
         optional licensed film LUT via lut3d, gated on a .license.txt
         sidecar (fails closed, no unlicensed asset applied)
  - R12: shutter-angle motion blur (tmix), toggle
  - R13: beat-synced cuts — snap cut boundaries onto the score's beat
         grid (HighlightBeatSync + tools/beat_detect.py, librosa)
  - R14: subject-tracking reframe — follow the detected subject instead
         of a static crop (HighlightSubjectTracker + tools/subject_track.py,
         YOLO/AGPL, non-commercial); renderer subjectFollowFilter
  - Fix: pin -pix_fmt yuv420p on every encode pass (was yuv444p, which
         browsers/QuickTime reject)

  R13/R14 are opt-in flags, on in localpoc. mvn verify: 288 tests green.
  E2e bowling re-render verified: 24fps, yuv420p, -16.0 LUFS, 3 cut
  boundaries beat-snapped, all 5 shots subject-followed.
  Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 12:36:18 +02:00
JSLMPR f03d5472c5 R6: cross-dissolve transitions between montage beats
Beats now blend instead of hard-cutting (incl. the cut into the slow-mo payoff)
via an xfade + acrossfade chain (xfadeTimelineCommand). The timeline compresses
by (n-1)*xf, so shiftOverlayForCrossfade re-times overlays and the reported
duration is reduced to keep overlays, loudness mastering, and QA aligned. Opt-in
via editing.crossfade-seconds (0 = hard cuts default; localpoc 0.25), clamped to
half the shortest beat. Offset math + overlay shift unit-tested; verified on the
bowling cut (visible dissolve, STRIKE overlay stayed on the payoff).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MPuJXQyAeWpFcTtcnxo1UN
2026-07-23 23:41:12 +02:00
JSLMPR 1da0661eea Automatic two-tier highlight director + source-adaptive rendering
Rendering (whole service, driven by source measurements, not constants):
- Orientation-aware geometry: FfmpegClipInspector reads display rotation and
  stores effective dims; HighlightFfmpegRenderer.outputGeometry renders portrait
  sources portrait and skips the 2.39 letterbox on portrait (landscape unchanged).
- Dynamic exposure: probeSourceLuma measures the frames; exposureNormalizationFilter
  maps the mean toward a target; the grade is now exposure-preserving (no crushed
  subjects: bowling final went ~63 -> ~100 mean luma).
- Motion-adaptive in-shot push-in (zoompan), amount from per-shot YDIF.
- Audio mix ducks source audio under the generated score so it leads.
- Highlight duration is no longer capped (validator + config).

Automatic director (plans were hand-authored before):
- Tier 1 HighlightMontageDirector: composes the montage from measured motion (YDIF)
  and audio-energy (RMS) curves -- setup, continuous action/tension, slow-mo payoff
  on the audio climax, resolution button, camera-whip tail trimmed.
- Tier 2 HighlightVisionDirector + tools/vision_caption.py: a local, offline
  vision-language model (moondream2) captions the payoff frame and augments the
  montage with a semantic overlay ("STRIKE") and scene-informed music; fails soft.
- Wired into the scheduler behind auto-director-enabled / vision-director-enabled
  (on in the localpoc profile).

Docs: cinematic-quality-rules.md (R1-R5, R9 both tiers), poc-plan milestones.
Tests: mvn -o verify -> 262 passing, 0 failures.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MPuJXQyAeWpFcTtcnxo1UN
2026-07-23 22:49:05 +02:00
JSLMPR 588c652a2f Add opt-in localpoc profile for the local highlight PoC
Activated with --spring.profiles.active=localpoc. Points only at pre-provisioned
local model paths (Piper voice, MusicGen, AudioLDM2), disables bootstrap
auto-start, uses heuristic visual analysis, isolates PoC input/output dirs, and
keeps render disabled + director approval required. Base/production defaults are
untouched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bg76sLc43Wc3j5ZcLkboYR
2026-07-22 09:38:47 +02:00