Set voiceover scripts
voiceover_batchSet voiceover text and/or trigger speech generation for any number of clips in a single call.
Each entry chooses its own action:
"set_text" — set transcript for a clip (clip_index + text)
"generate_speech" — async TTS for a clip (returns immediately)
"set_and_generate" — set text and kick off TTS in one entry (+ text)
Address a clip the same way as everywhere else: clip_index. Pass clip_id instead if you already have it — it survives clips being inserted or reordered mid-build — but you never need both; whichever you omit is looked up once for the whole call.
Entries within one call are applied in order. Returns one result object per input entry. All text-set actions land in ONE save; the TTS for generate/set_and_generate runs async per clip after.
IMPORTANT — generating speech RESCALES the whole clip, it does not clamp it: when audio is generated (generate_speech / set_and_generate), the clip's duration is reset to the spoken audio length, and then EVERY element on that clip is retimed proportionally by (new duration ÷ old duration). start_time, end_time and every keyframe timestamp are multiplied by that factor. Nothing is merely truncated — on a 6s clip that becomes 1.02s, an animation you placed at [0, 1.6] ends up at [0, 0.27]. Zoom elements whose window falls under the minimum after scaling are DROPPED entirely. Generation is async, so this lands AFTER this call has already returned success. So: generate speech BEFORE placing time-sensitive elements, or size them against estimate_duration first — then re-read the clip and check what your elements actually became, not just the clip duration.
Concurrency: parallel-safe (conflict domain: a clip's voiceover). The server merges each clip's voiceover under a per-guide lock and preserves that clip's elements, so you can fan voiceover work out across subagents by clip — and it's safe to run alongside element edits. Two concurrent edits to the SAME clip's voiceover do not last-write-win — both claim that clip's voiceover path, so the later one is REJECTED and nothing is written; re-read and re-apply. Do NOT run concurrently with whole-clip/whole-project mutations on the same guide (update_clips on that clip, structural clip ops, add_audio, update_project).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| entries | Yes | Voiceover entries — at least one. | |
| project_id | Yes | Project ID |