Communitygithub.com

Perso Dubbing — 多言語リップシンク出荷

Perso AI自動吹替:upload→split→translate→merge→リップシンクMP4。一命令で多言語。READMEにdemo GIF。38★。

Perso Dubbing — 多言語リップシンク出荷 とは?

Video Localization手順3:Perso 38★。多言語リップシンク。9/26 VoxCPM・9/24 IndexTTSとは別。

対応✓Claude Code✓Codex CLI✓Cursor✓Antigravity✓Gemini CLI
npx skills add perso-ai/perso-dubbing-plugin

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

/dubbing

Perso AI Dubbing API を介して動画を自動吹き替えするスキルです。

基本ルール(必ず守ること)

  • キーを生の状態で見るのはワーカーのみです。 Read で開いたり、エコーしたり、コマンドライン引数として渡したりしないでください。ワーカーは XP-API-KEY ヘッダーでのみキーを送信します。
  • 1コマンド = ジョブ全体です。 scripts/dubbing.mjs がアップロード・分割・翻訳・結合・保存をすべて自ら行います。その前に prepare_input.mjs や probe_split.mjs を実行しないでください。 これらはデバッグツールであり、probe_split.mjs は実際にアップロードを行うため、動画が2回アップロードされてしまいます。
  • 必ずバックグラウンドで dubbing.mjs を実行してください。 ジョブは数分から数時間かかるため、フォアグラウンドのシェルがタイムアウトすると実行が途中で終了します。
  • 言語が指定されていない場合 → ソースは auto、ターゲットは en です。
  • 複数の言語は1つのコマンドで指定します(--target en,zh,ja)— アップロード/分割は1回行われ、各言語で再利用されます。言語ごとに1回実行しないでください(ソースが毎回再アップロードされます)。
  • 進捗を忠実に中継してください。 ワーカーの標準出力 [progress] 行を、そのまま、または要約してチャットに伝え、実際に表示されなかったステップ(分割/結合は上限を超える動画にのみ存在します)についてはアナウンスしないでください。インデントされた標準エラーの詳細ログは中継する必要はありません。
  • 実行中はユーザーに情報を提供し続けてください。 吹き替え、リップシンク、音声分離はすべて [status] ハートビート(ステージとアイテム数、例:ja 4/6 · en 1/6 または separating — file 2/5、next check ~Nm のヒント付き)を出力し、各アイテムの完了は [progress] 行としてストリーミングされます。起動後約3分後、次にヒントの間隔(メディアが10分以下の場合は10分、それより長い場合は30分)でバックグラウンド出力を確認し、新しい [progress] 行があればすぐに中継し、そうでなければ最新の [status] 行を1行のアップデートとして投稿してください。パーセンテージ、経過時間、ETAを決してでっち上げないでください — 行に書かれていることだけを中継してください。ユーザーの入力を必要とする停止([space-select]、[split-confirm]、[free-limit]、[resume-check]、[credit-check]、クレジット切れ、完了)はプロセスを終了させるため、ポーリングしなくてもそれらが表面化します。
  • テレメトリ用にランタイムに名前を付けてください(サイレント)。 ワーカーコマンドに --host <claude-code|codex|cursor|antigravity|gemini> を追加し、自分がどのエージェントとして実行しているかを(分かれば)指定してください。これは使用状況テレメトリにタグを付けるだけで、ユーザーに決して表面化させたり、それについて尋ねたりしないでください。不明な場合は省略してください。
  • サポートされていないフォーマットは自動的にスキップされ、残りは処理を続行します — スキップ通知を中継してください。
  • 一時停止は失敗ではありません。 [space-select]、[split-confirm]、[free-limit]、[credit-check]、または [resume-check] 行は、実行が あなたに何かを尋ねるために停止した ことを意味します — 終了コードは0ですが(エラーのように見えない)、ジョブは 完了していません。これらの行のいずれかが存在する場合は、実行が完了したと報告せず、中継して対応してください。シグナルは終了コードではなく、これらの行です。

セットアップ(遅延 — 事前のステップはありません)

  1. APIキー — 最初に実行するステップではありません。 Perso APIを必要とするコマンドが実行された瞬間にワーカーが自らゲートをかけます:最初のそのような実行時に、ブラウザページを開くか(サインイン、ワンクリック — キーは暗号化されて保存されます)、ブラウザが開けない場合はファイルベースの手順を出力します — それらをユーザーに中継してください。ヘッドレス/SSHマシンでは、ワーカーはブラウザフローを完全にスキップし、ファイル/--import 登録から開始します(ブラウザページは、それが実行されているマシンにのみキーを配信できます)— 同じようにそれらの手順を中継してください。自分でキー登録をトリガーしないでください:ワーカーは必要に応じて connect.mjs/resolve_key.mjs --watch を起動するため、これらを実行したり、事前ステップとして resolve_key.mjs --check を実行したりしないでください(ユーザーがキーが登録されているかどうかを明示的に尋ねた場合のみ — キーの欠落はエラーではありません)。キーをチャットに貼り付けないでください。キーを取得する:https://developers.perso.ai/api-keys
  2. ffmpeg/ffprobe — 動画がプランの制限を超えていて分割する必要がある場合にのみ自動インストールされます(許可を求められた場合は承認してください)。手動チェック:node scripts/check_deps.mjs。

実行

入力(ローカルパスまたはURL — 不足している場合は再度尋ねてください)を収集し、バックグラウンドで実行 します — ワーカーは最初の必要時に自分でキーゲートを実行します。登録が開始された場合は、印刷された指示を中継するだけです。

  • 単一:node scripts/dubbing.mjs "<file|URL>" [--source auto] [--target en] [--space "space name"] [--out result.mp4] [--lipsync] [--no-save]
  • 複数言語/複数入力(1つ以上の入力;URLとファイルを混在可能):node scripts/dubbing.mjs "<URL>" "<file>" --target en,ja — 入力×言語ごとに1つの出力が、各ソースの隣に保存されます(--out <folder> で収集されます)。
  • フォルダ(バッチ):node scripts/dubbing.mjs "<folder>" [--target en,zh] [--recursive] [--out output-folder]

言語コード — --target は言語コード(en、ja)または地域タグを受け入れます。地域バリアントが存在するのは 英語(en = 米国デフォルト、en-GB = 英国)、ポルトガル語(pt = ブラジルデフォルト、pt-PT = ポルトガル)、スペイン語(es = メキシコデフォルト、es-ES = スペイン)のみです;en-US、pt-BR、es-MX はそれらのデフォルトの許容されるスペルです。他のすべての言語には単一のバリアントがあり、--source には言語のみが必要です(そこでの地域タグはプレーンな言語として扱われます)。

  • リクエストで地域が指定された場合 → その正確なタグを使用します。バリアントが ない 地域(例:オーストラリア英語)→ リストされているオプションのみが存在することをユーザーに伝え、実行前に選択させてください。
  • 2文字のトークンは国ではなく言語コードです:uk は ウクライナ語 — イギリス英語は en-GB です。ca(カタルーニャ語)、be(ベラルーシ語)、eu(バスク語)も同様の罠があります。ユーザーの表現がどちらかを意味する可能性がある場合は、実行前に どちらを意味するか尋ねてください。
  • 地域なしで指定された言語 → デフォルトのバリアントです。これら3つの言語については、配信ノートで適用されたデフォルトを明記してください(例:「Spanish (Mexico) — スペインには es-ES を使用してください」)。

保存場所 — --out は フォルダ(既存のディレクトリ、または / で終わるパス)を受け入れ、その中に結果を収集します。または、単一入力の場合は ファイルパス を受け入れます(パスに拡張子がない場合は実際の拡張子が追加されます)。デフォルトは各ソースファイルの隣です;尋ねる必要はありません。セッションの最初のジョブでは、キックオフ行でそれを述べてください(例:「結果はオリジナルの隣に保存されます — 別のフォルダが必要な場合は今教えてください」)そして、答えを待たずにすぐに開始してください。ユーザーがフォルダを指定した場合 — このリクエストで、またはこのセッション後いつでも — --out "<folder>" を指定して実行し、ユーザーが変更するまで後続のすべてのジョブでそのフォルダを使用し続けてください。実行が既に開始された後にユーザーがリダイレクトした場合は、実行が完了したら完了したファイルをそこに移動してください。例外:すべての入力がURLである場合(ローカルソースフォルダがない)、開始前に保存場所を尋ねてください。

スペース選択 — 複数のワークスペースがある場合、ワーカーはアップロード前に停止し、[space-select] 行(名前 | (プラン) | 残りクレジット)を出力して停止します。ユーザーにこれらのオプション のみ を表示し(内部番号は表示しない)、どれかを尋ね、--space "<space name>" を指定して再実行してください。スペースが1つ → 質問なし;PERSO_SPACE_SEQ で固定されます。

分割確認 — 入力が長さまたはサイズ制限を超えており、自動分割&結合(吹き替え、吹き替え+リップシンク、または音声分離)が必要な場合、ワーカーは停止して [split-confirm] 行を出力します。それらを中継し、ユーザーに尋ねてください:長さ/サイズ制限を超えているため、自動分割 → 処理 → 結合 が必要で、これは 自分で分割するよりも仕上がりが悪くなる可能性があります — 自動的に続行しますか?「はい」の場合、同じコマンドに --allow-split を指定して 再実行してください(この時点までは何も請求されないため、再実行は無料です)。バッチ実行:--allow-split は実行内のすべての分割を承認します。

保存しない(サーバーのみ) — ユーザーが動画を吹き替えたいが ローカルファイルとして保存したくない 場合、--no-save を追加します:ワーカーは結果をユーザーのPersoワークスペースに残し、ダウンロードをスキップし、Kept on server, not saved: … → project <seq> を出力します([project-ref] 行は引き続き出力されるため、ダブは後でリップシンクまたは取得できます)。分割されていない単一動画のみ — 分割された動画の結合ファイルはローカルダウンロードが必要なため、通常どおり保存され、ワーカーはそのように述べます。--lipsync と組み合わせることはできません(リップシンクされた動画はダウンロードする必要があります)。

無料プラン(結果はPersoに残ります) — Freeワークスペースは通常どおり吹き替え、リップシンク、分離できますが、サーバーは すべての ダウンロードを拒否するため、ワーカーはそこにファイルを保存しません。Free plan — <name>: … ready on Perso → <url> (downloads need a paid plan) と出力します — そのリンクを 配信された結果として 中継してください:実行は 完了 しており、失敗したものはなく、再開する必要もありません。ユーザーが実際のファイルを必要とする場合、有料プランが必要です — アップグレードパスを提供してください(プランアップグレードとクレジット を参照)、再実行はしないでください。

無料プラン [free-limit] 一時停止 — 2つあり、どちらも何かが請求される前に行われます:

  • 30秒プレビュー。 30秒を超える吹き替え/リップシンク入力は、[free-limit] 行で停止します:Freeでは 最初の30秒のみ が吹き替えられ、残りは除外されます。質問を中継し、「はい」の場合、同じコマンドに --allow-preview を指定して 再実行してください(ワーカーは最初の30秒をローカルでトリミングし、その部分のみを送信します)。Persoによってインポートされたプラットフォームリンクはトリミングできません — その場合の答えは、ローカルファイル、より短いクリップ、またはアップグレードです。
  • プラン制限超過。 プランの長さ/サイズ制限を超えるメディアは、Freeでは分割オファーが ありません(--allow-split は適用されません):[free-limit] 行は、より短いファイルまたはアップグレードのみが方法であることを示します。それらを中継して停止します。

実行中(待機中に説明するため):

  • 分割:ファイル全体が最初にアップロードされます;プラン制限の拒否のみがffmpegをインストールし、ロスレスで分割します。外部URL(YouTube・TikTok・Drive・Vimeo)はサーバー側で処理されます。
  • キュー:すべての入力 × パーツ × 言語が1つのプールを共有します;満杯のキューは5分ごとに再チェックされます。パーツのエンジンエラーは、そのパーツの他の言語をキャンセルします;サイレントパーツはオリジナルをそのまま通過させます;アイドルガードは永遠にハングするのを防ぎます。
  • 保存:パーツは入力×言語ごとに1つのファイルに結合されます。分割されていない出力はPersoのファイル名を保持します;結合されたものは <original-name>.dubbed.<lang>.<ext> になります;競合は _2、_3… になります。

リップシンク

リップシンク(口元を吹き替え音声に合わせる)は、吹き替え 後、完了した吹き替えプロジェクトに対して実行されます。動画のみ — 音声入力は拒否されます。これは長時間のジョブです:バックグラウンドで実行し、吹き替えよりもかなり時間がかかることをユーザーに事前に伝えてください。 クレジット(サーバー請求が信頼できます):吹き替え ≈ 秒×1 · リップシンク ≈ ×2 · 両方 ≈ ×3 — 今吹き替え + 後でリップシンクは、両方を一度に行うのと同じコストです。4K+ ソース:プロ/ビジネス/エンタープライズプランではすべてのレートが×3 (例:1分の4K吹き替え+リップシンク ≈ 60×3×3 = 540) — 動画が4Kの場合はこれに言及してください。

存在するものによってフローを選択してください:

  1. 新しい動画 + リップシンク — 1つのコマンドでチェーン全体(吹き替え → リップシンク → 保存)を実行します;両方のステージが課金されることを警告します: node scripts/dubbing.mjs "<file|URL>" --target en --lipsync [credit-check] 行が出力されて停止した場合、見積もりが残りクレジットを超えています:その行を表示し(トップアップURLを含む)、ユーザーがトップアップするか、とにかく続行を承認した 後でのみ --force を指定して再実行してください。
  2. このセッションで以前に吹き替え済み — 完了した実行はすべて [project-ref] {...} 行を出力します。それを保持し、ユーザーに決して表示しないでください。 再吹き替えなしのリップシンク(×2、吹き替え料金なし): node scripts/dubbing.mjs --lipsync-only '<that [project-ref] JSON>'
  3. このセッションに [project-ref] がない場合 — ユーザーがPersoポータルからプロジェクト番号を知っているか尋ねてください(--lipsync-only <number>、×2)。そうでなければ、動画を再度吹き替える必要があります(--lipsync、×3) — 再吹き替えの前に確認してください。

ルール:

  • 同じプロジェクトでのリップシンクの繰り返しは再度課金されます(サーバー側の重複排除はありません)。このセッションで既にリップシンク済みの場合は、既存のファイルを指摘し、明示的な確認があった場合にのみ再実行してください。
  • リップシンクが失敗した場合、ワーカーは代わりに吹き替え動画を保存し、最終レポートでそのように述べます — それを明確に中継してください;吹き替えクレジットは無駄になりません。
  • 吹き替えとリップシンクの間にクレジットが不足した場合:吹き替え動画は保存され、リップシンクのみが続行されて完了します — トップアップURLを中継し、支払い後は [resume-state] パスを介して続行します(中断と再開 を参照)。

スピーカー(吹き替えプロジェクトのみ)

既に吹き替えられたプロジェクトの1つ以上の文に 新しいスピーカー を割り当てるには、以下を実行します:

node scripts/speaker.mjs "<project URL|projectSeq>" --at "5s,22s,98s"(カンマ区切りのタイムコード/範囲) node scripts/speaker.mjs "<project URL|projectSeq>" --text "first line|second line"(パイプ区切り、引用符で囲まれたテキスト) node scripts/speaker.mjs "<project URL|projectSeq>" --sentence 1234,1288([sentence-select] の質問の後に再実行) node scripts/speaker.mjs "<project URL|projectSeq>" --list(プロジェクトの文を閲覧して適切なターゲットを見つける)

吹き替えプロジェクトのみ — ワーカーは字幕(STT)、音声分離、リップシンクのプロジェクト、および未完了/失敗したプロジェクトを拒否します。プロジェクトリンクからワークスペースを自動的に特定するため、どのスペースかを尋ねる必要はありません。

一時停止は失敗ではありません。 [sentence-select] 行は、ワーカーが単一のターゲットを特定できなかったことを意味します(何も指定されていない、一致するものがない、または複数の文が一致した)— 失敗したからではなく、何かを尋ねるために正常終了します。その下の番号付きリスト(インデックス、時間ラベル、テキスト)は、そのままユーザーに中継しても安全です。そのリストの直後に、[sentence-ref] 行が同じ番号をワーカーの内部文番号にマッピングしたJSONマップを出力します — その行は あなた自身の参照用のみです:ユーザーに表示したり、読み上げたりしないでください。ユーザーが番号を選択したら、そのマップでルックアップし、--sentence にその値を設定して同じコマンドを再実行してください。それに加えて [speaker-resolve] ブロックがある場合、一部のターゲットは既に解決されているが まだ何も書き込まれていない ことを意味します — それ自体に番号付きリストと独自の [sentence-ref] 行があります;再実行の --sentence リストには、既に解決された値と新しく選択された値の両方を含める必要があります。そうしないと、解決された値が削除されてしまいます。実行で複数の [sentence-select] グループが出力された場合(複数のあいまいなターゲットが同時に)、各グループは…

…[翻訳のために切り詰められました]

Individual skills in this repo

This repo contains 3 individual skills — each has its own dedicated page.

関連スキル