# Music

Cut a video to a track: what rapid listen hears, the map agents plan from, the bed under the video, and the checks that hold it to the beat.

An agent can't hear a song, so rapid hears it first and writes down what matters. Bring a track and the video is planned to its beats, built to them, checked against them, and mixed over it. You must own the track or have the rights to use it.

```sh
rapid video --brief "Twenty seconds, vertical, cut to this." --music ~/Music/track.mp3
```

In Claude Code, name the track in the brief conversation, or pass `music` to [`new_video`](/docs/using-the-mcp-tools#newvideo). A track outside the project is copied into `assets/`.

The listener needs [`uv`](/docs/install#requirements), and sets itself up on first use.

## What the job does

1. **Hears it.** A `listen` node runs `rapid listen` before the storyboard. A track is heard once per machine: the result is kept by the file's hash, in `$RAPID_HOME/listen/heard/`, so the same song in another project answers at once.
2. **Plans to it.** The storyboarder reads the map and names the track in the storyboard's `music`, with `from`, where in it the video starts. Each scene's length is a whole number of beats.
3. **Checks the plan.** Code holds the start and every cut to a beat, within 0.07 s, and sends a plan that misses back, with or without a director.
4. **Builds to it.** A builder runs `rapid beats <scene>` for the music under its scene, in the scene's own seconds, and lands its moments there.
5. **Checks the landings.** `rapid check --music` marks a moment that misses, and the scene goes round again.
6. **Mixes the bed.** The track goes under the video, beneath the style's cue sounds.

## The map

`rapid listen <track>` writes `<track>.music.json` beside the track, and a picture of it, `<track>.music.png`, unless you pass `--no-picture`. Every time is in the track's own seconds.

| Field | Holds |
|---|---|
| `track` | the `file`, `sha256`, and `duration` |
| `heard_by` | the model that heard it, with its version |
| `tempo` | beats a minute |
| `beats`, `downbeats` | every beat, and the first beat of each bar |
| `sections` | `{ start, end, label, energy }`: `label` is `start`, `intro`, `verse`, `chorus`, `bridge`, `inst`, `solo`, `break`, `outro`, or `end`; `energy` is its loudness against the loudest section, 0 to 1 |
| `energy` | `{ step, values }`: loudness against the loudest step, one value per `step` seconds |
| `moments` | the places a video should land |

A moment is a `drop` or a `build`:

- **`drop`:** a section start where the energy jumps. `t` is when, `rise` how much, 0 to 1.
- **`build`:** the bars before a section over which the energy climbs into it, from `from` to `t`.

Both name the section they open or lead into by index, and a bigger `rise` is a bigger moment.

`rapid beats [scene]` prints the same music for a video's scenes, each in its own seconds, laid out the way the join lays them, overlaps included. It reads each scene's built length where it has one.

## Cutting to it

- **`music.from`** sits on a downbeat, chosen so the video's length holds the part of the song worth having: a bar or two before a drop, or the top of a chorus.
- **Cuts land on beats.** Each scene's `dur` is a whole number of beats, most of them whole bars.
- **Moves land on moments.** The rationed big moves go on drops, a held breath in a section whose `energy` falls, and cuts shorten into a build.
- **An overlap counts.** The plan check measures each cut where the next scene starts, the first frame of a [transition](/docs/transitions)'s overlap.

## In a scene

Land entrances, hits, and settles on beats, and the hero on a downbeat. A declared cue carries the moment, and `data-cue-duck` dips the track under it, for a word or a hit that has to read over the song:

```html
<i hidden data-cue="land" data-cue-at="1.92" data-cue-key="hero" data-cue-duck></i>
```

From a frame callback: `rapid.cue('land', { key: 'hero', duck: true })`.

## The beat check

With a track, `rapid check --music` runs the `beat` check on each render. It holds every cue of a landing kind (`land`, `hit`, `enter`, `drop`, `pop`, `kick`) and every ducked cue to the nearest beat:

| Off the beat by | Mark |
|---|---|
| 2 frames or fewer | none |
| more than 2 frames | minor: a note for the reviewer |
| more than 5 frames | major: fails the scene |

## The bed

The job's mix takes the track from `music.from`, brings it to −18 LUFS, and fades it out over the video's last 1.5 s. A video that outlasts the track loops it from the first downbeat at or after its start, crossfading the seam so the bar holds. Each ducked cue dips the bed to 40% with a soft attack and release.

By hand, `rapid mix` takes the same choices as `--music`, `--music-from`, `--music-lufs`, `--music-tail`, and `--map`, plus `--music-at` for where the bed enters. See [`rapid mix`](/docs/cli#rapid-mix).
