Commit Graph

7 Commits

Author SHA1 Message Date
JSLMPR 9fb24e8f19 R6 speed-ramp: ease into slow-motion
A slow-motion shot now decelerates smoothly instead of snapping to slow-mo:
speedRampSetpts builds a log-integrated setpts that ramps playback speed from
normal (1.0) down to below the target across the shot. The shot stays a SINGLE
segment (so the R5 per-shot push-in is preserved) and the existing -t pin keeps
the planned output duration. Normal-speed shots keep a plain constant setpts.
Unit-tested; verified in a real render (payoff carries the ramp, output valid).
Completes R6 (crossfades + speed-ramp).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MPuJXQyAeWpFcTtcnxo1UN
2026-07-24 12:04:32 +02:00
JSLMPR a2a7d7d736 R8: swell the music into the payoff
MusicGen's internal structure is uncontrolled, so the mix applies a deterministic
swell envelope to the score (volume='min(1,0.5+0.5*t/peak)':eval=frame): the music
amplitude rises from 0.5x to full over the run-up to the payoff, then holds. The
peak is the payoff (slow-motion) beat's timeline midpoint on the crossfade-
compressed timeline -- generic, driven only by the plan, no content assumptions.
No-ops when there is no slow-mo beat. Filter string unit-tested; verified in a real
render (swell peaks at 6.83s, output -16.1 LUFS).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MPuJXQyAeWpFcTtcnxo1UN
2026-07-24 09:37:43 +02:00
JSLMPR 407f6b5e04 Tier-2 caption-driven shot selection (semantic editor, not just decorator)
The vision director now captions several beat frames (two questions per frame in
one worker call: a discriminative description + a punchy label) and turns the
descriptions into a per-window "highlight-worthiness" curve via generic
emotion/action/idle keyword scoring (semanticScore/semanticCurve). The montage
director blends that curve with audio to place the payoff on the semantically
strongest moment; the payoff label becomes the bold overlay and the description
flavors the music. Everything is content-agnostic and fails soft to the measured
cut. Verified on bowling: the payoff moved onto moondream's detected celebration.

Honest limit: a small VLM on distant subjects is only weakly discriminative;
descriptive questions beat terse ones (which collapse to a constant answer).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MPuJXQyAeWpFcTtcnxo1UN
2026-07-24 01:31:48 +02:00
JSLMPR 67bdf683ca R7: bold, animated overlay captions
Overlays are now large (fontsize 84) with a thick outline + strong drop shadow so
they read on any background, and animate in: a snappy 0.18s alpha punch plus a
34px rise-up over 0.22s, with a soft ease-out. Placed on the payoff beat so the
entrance lands on the musical/edit accent. This presents the Tier-2 vision
director semantic caption ("STRIKE") boldly. Overlay style/animation asserted in
the existing overlay test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MPuJXQyAeWpFcTtcnxo1UN
2026-07-24 00:05:39 +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 30c832e9d5 Accurate loudness mastering: measure the finished file and correct to target
Single-pass loudnorm in the mix is only ~+/-2 LUFS accurate, so the auto-rendered
output could land quiet (e.g. -18.7 LUFS vs the -16 target). After the mix,
probeIntegratedLoudness measures the file, loudnessGainDb computes the corrective
gain, and masterLoudness applies it with a brickwall limiter for true peak. No-ops
when already on target or when the measurement is implausible; handles MusicGen
loudness variance. loudnessGainDb unit-tested.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MPuJXQyAeWpFcTtcnxo1UN
2026-07-23 23:09:06 +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