Skip to content20cuts
Menu

Keep the picture and voice together.

VO-sync measures your recordings and places them on the scene timeline. Longer takes extend their scene and move the following scenes with them.

Build the picture first.

  1. Finish the visual beats. Write narration that describes the action on screen.
  2. Record each narrated scene. Save the files under public/vo/ and match each take to its scene ID.
  3. Measure, compile, and review. Use the same timing map for the audio and visual events.

Use one frame map.

src/ProductVideo.tsx
Source
import timing from "./timing.json";
import { filmSpec } from "./film";
import {
  withVoiceTimeline, compileFilm, compositionMetadata, Film,
} from "./system/production";

const film = compileFilm(withVoiceTimeline(filmSpec, timing));
export const filmMetadata = compositionMetadata(film);

export function ProductFilm() {
  return <Film film={film} />;
}

Measure the recordings first. Import that timing file into your film and use the compiled film’s duration in its Remotion composition.

Measure a recording

Write the result of voicePlanOf(spec) to scenes.json. Add recordings in takes.json, then run this command from the video folder. Measurement requires FFmpeg’s ffprobe.

Terminal
node scripts/vo-sync.mjs scenes.json takes.json src/timing.json --measure
Land an action on a spoken word

Measure the word’s position in its recording. Use voiceCueOffset(timing, sceneId, cueId) for the event’s at value, then compile with that same timeline.

VO-sync does not generate speech or infer word timing. Watch the full video to check whether the action lands with the intended word.