---
name: ad-localizer
description: Localize a video ad into many languages in one batch. Dubs with the original speakers' voices (Kenerate dub_video), adds captions in each language (add_subtitles, or a translated SRT burned locally for free), checks length and audio per locale, and names the files ad_es.mp4, ad_fr.mp4 and so on, with a report and contact sheet. Use when the user wants to translate, dub or localize an ad or video into other languages or markets, or to run international or multi-language campaigns.
compatibility: Needs the Kenerate MCP server (dub_video, add_subtitles) and Python 3.9+ with Pillow and ffmpeg for collecting and checking.
metadata:
  author: kenerate
  version: "1.0"
  kenerate-tools: "dub_video add_subtitles estimate_cost wait_for_generation upload_media tool_guide"
---

# Ad localizer

Rules: [references/KENERATE.md](references/KENERATE.md) (models and voices: [references/MODELS.md](references/MODELS.md), or the free `pick_model` / `pick_voice` tools). `dub_video` is priced per second for each language, so batches
add up fast. Always estimate first.

## Ask the user
- The ad (Kenerate url, or a public link → `upload_media`). It must contain speech.
- Target languages (dub_video codes such as es, fr, de, pt, it, ja, ko, zh, hi, ar, id, tr, nl, pl; full list in
  `tool_guide("dub_video")`) and the source language if auto-detect might miss it.
- Captions: none, Kenerate animated captions (`add_subtitles`), or local burn from translated SRTs (free).
- Whether to drop background music from the dub (`drop_background_audio=true`).

## 1. Plan and price
```
python <skill-dir>/scripts/localize.py plan --source "<ad url>" --langs es,fr,de,ja --captions --name <project>
```
This prints the exact calls and output names. Then run `estimate_cost("dub_video", {"media_url": ad, "target_lang": "es"})`,
multiply by the number of languages, add `add_subtitles` (720p: 20 credits per started minute, double at 1080p), show
the total and get a yes.

## 2. Run (Kenerate)
For each language: `dub_video(media_url=ad, target_lang=<code>)` → `wait_for_generation("dubbing", id)`. Start all
languages first, then wait for each.
Captions (optional): `add_subtitles(video_url=<dubbed url>, style="simple" (or "rizz" for social), language=<en-US|es-ES|fr-FR|de-DE|ja-JP|zh-CN|it-IT|pt-BR|ru-RU when it is one of these, else leave empty to auto-detect>)` → kind `"subtitles"`.

## 3. Collect, check and name (local)
```
python <skill-dir>/scripts/localize.py collect --name <project> --source "<original ad url>" \
  --item es=<final es url> --item fr=<final fr url> --item de=<final de url> \
  [--srt de=<translated de.srt>] --out-dir kenerate-out/ad-localizer
```
- Flags any locale with no audio, or a length more than 8% off the source (`--tolerance`).
- `--srt LANG=file.srt` burns captions locally instead of add_subtitles. You can write the SRT yourself by translating
  the original script with the same timings.
- Writes `<project>_<lang>.mp4`, `<project>_locales.json/.csv` and `<project>_locales.jpg`.

## If something fails
A failed dub is refunded; the rest of the batch continues. Report which languages failed and ask before retrying.
`source_lang` must differ from `target_lang`. Files over 15 minutes are rejected; split them first with `video-editing`.

## Limits
dub_video up to 15 min per file; add_subtitles up to 4 min and speech only.
