language-swap

Use when the user asks for language swap or a task matching the examples below. Translate and dub a video into another language. One worker call preserves each speaker's voice, translates the speech, and returns a fully A/V-synced video. Lipsync ON by default. Use when the user says "translate this

By pika-labs · 1,145 installs

npx skills add pika-labs/pika-plugins --skill language-swap

Source repository · Upstream listing

/pika:language swap Tools below are Pika MCP tools, named bare — call each under whatever prefix your session exposes for the Pika MCP. Translate and dub a video into another language while preserving the original speaker's voice. Pipeline: dub (one worker call) → lipsync (default ON) → burn target language captions or bilingual captions. The dubbing worker does the heavy lifting in a single call: it transcribes, translates, preserves each speaker's voice server side (no separate clone step), and returns a fully A/V synced video — so there is no manual transcribe/clone/TTS/replace chain to manage and no duration drift handling to do by hand. Segmented / multi language dub (per range languages) Use this when the user wants different languages on different parts of one video (e.g. first half Spanish, second half Japanese), or wants to translate only some sections and keep the rest in the original voice. Both are the same thing: a timeline of segments, each tagged with a language; any uncovered range keeps the original audio. dub video takes a segments plan instead of target language (pass exactly one — they are mutually exclusive): How to build the plan: the user needs to know where the content is before they can pick ranges, so transcribe first — extract the audio with extract audio from video , then transcribe audio(audio=<audio url , timestamps=true) , show the user the timestamped segments, and let them say which time range goes to which language. Then assemble segments[] (seconds, ordered, non overlapping) and make ONE dub video call. There is no separate "video understanding" tool — the timestamped transcript is the understanding step. Behavior of the segmented path: Shared voice across all segments. The source speaker is cloned once and every segment — in every language — is spoken in that same cloned voice, then the clone is recycled, all inside the one dub video call. You never clone or delete a voice yourself. Keep original. Any time range NOT covered by a segment plays the original audio (voice + background) untouched. To translate only parts of a video, list only the parts you want translated. Length locked. Output stays exactly the source length (each dubbed range is speed fit to its window), so boundaries line up with the original timeline. Provider. Mixed language per range always uses the voice cloning route automatically; the single call whole video dubbing route can't mix languages per range, so don't force a single call provider for a segmented plan. Every covered language must be supported on the voice cloning route — if one isn't, surface the error and consult references/language coverage.md . Result. Same dubbed video result; target language echoes the covered languages comma joined (e.g. "spa,jpn" ), and no single transcript language is returned (the track is multi language). Lipsync (Step 2, default ON, ≤5 min) still runs on the whole dubbed video. For captions (Step 3), use the returned multi language subtitles[] in caption mode="manual" ; auto re transcription can't pick a single language for a mixed track. If dub video rejects segments (older deployment without segmented support), fall back to dubbing each range single language and concatenating — but prefer the one call segmented path when available. Behavior defaults Target language : required via to <language . Prefer language codes: es , fr , ja , de , pt BR , zh Hans . The dubbing worker accepts ISO/BCP 47 like tags and normalizes script/region subtags before calling ElevenLabs (for example zh Hans → zh ; zh Hant TW → zh ). Lipsync : ON by default — re matches the speaker's mouth to the translated audio (fal sync lipsync; the full video lip matcher, distinct from the portrait image animator). Pass no lipsync to skip it when the source has no on camera face or to avoid the meaningful cost (~$4/min on the sync 2 pro tier). Applies only to videos ≤5 min — edit lipsync hard caps at 300 s upstream, so longer sources auto skip lipsync (see Step 2); the dub itself has no length limit. BGM / background music : kept by default — the dub lays the translated voice over the original music / SFX bed. Pass no bgm for a translate only output: the worker drops the original music and keeps only the translated speech ( drop background audio=true ). Captions : target language captions are burned by default. When the user asks for bilingual / dual subtitles, burn the target language (translated) row on top and the source language (original) row below it — after dubbing, the translated speech is what's actually being said, so it's the primary row; the original is the secondary reference. Bilingual captions : enable when the user passes bilingual subtitles or asks for "bilingual subtitles", "dual subtitles", "two language captions", "original + translated subtitles", "双语字幕", or "原文+译文字幕". Language coverage : if language support is questioned or a language related upstream error occurs, consult references/language coverage.md . Do not proactively surface provider specific language list details in normal user replies. State variables produced and consumed video url : input — from positional arg source input url : original positional URL — preserved for diagnostics if video url is rehosted target language : text — from to <language with lipsync : boolean — defaults true; false only when no lipsync no bgm : boolean — true when no bgm (maps to drop background audio=true ) bilingual subtitles : boolean — true when the user asks for bilingual / dual subtitles dubbed video url : dubbed, A/V synced video — produced by Step 1 dub subtitles : optional target language timed subtitles from the dub result — consumed by Step 3 source subtitles : optional source language timed subtitles from the dub result — consumed by Step 3 for bilingual captions dub transcript srt : optional target language SRT from the dub result — returned for review/debugging source transcript srt : optional source language SRT from the dub result — returned for review/debugging source transcript language : optional source language code from the dub result lipsynced video url : dubbed video with mouth re matched — produced by Step 2 (when lipsync runs) caption target video url : final visual video URL before captions are burned final video url : video with target language captions burned in — produced by Step 3 Step 0 — Parse input Required: Positional video url — MUST be https://... to <language — target language (free text or BCP 47 code) Optional: no lipsync — skip the default mouth matching step. no bgm — translate only output; drop the original music/SFX bed. bilingual subtitles — burn source language + target language subtitle rows. Infer bilingual subtitles=true from user wording even if the explicit flag is absent. If to is missing, STOP and prompt the user — UNLESS the user wants different languages on different parts, or to translate only some sections: that is the per range segmented path (see "Segmented / multi language dub" above), which uses a segments plan instead of to . For the segmented path, first build the time range plan: extract the audio with extract audio from video , then transcribe it with timestamps via transcribe audio(audio=<audio url , timestamps=true) , show the user the timestamped segments, and capture which time range maps to which language into segments[] . Outputs: video url , target language , with lipsync (default true), no bgm (default false), bilingual subtitles (default false). Step 1 — Dub the video (state: dubbed video url ) Call dub video with: source video url — <video url target language — <target language (ISO/BCP 47 like tag, e.g. es , pt BR , zh Hans ) source language — "auto" drop background audio — true only when no bgm is set; otherwise omit (keeps the original music bed) dub video is a plugin only Pika MCP tool: the claude.ai connector surface can lag the plugin build, so a connector session may not expose it at all. If it is absent from your tool list, say so rather than substituting another tool. dub video is worker backed: if the response comes back as {task id, status} , poll task status until completed , then read the dubbed video from the result ( video url for a video source; audio url for an audio source). Also capture optional subtitles[] , transcript srt , and transcript language — these are target language transcript metadata the dub worker produced, consumed in Step 3. For bilingual captions, also capture optional source subtitles[] , source transcript srt , and source transcript language . These source language transcript fields are best effort. The dubbed media is still valid when transcript fields are absent. Source not worker fetchable: if dub video fails because the source URL cannot be fetched — especially HTTP 403 / 4xx , hotlink protection, UA gated hosts (Wikimedia/news CDNs), or "Access Denied" errors — do not keep retrying the same call. Rehost first: 1. Download the source bytes in the client/host environment using a normal browser/download path or an HTTP client with a real user agent. 2. Call upload asset with the downloaded filename, MIME type, and exact byte size, then upload the bytes to the returned presigned URL. 3. Set source input url = <original URL and replace video url with the returned Pika CDN public url . Do not construct CDN URLs manually. 4. Retry Step 1 once against the Pika CDN URL. All later steps must use the updated video url . If the client/host also cannot download the source bytes, stop and tell the user the host blocks direct fetch; ask them to upload the file or provide a different URL. Outputs: dubbed video url , dub subtitles , source subtitles , dub transcript srt , source transcript srt , source transcript language . Step 2 — Lipsync (state: lipsynced video url ) Default ON. Skip entirely when no lipsync is passed (then Step 3 captions dubbed video url directly). Hard 5 minute cap — check duration before calling. edit lipsync enforces a 300 second (5 minute) audio limit upstream (sync.so) and rejects anything longer with invalid input before billing; every variant tier shares the same cap, so falling back through tiers does NOT help. If the dubbed video's duration seconds (returned by Step 1) is 300 , skip lipsync entirely, go straight to Step 3 captioning dubbed video url , and tell the user lipsync isn't available past 5 minutes (the dub itself works at any length). Only run the lipsync call below when duration seconds ≤ 300 . Cost heads up first. Lipsync is the dominant cost (~$4/min on the v2 pro tier). Before calling it, estimate from the dubbed video's duration seconds (returned by Step 1) using cost usd = duration seconds / 60 4 . Do not round short clips up to a full minute: a 7s clip is about $0.47 , not about $4 . Send the user a one line heads up with the actual duration and prorated estimate, e.g. "Lipsync on — ~7s video, est. ~$0.47 at $4/min (pass no lipsync to skip). Starting now." If duration seconds is missing and no reliable media duration is available, state the $4/min rate without inventing a dollar estimate. Then proceed straight into the call; this is a heads up, not an approval gate. Call edit lipsync(video url=<dubbed video url ) with no audio url — the worker syncs to the dubbed video's own embedded translated audio. Do not extract the audio just to feed it back in. ( variant defaults to v2 pro , with sync 3 / v2 as fallbacks.) Outputs: lipsynced video url (read from url of response). When this step runs, Step 3 captions this video, not dubbed video url — otherwise the lip matching is dropped. Step 3 — Burn target language captions (state: final