Skip to content

feat(demo): lay the generated music bed under the demo video - #60

Merged
upgradedev merged 2 commits into
mainfrom
feat/generated-soundtrack
Aug 3, 2026
Merged

feat(demo): lay the generated music bed under the demo video#60
upgradedev merged 2 commits into
mainfrom
feat/generated-soundtrack

Conversation

@upgradedev

Copy link
Copy Markdown
Owner

The demo film had no music because an unlicensed track is a copyright problem we will not hand a judge. Generating it removes the question instead of dodging it: the bed is as clearly ours as the footage.

minimax-music-2.5 through the same Genblaze path every other asset uses, prompted from the occasion the reel in the video actually picks (anniversary: warm romantic strings, 96 bpm), which is exactly what Occasion.music_style has always documented itself as being for.

Two problems worth naming

No duration control. The bed came back 90.26s against a 169.74s film. demo/mix-music.py loops it by crossfading it into a second copy of itself with a constant-power (qsin) seam, then trims to the film and eases in and out. On a sustained strings pad the seam is not something you can point at.

Narration stays dominant. Both tracks are measured with EBU R128 integrated loudness and the bed is attenuated to sit exactly 20.1 LU under the voice, with amix normalize=0 so the mixer cannot quietly halve both inputs and undo the measurement. The script fails hard if the measured separation drifts more than 0.5 LU.

Integrated loudness is -25.9 LUFS before and after, so the voice is not one decibel quieter than the cut that was already approved.

The picture is untouched

The video stream is copied, not re-encoded, so every footage beat, caption window and cut survives byte for byte. 169.74s, under the 180s cap, ten beats and ten cues.

The gate

The mix is one AAC track, so exactly one audio stream still guards against a stray stream but can no longer tell narration-only from narration-plus-music. check_music adds two bounds, two-sided on purpose (a one-sided "not silent" check would pass a mix that drowns the voice):

  • Floor. Narration is built by padding each beat with digital silence, so a narration-only film leaves 44 windows of true dead air at or under -50 dBFS. With the bed under it that count is 1. A rebuild that skips the music step fails here.
  • Ceiling. The mixed film must still measure within 1.0 LU of the narration it was built from. A bed mixed anywhere near the voice drags that up and fails.

The bed is pinned by content hash and recorded in demo/cinemory-demo.beats.json with its provider, model and prompt like every other generated artifact.

Docs

The "no music, deliberately" claims in demo/SUBMISSION.md and demo/video-script.md become false on merge and are updated. demo/STATE.md gets a new top entry rather than a rewrite, per its own append-log contract. README.md had no false claim; one clause was added to the demo-video bullet. Badge row, YouTube URL and test-count floors untouched.

Owner action after merge: re-upload demo/cinemory-demo.mp4 to YouTube and repoint the Devpost video link.

Efthimios Fousekis added 2 commits August 3, 2026 23:14
The demo video has no music because an unlicensed track is a problem we
will not hand a judge. Generating it removes the licensing question
entirely: the bed is as clearly ours as the footage.

minimax-music-2.5 is reachable through the same Genblaze/GMI Cloud path
every other asset uses. It answers the SDK's empty-payload liveness probe
with 400 'lyrics (Required parameter is missing)' where a made-up slug
answers 404 'does not exist'.

The SDK's own gmi-audio-music surface does not allow 'lyrics', which the
model requires, so the slug gets an explicit ModelSpec through the
documented per-instance registry override - the same shape the seedance
FLF2V bridge already uses.

Direction comes from the occasion the reel in the video actually uses
(anniversary: warm romantic strings, 96 bpm), which is what
Occasion.music_style has always documented itself as being for.
The film had no music because an unlicensed track is a copyright problem we
will not hand a judge. Generating it removes the question instead of dodging
it: the bed is as clearly ours as the footage.

Two things had to be solved. minimax-music-2.5 gives no duration control, so
the bed came back 90.26s against a 169.74s film; mix-music.py loops it by
crossfading it into a second copy of itself with a constant-power (qsin) seam,
which on a sustained strings pad is not something you can point at. And the
narration stays dominant: both tracks are measured with EBU R128 and the bed is
attenuated to sit exactly 20.1 LU under the voice, with amix normalize=0 so the
mixer cannot quietly undo the measurement. Integrated loudness is -25.9 LUFS
before and after, so the voice is not one decibel quieter than the approved cut.

The picture is stream copied, never re-encoded, so every footage beat, caption
window and cut survives byte for byte.

check_video.py gains a music section. The mix is one AAC track, so "exactly one
audio stream" still guards a stray stream but can no longer tell narration-only
from narration-plus-music. Two new two-sided bounds do: a floor (narration-only
leaves 44 windows of true dead air between padded lines, the mix leaves 1, so a
rebuild that skips the music step fails) and a ceiling (the mixed film must
measure within 1.0 LU of the narration it was built from, so a bed mixed near
the voice fails). The bed is pinned by content hash and recorded in the beat
script with its provider, model and prompt like every other generated asset.
@upgradedev
upgradedev merged commit 95556b0 into main Aug 3, 2026
12 checks passed
@upgradedev
upgradedev deleted the feat/generated-soundtrack branch August 3, 2026 20:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant