Communitygithub.com

動画ローカライズ:リンクから字幕焼き込み完成版へ

Porter で YouTube・X・Instagram・TikTok・Bilibili のリンクをローカライズ版に。取得・文字起こし・翻訳を行い、FFmpeg で二言語または中国語のみの字幕を焼き込みます。各段階はディスクに保存。

動画ローカライズ:リンクから字幕焼き込み完成版へ とは?

「動画ローカライズ」レシピのステップ 1(エンドツーエンドのパイプライン)、RolinShmily/porter-workflow より。Porter は取得 → 文字起こし → 翻訳 → 焼き込みの再開可能な 4 段階を実行し、各成果物をディスクに書き出すため、失敗しても完了済みの作業は失われません。エージェントはまず `plan` を実行し、ネイティブ字幕トラック(ASR・キー不要)があるか、Whisper 互換の文字起こしが必要かを判定。その後、二言語/中国語 SRT と libass による字幕焼き込み MP4 を出力します。CLI・MCP サーバー・Web ワークベンチ・本 Agent Skill の 4 形態で同じエンジンを提供します。

対応~Claude Code✓Codex CLI~Cursor
npx skills add https://github.com/RolinShmily/porter-workflow/tree/HEAD/skills/porter-skill

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

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

ドキュメント

Porter Skill(ストリーミングメディア運び屋)

1つの動画リンクを、中国語ハードサブ付きの完成品に変換します。4つのフェーズを順に実行:取得 → 文字起こし → 翻訳 → 焼き込み。各フェーズの成果物をディスクに書き込むため、途中で失敗しても完了済みの部分は失われません。


⚠️ 前提条件:文字起こしにはキーが必要

これは最初に確認する必要があります。そうしないと、タスクは文字起こしフェーズで失敗します。

機能キーの要否
ダウンロード、翻訳、焼き込み不要
音声文字起こし(ASR)OPENAI_API_KEY(または WHISPER_API_KEY)が必要、または VideoCaptioner CLI がインストールされていること
プラットフォームネイティブ字幕トラック(YouTube / Bilibili など)不要——ネイティブトラックがあれば ASR は実行しない

v0.1 で宣言されていた「純 Python でキー不要のクローズドループ」は機能しなくなりました:キー不要の音声認識エンドポイントはすべて停止されています(2026-09-22 時点で確認;または [asr-local] extra を使用してキー不要のローカル認識を行う)。キーがなく、動画にプラットフォームの字幕トラックもない場合、タスクは transcribe フェーズで every speech-to-text backend failed で終了します。

したがって:最初に plan を実行してください。これにより、この動画がネイティブ字幕トラックを使用するか、ASR を使用するか、そしてそれが可能かどうかが直接通知されます。


呼び出しエントリポイント

CLI エントリポイントは uvx を介して実行されます。Windows PowerShell ではネイティブの .ps1 を使用し、Git Bash / WSL が利用可能であると仮定しないでください:

スクリプト用途
scripts/porter.shBash メインエントリポイント、porter CLI に転送します。
scripts/porter.ps1Windows PowerShell メインエントリポイント、inspect / plan / run / jobs などのサブコマンドをサポートします。
scripts/inspect.shBash 事前チェック、porter.sh inspect と同等です。
scripts/bootstrap.shリポジトリチェックアウトから .venv を作成するための代替エントリポイント;スキルと一緒に Python ソースコードはインストールされません。
# 事前チェック
<SKILL_DIR>/scripts/inspect.sh "https://youtu.be/dQw4w9WgXcQ"
# 計画
<SKILL_DIR>/scripts/porter.sh plan "https://youtu.be/dQw4w9WgXcQ"
# 実行
<SKILL_DIR>/scripts/porter.sh run "https://youtu.be/dQw4w9WgXcQ" -o ./porter_output

Windows PowerShell では & '<SKILL_DIR>\scripts\porter.ps1' inspect '<URL>' --json を使用し、plan / run / jobs も同じエントリポイントを呼び出します。inspect.sh および以下の nohup、grep コマンドは Bash の例であり、そのまま PowerShell に貼り付けることはできません。

uvx の初回実行時には、依存関係を解決するためにネットワーク接続が必要です。デフォルトでは porter-workflow[llm] のみがインストールされます(基本パッケージには既に yt-dlp が含まれています);ローカル ASR が必要な場合、ユーザーの同意を得て PORTER_SKILL_SPEC=porter-workflow[llm,asr-local] を設定します。オフラインインストールの場合は、リポジトリチェックアウト内でローカル依存関係を準備してください。スキルディレクトリにソースコードが含まれているとは想定しないでください。

ワークスペースのみに書き込めるホストでは、まず許可された絶対ディレクトリを確認し、PORTER_SKILL_STATE_DIR をその中の .state に設定し、porter.sh --host-check または porter.ps1 --host-check を実行します。これにより、uv、yt-dlp、およびジョブレジストリキャッシュがそのディレクトリにリダイレクトされます(ホストが既に設定したキャッシュパスを上書きします)。出力 -o も許可されたディレクトリ内にある必要があります。設定されていない場合は、ホストのデフォルトパスが保持されます。コマンド、制限、および Windows の例は references/HOSTS.md を参照してください。


ワークフローのクローズドループ

順番に実行します。各ステップは後続のステップよりも安価であり、目的は長時間の計算を費やす前に、不良な入力を排除することです。

1. 事前チェック —— inspect

<SKILL_DIR>/scripts/inspect.sh "<URL>" --json

プラットフォーム、タイトル、長さ、解像度、アスペクト比、字幕トラックの有無を返します。メディアをダウンロードする前に行われ、数秒で完了します。

解釈:is_valid が「リンクが有効」であり、ok は単に「呼び出しが成功した」ことを意味します。リンクが無効な場合、is_valid=false となり、その場合は再試行しないでください——デッドリンクの再試行は無意味です。

終了コード 1 は、リンクが利用できないことを示します。

2. 計画 —— plan

<SKILL_DIR>/scripts/porter.sh plan "<URL>" --json

これは最も時間を節約するステップです。次の質問に答えます:「この動画はどのように処理されるか、処理可能かどうか」:

  • subtitles.route:platform(プラットフォームのネイティブ字幕トラックを使用)または asr(音声認識を実行)
  • translation.needed:既存の中国語トラックがある場合は false、翻訳フェーズ全体をスキップ可能
  • feasible / blocking_issues:false の場合は停止、ジョブを開始しない
  • notes:必読。最も重要な2つ:
    • プラットフォームの字幕トラックは**「要求されたものであり、保証されていない」**——取得に失敗する可能性あり(プラットフォームのレート制限、HTTP 429)し、音声認識にフォールバックする
    • 利用可能な認識バックエンドがすべて未検証のリバースエンドポイントである場合、ノートはそれを明示します

終了コード 1 は、実行不可能であることを示します。

3. ユーザー確認

1つのジョブで数百 MB のダウンロードと数分の実行が発生する可能性があります。plan の結果をユーザーに報告し、実行前に同意を得ます(どのトラックを使用するか、どのフェーズを実行するか、焼き込みを行うかどうか)。feasible=false の場合は、ブロッキング問題を報告し、ジョブを開始しないでください。

4. 実行 —— run

<SKILL_DIR>/scripts/porter.sh run "<URL>" -o ./porter_output

長い動画ではフォアグラウンドで呼び出して完了を待たないでください。 バックグラウンドで起動し、ジョブレジストリをポーリングします:

nohup <SKILL_DIR>/scripts/porter.sh run "<URL>" -o ./porter_output > run.log 2>&1 &
# ポーリング(ジョブレコードは共有レジストリファイルに書き込まれ、プロセス間で参照可能)
<SKILL_DIR>/scripts/porter.sh jobs list
<SKILL_DIR>/scripts/porter.sh jobs status <job_id>

PowerShell では、ホストが提供するバックグラウンドジョブツールを使用して & '<SKILL_DIR>\scripts\porter.ps1' run ... を非同期で起動し、同じ PORTER_SKILL_STATE_DIR を使用して jobs status を継続的に呼び出します。Out-String を使用して、長時間のコマンドの進行状況を最後まで蓄積してから出力しないでください。

「ツールのタイムアウトを1200秒に設定する」という方法で長時間タスクに対処しないでください(v0.1 の方法)。 それは動画が長くなると同様に失敗し、失敗したときに進行状況を取得できません。ジョブレジストリはこの目的のために設計されています。

5. 品質チェック(必須)

終了コードだけで完了と判断しないでください。 少なくとも以下を確認:

# 1. 中国語字幕が確かに存在し、CJK 文字を含む(「未翻訳の偽の完成品」を防止)
grep -qP '[\x{4e00}-\x{9fff}]' ./porter_output/<task>/cooked/subtitle_zh.srt \
  && echo "OK: 中国語を含む" || echo "FAIL: 中国語なし"

# 2. 完成品がデコード可能で moov atom が完全(公開時のファイル切り捨てを防止)
ffprobe -v error -show_entries format=duration -of csv=p=0 ./porter_output/<task>/cooked/video_zh.mp4

完成品のサイズが異常に小さい場合、通常は動画が短いのではなく、焼き込みの失敗を示しています。

6. エラー発生時

<SKILL_DIR>/scripts/porter.sh doctor     # このマシンが動作可能か:ffmpeg/libass、JS ランタイム、フォント、エンコーダー
<SKILL_DIR>/scripts/porter.sh config list # 解析された設定(キーはマスク済み)

よく使うパラメータ

# 字幕のみ、焼き込みなし
run "<URL>" --burn skip

# 中国語のみの完成品(バイリンガルは生成しない)
run "<URL>" --burn zh_only

# 出力ディレクトリ / ターゲット言語を指定
run "<URL>" -o /path/to/out --target-lang zh-Hans

# 特定のバックエンドを優先(残りはフォールバックとして、「それのみを使用」ではない)
run "<URL>" --translator google
run "<URL>" --asr-engine whisper-api

# このジョブだけ別の LLM モデルを使用(設定は変更しない)
run "<URL>" --llm-model deepseek-reasoner

# 既存のソース字幕を直接使用、認識は実行しない(.srt / .vtt)
run "<URL>" --subtitle-file ./my_subtitles.srt

# ログインが必要な動画
run "<URL>" --cookies-from-browser chrome
run "<URL>" --cookies ./cookies.txt

# 再実行(キャッシュされたフェーズ結果を無視)
run "<URL>" --force

# スクリプトで消費するため
run "<URL>" --json

--only-phase のセマンティクスは 「このフェーズまで」 であり、「このフェーズのみを実行」ではありません——各フェーズは前のフェーズの出力を消費するため、より前のフェーズも実行されます。


成果物構造

<task_dir>/
├── raw/                       # マスターと中間成果物
│   ├── video.mp4              # 標準化マスター(ロスレスストリームコピー、再エンコードなし)
│   ├── audio.wav              # ベースオーディオトラック
│   ├── audio_enhanced.wav     # ASR 専用強調オーディオ(ノイズ低減 + ボーカルイコライゼーション)、完成品では使用しない
│   ├── subtitle.srt           # ソース言語字幕(プラットフォームトラックまたは ASR 結果)
│   ├── transcript.json/.txt   # 構造化台本
│   ├── cover.jpg
│   └── metadata.json
└── cooked/                    # 完成品
    ├── subtitle.srt / .ass    # バイリンガル
    ├── subtitle_zh.srt / .ass # 中国語のみ
    ├── video_bilingual.mp4    # バイリンガルハードサブ完成品
    └── video_zh.mp4           # 中国語のみハードサブ完成品

完成品のオーディオは直接コピー(-c:a copy)で元のマスターから取得されます。強調オーディオは認識専用に使用されます——認識精度と完成品の音質を両立します。


設定

設定の検索順序(後者が前者を上書き):

  1. 組み込みデフォルト
  2. 環境変数:OPENAI_API_KEY、OPENAI_BASE_URL、OPENAI_MODEL、WHISPER_API_KEY、PORTER_ASR_ENGINE
  3. ユーザー設定(porter config list で実際のパスを表示)
  4. プロジェクト設定:カレントディレクトリの porter.json / porter.toml / config.json
  5. --config <path>

完全なキーテーブルは references/CONFIG.md、テンプレートは assets/config.example.json を参照してください。


MCP 経由の使用(オプションだが推奨)

ホストが porter MCP server を設定している場合、シェルよりも優先して使用します:

  • 構造化された結果。stdout の解析が不要(シェルのエスケープとエンコーディング問題も回避)
  • porter_job_start はすぐに戻り、porter_job_status でポーリング。長時間タスクがツールのタイムアウトに衝突しない
  • キー不要の LLM レベル翻訳を取得できる唯一の方法:§8.3 sampling はホストモデルを使用して翻訳。CLI プロセスはホストモデルにアクセスできない

ツール名の対応と設定方法は references/MCP.md を参照してください。

注意:npx skills add はこのスキルディレクトリのみをインストールし、MCP server はインストールしません。新規インストール時は、CLI パスを基準にしてください。


参考ファイル

ファイル内容
references/ARCHITECTURE.md4フェーズパイプライン、プラットフォームとバックエンドのフォールバックチェーン、設計制約
references/CONFIG.md全設定キー、環境変数、優先順位
references/MCP.mdMCP ツール対応表と設定方法
references/HOSTS.mdWindows ネイティブエントリポイントと制限付きホスト事前チェック
assets/config.example.json設定テンプレート

関連スキル