From SPECTRUM_START_S the nodes stop following the lyric and behave as a spectrum analyser: every sung node is given one log-spaced frequency band (40 Hz–12 kHz), dealt out in a seeded shuffle, and sizes up and down with that band's amplitude. - spectrum.ts: band maths and every tunable. Levels come from @remotion/media-utils visualizeAudio on audio loaded by useWindowedAudioData (10 s windows, so the 227 MB WAV is never decoded whole; before the outro the window stays parked at its start). Bands average the FFT bins they span, or interpolate for bands narrower than a bin, so neighbouring bass nodes never move in lockstep. Level = (raw × GAIN × (f/40 Hz)^TREBLE_TILT)^CURVE with a release that looks back RELEASE_FRAMES frames at RELEASE_DECAY per frame. Defaults were calibrated on the release2 outro (nodes pinned at full size 0.6% of the time). The node→band mapping uses Remotion's seeded random() (BAND_SEED), not Math.random(), so render tabs and the Studio agree. - nodeAnimation.ts: SPECTRUM_PEAK and spectrumLook(level), alongside lightUp and switchOff, plus a levelExponential shaping curve. - Transect.tsx: hands each node over from its lyric look to its spectrum look over SPECTRUM_FADE_S. - package.json: declare @remotion/media-utils 4.0.522 (already installed as a dependency of the CLI; now pinned alongside the other Remotion packages). Verified: eslint + tsc clean on this commit's tree; outro stills show nodes sized by band level, so the windowed audio loads during renders. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PLt25nCVMsoroKALYUBu6u
Video-related files for NCMR songs
This repo houses the code-like files for NCMR music videos. Binary assets live elsewhere.
Structure
Repo state: workspace under construction.
masteris not locked in yet — it is still being assembled as the shared template. Until it is locked, any branching strategy is fine and template/tooling work can land onmasterdirectly. The branch conventions below describe the intended end state, not a rule currently in force.
master branch — shared template
This branch holds the common scaffolding:
- Remotion project — entry point, root component, and a placeholder composition
scripts/— Python toolchain (stdlib only) for subtitles, ffmpeg and asset manifests- Build config — TypeScript, ESLint, Prettier, Remotion studio
src/ vs scripts/
Two directories, two jobs:
src/— Remotion input only. Everything here is compiled bytsc/Remotion and linted bynpm run lint.scripts/— operator tooling. Python, standard library only, run directly (python3 scripts/tools.py --help). Nothing here is part of the Remotion build.
Keep the boundary sharp: anything the video build compiles belongs in src/, and
anything you run by hand belongs in scripts/.
Song branches
For each song, create a branch <song-name>/master (and optionally feature branches
like <song-name>/synced-lyrics-remotion):
git checkout -b <song-name>/master
Copy the shared template into the song branch, then add song-specific files:
mkdir -p <song-name>
# Place your song-specific compositions, assets manifests, etc.
Once master is locked in it remains protected and mostly immutable. Until then,
song branches are a rehearsal for that end state, not a requirement.
Guideline
Git-ignored (not tracked here)
- Binary input assets (audio, images, fonts, material video clips)
- Video output (
out/, rendered files) package-lock.json— see below
For untracked input assets, a bill of materials listing everything and explaining
what each file is will be mandatory. Keep it as BOM.md alongside your song assets.
Why there is no package-lock.json
Deliberate, not an oversight. Work happens on both Windows and Linux, and two things make a lockfile a liability here rather than a safeguard:
- There is nothing for it to pin. Every dependency in
package.jsonis pinned to an exact version — no^, no~. A plainnpm installon any machine resolves to the same versions the lockfile would have recorded. - A lockfile is platform-specific. It records the resolved tree, including
the optional native binaries for whichever OS generated it (
@rollup/rollup-linux-x64-gnu,@rollup/rollup-win32-x64-msvc). Committed from Linux it is wrong on Windows, andnpm cirefuses outright rather than adapting, since its whole purpose is to reproduce the recorded tree exactly.
So it would be strict about the wrong thing: breaking installs across machines while guarding versions that were never floating. Revisit this if a dependency is ever loosened to a range, or picks up transitive drift that exact pinning cannot control — at that point the lockfile earns its friction.
Branching
master— minimal template (protected once locked in)<song>/master— song-specific work<song>/<feature>— parallel features for a song
Once master is locked, this repo's branching rules supersede any generic git
operation conventions. Before that point, use whatever is convenient.