auto-dubbing について
指定した1つ以上の言語に動画を翻訳・吹き替えし、言語ごとにMP4を生成するSoniloのスキルです。翻訳済み字幕を台詞として使えるほか、タイミングを調整した字幕も出力できます。
主な機能
- 01指定言語の吹き替え動画を生成
- 02指定字幕を台詞として使用
- 03BGMのダッキングとリップシンクに対応
- 04タイミング調整済みSRTを出力可能
活用シーン
- 01製品紹介動画の多言語版を作成
- 02承認済み翻訳スクリプトで吹き替え
- 03ナレーションや画面録画の音声を差し替え
MCP 対応
SoniloのMCPツール `dubbing` は、動画、対象言語、任意の字幕などを受け取り、言語ごとの吹き替え動画を生成します。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ sonilo-ai/ skills --skill auto-dubbingインストール後、Claude Code で/auto-dubbingを入力して読み込まれたか確認します。
詳細
Sonilo Dubbing
動画を 1 つ以上の別の言語に吹き替えます。音声を翻訳して再収録し、対象言語ごとに新しい .mp4 を生成します(音声トラックや字幕だけではありません)。ユーザーがすでに承認済みの翻訳を用意している場合は、それらを subtitles として渡すと、原文を翻訳する代わりに、その文を読み上げます。
セットアップ: setup-api-key スキルを参照してください。
⚠️ 料金 — 呼び出す前にお読みください: 料金は言語ごとに発生します。無料で実行できるのは15 秒のプレビューのみです。セルフサービスアカウントで最初に 1 言語を指定し、
subtitlesを指定せずに呼び出すと、動画の最初の 15 秒だけが無料で翻訳され、動画全体の料金が記載されたtrial_previewが結果に含まれます。それ以降の呼び出しと、複数の言語またはスクリプトを指定した呼び出しはすべて有料です。4 言語をリクエストすると、1 言語の場合の 4 倍の料金がかかります。呼び出す前に、正確な言語リストをユーザーに確認してください。「親切心から」長いリストを推測してはいけません。
⏱ この呼び出しには時間がかかります。
TIME_OUT_SECONDSがそれより短くても、内部で少なくとも 2 時間ポーリングします。これは吹き替えパイプラインにおけるバックエンド独自の上限です。1 時間以上処理が続くのは正常で、停止しているわけではありません。キャンセルしないでください。いずれにしてもジョブは実行され続け、課金も発生します。キャンセルすると、結果を簡単に取得する手段が失われます。代わりにget_sfx_taskを使うか、ホスト型サーバーではget_generation_taskを使ってジョブを復旧してください。
トランスポート:MCP または CLI
セッション開始時にどちらかを選び、その後も同じものを使ってください。1 つのジョブ内で両方を混在させてはいけません。また、選択した方法を伝える必要はありません。
- このセッションで Sonilo MCP ツール(
dubbingなど)が使える場合 — それらを使用してください。シェルが不要で、非常に長い生成処理にも対応できる唯一の方法であるため、こちらを推奨します。入力内容ではなく認証に失敗した場合、このセッションではこのトランスポートを使用できません。再試行せず、2 に進んでください。 - 使用可能な Sonilo MCP ツールがないが、
sonilo accountが終了コード 0 を返す場合 — 以下の CLI コマンドを使用してください。同じ API、同じアカウント、同じ認証情報ファイルを使います。確認にはsonilo whoamiではなくsonilo accountを使用してください。whoami はサインアウト中でも終了コード 0 を返すため、2 つの状態を区別できません。 - どちらも使えない場合 — 停止し、setup-api-key スキルを実行してください。回避策として
curlでapi.sonilo.comを呼び出してはいけません。どちらのトランスポートも、単純なリクエストでは対応できないアップロード、ポーリング、再試行を処理します。
⏱ CLI を使う場合、この呼び出しを 1 つのコマンドで完了することはできません。 バックエンドは最大 2 時間ポーリングしますが、ホストのシェルツールの上限はそれより大幅に短く(Claude Code では 10 分)、
sonilo dubbingをフォアグラウンドで実行すると、ジョブは実行中で料金もすでに発生している状態のまま、コマンドが強制終了されます。代わりに、送信とポーリングを分けてください。
# --timeout はジョブの待機時間ではなく、CLI 自身の待機時間です。 # ホストのシェルにプロセスを強制終了される前に終了します。ID は「Submitted task ...」行に表示されます。 sonilo dubbing --video-url https://example.com/clip.mp4 --languages es,fr --timeout 300 sonilo tasks wait <task-id> # 完了するまで繰り返しますMCP を使う方法にはこの制限がないため、吹き替えにはこちらが適しています。
クイックスタート
MCP ツールの呼び出し(推奨)
dubbing(
video_path="~/Desktop/product-demo.mp4",
languages=["es", "fr"]
)
ユーザーが用意したスクリプトを使用し、言語ごとにタイミングを調整した .srt を返す場合:
dubbing(
video_path="~/Desktop/product-demo.mp4",
languages=["es", "fr"],
subtitles={"es": "~/Desktop/demo.es.srt", "fr": "~/Desktop/demo.fr.srt"},
export_srt=True
)
ホスト型サーバーでは、すべての字幕値に
https://URL を指定する必要があります。このサーバーにはファイルパスを読み込むためのファイルシステムがなく、video_urlも唯一の入力元です。ローカルの動画または.srt/.vttファイルには、ホスト型サーバーのcreate_upload_urlツールを使って URL を取得してください(手順は 事前確認 のステップ 4 を参照)。ローカルのsonilo-mcpサーバーでは、ローカルの.srt/.vttパスか、https URL のどちらも使用できます。
Python(pip install sonilo)
from sonilo import Sonilo
with Sonilo() as client: # reads SONILO_API_KEY
result = client.dubbing.generate(
video="product-demo.mp4",
languages=["es", "fr"],
# Optional: the lines to speak in each target language. A value is
# either a local .srt/.vtt path or an https URL.
subtitles={"es": "demo.es.srt", "fr": "demo.fr.srt"},
export_srt=True,
timeout=7200, # seconds — matches the backend's own ~2h ceiling
)
for language, path in result.save_all("./dubbed").items():
print(language, path)
# Only present with export_srt. Iterate this map, not the videos: a
# language whose export was blocked still has its .mp4.
for language, path in result.save_all_subtitles("./dubbed").items():
print(language, path)
JavaScript / TypeScript(npm install sonilo)
import { SoniloClient } from "sonilo";
import type { DubbingResult } from "sonilo";
const client = new SoniloClient(); // reads SONILO_API_KEY
const result = await client.dubbing.generate(
{
video: "./product-demo.mp4",
languages: ["es", "fr"],
// Optional: a local .srt/.vtt path, an https URL, or a File in a browser.
subtitles: { es: "./demo.es.srt", fr: "https://example.com/demo.fr.vtt" },
exportSrt: true,
},
{ timeout: 7_200_000 }, // milliseconds — matches the backend's own ~2h ceiling
);
for (const [language, url] of Object.entries((result as DubbingResult).outputs ?? {})) {
console.log(language, url);
}
// Only present with exportSrt, and a language whose export was blocked is absent.
for (const [language, url] of Object.entries((result as DubbingResult).subtitles ?? {})) {
console.log(language, url);
}
CLI(npm install -g sonilo-cli または pip install sonilo-cli)
sonilo dubbing --video-url https://example.com/product-demo.mp4 --languages es,fr --output dubbed.mp4
# writes dubbed.es.mp4 and dubbed.fr.mp4
# With the user's own scripts. --subtitle is repeatable, once per language, and
# its value is a local .srt/.vtt path or an https URL.
sonilo dubbing --video-url https://example.com/product-demo.mp4 --languages es,fr --subtitle es=demo.es.srt --subtitle fr=demo.fr.srt --export-srt --output dubbed.mp4
# also writes dubbed.es.srt and dubbed.fr.srt beside the videos, so --output may not end in .srt
--timeout のデフォルトはすでに 7200 秒で、バックエンドの上限に一致しています。通常のターミナルでは問題ありませんが、エージェントホストのシェル内では、シェルツールがフォアグラウンドのコマンドを終了させないよう、上記の短い送信・ポーリングのパターンを使用してください。
cURL(MCP ホストを使わない生の REST API)
curl -X POST "https://api.sonilo.com/v1/dubbing" \
-H "Authorization: Bearer $SONILO_API_KEY" \
-F "[email protected]" \
-F 'languages=["es","fr"]' \
-F "subtitles[es][email protected]" \
-F "subtitles[fr]=https://example.com/demo.fr.vtt" \
-F "export_srt=true"
# -> {"task_id": "...", "subtitle_preflight": {...}}
# poll GET /v1/tasks/{task_id} — can take up to ~2 hours
アップロードしたファイルの代わりに video_url も使用できますが、https である必要があります。吹き替えパイプラインはソースを自ら取得するため、http は拒否されます。
各言語につき subtitles[<language>] フィールドを 1 つ指定します。値は、アップロードした .srt/.vtt パート、または https URL 文字列です。角括弧付きのキーが必須です。subtitles だけのキー、同じキーの繰り返し、または類似しているものの誤ったコード(subtitles[zh-CN] — コードではアンダースコアを使用するため、zh_cn)は拒否され、黙って無視されることはありません。
ツール
| ツール | 説明 |
|---|---|
dubbing(video_path? | video_url?, languages?, ducking?, lipsync?, subtitles?, export_srt?, output_directory?) | 指定された各言語に動画を吹き替えます。言語ごとに 1 つの .mp4 が保存され、export_srt を指定すると言語ごとに 1 つの .srt も保存されます。 |
パラメーター
| パラメーター | 型 | デフォルト | 備考 |
|---|---|---|---|
video_path | string | — | .mp4/.mov/.webm/.m4v/.gif(gif はアニメーションである必要があります)。最大 300s(5 分)。アカウントのアップロードサイズ上限が適用されます。 |
video_url | string | — | https である必要があります(http だけでは不可)。video_path/video_url のどちらか一方のみを指定してください。 |
languages | list[str] | ["zh_cn", "es", "fr"] | 対象言語コードです。対応言語:en、zh_cn、ja、ko、pt、pt_br、es、es_419、de、fr、it、ru、th、ar、tr、vi、id、ta、ml、kn、gu、pa_in、sd_in、hi。pt_br はブラジルポルトガル語、es_419 はラテンアメリカのスペイン語です。pt/es は地域が指定されていないため、重要な場合はユーザーに希望を確認してください。ar は国ごとの方言ではなく、地域指定のないアラビア語なので、確認する必要はありません。pa_in と sd_in はインドで話されるパンジャーブ語とシンド語です。利用できる異形はこれだけなので、ユーザーの対象視聴者がパキスタンにいる場合は、どちらも別の文字体系で書かれることを伝えてください。hi はヒンディー語です。これを省略しても 3 言語に吹き替えられ、3 言語分の料金が発生します。1 言語のみを希望する場合は、要素が 1 つのリストを明示的に渡してください。 |
ducking | bool | off | 吹き替え音声が話している間、バックグラウンドの音楽や効果音を小さくします。デフォルトではオフで、バックグラウンド音声は常に一定の音量で維持されます。どちらを選んでも無料です。 |
lipsync | bool | true | 吹き替え音声に合わせて話者の口元を再レンダリングするかどうかを指定します。false にすると映像には一切手を加えず、再レンダリングではなく元の解像度とフレームレートで動画が返され、音声のみが置き換えられます。そのため、口の動きは元の言語のままになります。画面上に話者がいない映像(画面録画、B ロール、ナレーションなど)や、口の動きの一致より元の映像を正確に維持することが重要な場合に使用してください。どちらを選んでも料金は同じです。 |
subtitles | dict[str, str] | — | 対象言語ごとに台本を 1 つ指定します。例:{"es": "demo.es.srt"}。各値には、ローカルの .srt/.vtt パスまたは https URL を指定します(ホストされた MCP サーバーでは URL のみ受け付けます)。これらは話す内容を含む対象言語の台本であり、元の言語の文字起こしではありません。翻訳の代わりに、吹き替えでは台本の内容がそのまま話されます。キーの集合は languages と完全に一致する必要があります。以下のルールを確認してください。いずれかの違反があると、課金前に 422 が返されます。 |
export_srt | bool | false | 強制アラインメントを使用して、各言語の台本の文言をそのまま保ちながら、納品される音声に合わせてタイミングを調整した字幕も返します。subtitles が必要です。これだけを送信すると 422 が返されます。 |
output_directory | string | SONILO_MCP_BASE_PATH | 絶対パス、またはベースパスからの相対パスを指定します。 |
スクリプトの持ち込み
ユーザーが承認済みの翻訳をすでに用意していて、その内容を一言一句そのまま音声にしたい場合は、subtitles を使用します。音声にする前に翻訳を確認または修正したいものの、まだスクリプトがない場合は、まず proofread スキルを実行してください。言語ごとに編集可能な .srt が返され、修正済みファイルはそのまま subtitles に渡せます(ここでは追加のキーとなる原文言語のファイルは除きます)。以下のルールは課金前にすべて確認されるため、違反しても費用はかからず 422 が返されます。ただし、ユーザーに再度のやり取りを強いることになります。特に最初の2つは間違えやすいため、注意してください。
- すべての言語を対象にし、それ以外は含めないでください。 キーのセットは
languagesと完全に一致する必要があります。コードが不足または余分な場合は拒否され、エラーにそのコードが示されます。ユーザーから3言語中2言語分のスクリプトしか提供されていない場合は、1言語分を省くのではなく、残りのスクリプトを依頼してください。languagesを省略してもデフォルトで3言語(zh_cn、es、fr)になるため、3言語すべてのスクリプトが必要です。 - 原文の文字起こしではなく、対象言語のスクリプトを指定してください。 元の英語のセリフを
"es"として送信するのは、一見有効なスクリプトですが、英語を話すスペイン語吹き替えが生成されます。チェックではテキストを読み取り、指定された言語と異なるスクリプトは拒否されますが、送信前にユーザーから渡された内容を確認してください。 - 使用できるのは
.srtまたは.vttのみで、拡張子は小文字にしてください。各ファイルは最大 1 MiB です。それ以外は拒否されます。 export_srtにはsubtitlesが必要です。 スクリプトがなければ音声と照合できるものがないため、単独では422が返されます。- エクスポートがブロックされても、ジョブは失敗しません。 吹き替え動画は引き続き納品され、課金されます。その言語の
.srtだけが生成されません。これを吹き替えの失敗ではなく、追加項目の欠落として報告し、そのためにジョブを再実行しないでください。 202応答にはsubtitle_preflightが含まれ、各スクリプトについてチェック結果が示されます。完了したタスクでは、言語ごとのstatus、alignment_loss、issuesを含むsubtitle_exportとともに、subtitle_preflightが再び含まれます。パイプラインはこれらの値を、記録時の型のまま JSON として保存します。そのため、件数や損失値が数値ではなく文字列として返されることがあります。ユーザーに伝える際は、数値であると決めつけないでください。
ワークフローのヒント
- ユーザーが指定していない場合は、必ずどの言語にするか確認してください。
["zh_cn", "es", "fr"]のデフォルトに頼ってはいけません。このデフォルトでは、3言語分の料金が気付かないうちに発生します。 - カメラに話者が映っていない場合は、
lipsync=falseを検討してください。 画面収録、Bロール、ナレーションでは口の動きを合わせる必要がありません。リップシンクを適用すると、メリットがないまま映像が再レンダリングされます。適用しない場合は、元のフレームが元の解像度とフレームレートのまま返されます。ユーザーからの依頼がない限り、トークヘッド動画ではオフにしないでください。口が元の言語で話し続けているのがはっきり見えてしまいます。 - ユーザーが台本を持っている場合は、提供してもらってください。 承認済みの文面、既存のローカライズ、またはそのまま話してほしい翻訳に言及している場合、それは
subtitlesです。パイプライン独自の翻訳で上書きされてしまいます。台本をこちらで作ってはいけません。自分で書いた台本は、ユーザーが承認していない翻訳を動画内で話すことになります。 - これは音楽やSFX用のスキルではありません(text-to-music、video-to-music、text-to-sfx、video-to-sfx)。音楽やSFXには一切手を加えず、既存の音声を翻訳して吹き替えます。
- 所要時間について事前に伝えてください。 最大で約2時間かかる場合があること、処理中にその場を離れても問題なく、後から結果を取得できることをユーザーに伝えてください。
- 無料実行は動画全体ではなく、プレビューです。 セルフサービスアカウントで利用できる無料の単一言語呼び出しは1回で、翻訳されるのは最初の15秒のみです。結果に
trial_previewが含まれている場合は、クリップが動画の最初の15秒であり、動画全体の料金がfull_video_cost_usdであることをそのまま伝えてください。クリップを翻訳の完成版として提示してはいけません。無料実行を使い切った後、支払い方法が登録されていないアカウントで呼び出すとtrial_exhaustedになります。確信がない場合は、まず account を参照してget_account_servicesを確認し、呼び出す前にユーザーへ警告してください。
タイムアウトした呼び出しからの復旧
呼び出し自体のロングポーリングが中断された場合(ホスト側のタイムアウトやセッションの終了など)、エラーメッセージ、または送信時に stderr に出力されたタスク ID から task_id を取得できます。get_sfx_task(task_id) を呼び出してください。ホスト型サーバーでは get_generation_task(task_id) を呼び出します。これでステータスを確認し、準備ができたら完成ファイルをダウンロードできます。詳しくは task-recovery を参照してください。
出力ファイル
リクエストした言語ごとに .mp4 が1つ生成され、ファイル名は dubbing-<first 8 chars of the task id>.<language>.mp4 になります。ファイル名を指定するプロンプトはないため、すべての吹き替え出力にタスク ID に基づく名前が付けられます。
export_srt を指定すると、各動画と同じファイル名の .srt が動画の隣に生成されます。
dubbing-<first 8 chars of the task id>.<language>.srt という名前になり、その言語の各行が、出力された音声に合わせてタイミング調整されます。エクスポートがブロックされた言語では、動画のみが生成され、.srt はありません。この場合はエラーではなく注記として報告されます。CLI では、動画と同様に SRT も --output の名前に従います(--output dubbed.mp4 を指定すると dubbed.es.mp4 と dubbed.es.srt が生成されます)。そのため、--output 自体の拡張子に .srt を指定することはできません。
無料プレビュー
実行がアカウントの無料15秒プレビューだった場合、どの状態でもタスクに
trial_preview が含まれます。
"trial_preview": {
"preview_seconds": 15,
"source_duration_seconds": 60.0,
"trimmed": true,
"languages": 1,
"full_video_cost_usd": 3.49,
"message": "Free preview: the first 15 seconds of your 60-second video, in 1 language. Translating the full video costs $3.49 — add funds at https://platform.sonilo.com/dashboard/billing"
}
この場合、duration_seconds はソースの長さではなく15で、出力される
.mp4 は動画の最初の15秒です。MCP ツールと両方の CLI は、他のステータス行とともに
message を出力します。SDK では DubbingResult.trial_preview として公開されます。
この情報をユーザーに伝え、クリップを動画全体として扱うのではなく、全編を実行する方法
(資金を追加して再度呼び出す。この実行には料金が発生します)を案内してください。
エラー処理
よくあるエラー:401 無効なキー、402 残高不足(吹き替えには使い切るトライアルがなく、直ちに課金されます)、413 ファイルが大きすぎる、422 無効なパラメーターまたは未対応の言語コード(課金前に拒否されます)、429 レート制限です。アカウントスキルを参照してください。
code: SUBTITLE_PREFLIGHT_BLOCKED を含む 422 は、送信したスクリプト自体がチェックに合格しなかったことを意味します。メッセージにはブロックされた言語とその問題コードが示され、details には言語ごとのレポートが含まれます。課金は発生していません。そのスクリプトを修正または差し替えて再送信してください。subtitles を削除してそのままジョブを実行してはいけません。そうすると、ユーザーが承認したセリフではなく、パイプライン独自の翻訳が気付かれないまま納品されてしまいます。