# iPolloWork Video Voiceover and Captions Read only for requested new/revised speech or speech-linked captions. Existing narration, a saved voice setting or a soundtrack-only task does not request synthesis. Inputs are exact `voiceover.json`, affected storyboard frames, current scene anchors and actual saved audio/alignment. Share the [session boundaries](video.md); preserve unrelated scenes and sound. ## Speech authorization and transcript Use `ipollowork-video-voiceover` and injected voice contract only when authorized and enabled, or explicitly requested. Preserve saved `enabled: false`; use selected valid voice or the supplied default, never hardcode provider/model/voice, request chat keys or substitute a generic TTS tool. Without narration keep composing, preserve existing audio, use truthful `estimated-reading`/silent driver and disclose partial delivery when required speech is missing; do not invent spoken assets or a pending-model placeholder, redirect to Media Studio or block file work. Plan natural phrasing, pronunciation of names/abbreviations/numbers, emphasis and purposeful pauses in frame notes. Keep stage directions and pause markers out of voiceover spoken text. Use only supported delivery controls; do not invent pauseSeconds or SSML support or override pinned voices. A visual hold is not an inserted audio pause. Exact unsupported silence must be disclosed. Mark the complete visible scene transcript with `data-ipw-narration-source="true"`; combined marked text must exactly equal synthesis `text` and `sceneText`. Other factual titles/labels may remain without duplicating narration. Derive speech from actual scene anchors, with useful source-supported depth rather than generic filler. Keep title/takeaway, evidence labels and phrase captions distinct. Returned `wordTimings` and `wordTimingAlignment` are authoritative; save `captionElementsHtml` with its actual phrase boundaries when captions are required. After synthesis preserve `.timings.json` and replace estimates with actual returned duration/real provider word timings; without alignment use honest sentence-level captions, never character-proportional or evenly divided word timestamps. Recheck transcript and dependent beats/captions after edits; do not speed speech or omit facts to match samples. Pass `targetDurationSeconds` only for a user duration request. Reuse the storyboard estimate before synthesis; calculate once only if absent or spoken text changed, and validate requested duration against the complete final timeline rather than small batches. Per-frame explicit voice/model overrides batch defaults; auto resolves a compatible explicit voice from role/language/content, empty inherits project settings. Only use supported delivery controls explicitly saved/requested; default-path instruction stays empty. ## Measured recipe bindings For a narrated recipe pass its real `narration={timingSourcePath:"video//assets/.timings.json",text:"",bindings:{"":{phrase:"",occurrence:1}}}` to `video_component_install` instances. Use an actual provider-aligned timing file, bind every active event, and specify occurrence only to disambiguate repeated phrases; missing/ambiguous alignment needs correction or truthful disclosure, not guessed timestamps. Preserve returned literal `data-ipw-narration-binding` on the mounted host so delivery validates the same measured source/text/event map. `wordTimings` drive word emphasis/callouts/captions; no evenly split duration proxies. ## Synthesis and source patch Use `speech_synthesize_workspace_batch` in sequential batches of at most THREE scenes. Keep immutable per-scene output paths, returned `durationSeconds`, `timelinePatch`, `audioElementHtml` and timing data unchanged. Save each batch; carry `totalShiftSeconds` into later `sceneStart` values. After interruption retry the SAME paths so matching receipts reuse audio without another provider request. Keep existing narration until the full batch succeeds. In one entry edit insert returned `audioElementHtml` unchanged, including `data-ipw-voice*`, directly under the root. Use exactly one timeline-owned `audio[data-ipw-voiceover="true"]` per narrated scene; remove obsolete narration/manual playback/references only, preserve music/SFX. Returned items are already in visual order with cumulative shifts; never apply a shift twice or call per-scene synthesis. Keep spoken text visible through returned `timing.endSeconds`. Recovery never invents a revision, deletes successful files or requests paid media before repairing wrong-workspace/missing-project errors. Synthesis alone is not replacement success: patch actual source/audio/timing/captions before replying. Extend longer scenes and shift every dependent scene/transition/caption/audio/animation. Do not use raw TTS URLs, shell downloads, WAV-header arithmetic or invented timing attributes. Reuse approved storyboard rather than reconstructing it after assembly. ## Same-composition language variants For authorized alternate language, keep one editable composition/design system and language variables. Generate only changed speech through the existing voice contract. `media/video_language_timing_prepare` takes exact `sourcePath`, `source`/`variant` `{audioPath,timingSourcePath,text}`, complete `authorDurationSeconds`/`filmDurationSeconds`, semantic `bindings:[{source:{phrase,occurrence?},variant:{phrase,occurrence?}}]`, and authored `windows:[{id,start,end}]`. Both files must contain current provider-aligned complete transcripts of actual project audio. Pair meaningful phrases explicitly, never proportional character timing or inferred translation correspondence. Returned strictly increasing `anchors` map author ↔ film time. After construction, wrap the existing author GSAP timeline once with `rootTimelineScript`; each native child uses its window-local `timelineScript`, actual `compositionId` and matching host/child duration. Remap visual clips/events through anchors; variant audio/captions retain measured ordinary-speed times. Add new variant music volume automation to the registered film timeline after wrapping. Root duration alone cannot retime children. Register only the film timeline, replace a locale wrapper rather than nesting it, and retain author source. Validate original-language pixel identity, actual child actions, direct/reverse seeks and exported phrase sync. No global player warp, audio speed change or duplicate film. ## Captions Requested captions are timed visible `.clip[data-ipw-caption="true"]` covering speech; carry `requirements.captions: true` to the supplied gate. Default bottom-safe transparent overlays use `data-ipw-caption-style="transparent-bottom"` and inline `position:absolute;inset:auto 5% 5%;height:auto;display:flex;align-items:flex-end;justify-content:center;overflow:visible;background:transparent;pointer-events:none` so global `.clip {inset:0}` cannot stretch them. Put one/two readable lines in a stable leaf `data-ipw-caption-text="true"` with id/data-hf-id, inline max-width, transparent background, centered visible text and shadow/stroke. No pill/card/band/backdrop unless requested. Caption lifecycle is framework-owned; animate that real leaf using ordinary discovered text presets and `mutate_motion`, not a reduced caption-only implementation. Custom finite seek-safe GSAP is only for unsupported semantic effects. For captions-only work reuse actual saved transcript/audio alignment and the affected scene windows; do not resynthesize unchanged speech. A changed spoken script requires actual replacement speech and retiming. Check the mounted source with the existing project/voice tools and return actual files. The receipt is technical evidence; audible sync needs the host's current-version evidence under the applicable [acceptance](video-acceptance.md#media-narration-and-soundtrack) checks.