Communitygithub.com

MuhammadToffaha/動画編集

トーク動画をプロ品質のリール/TikTok/ショートに変換します。言葉に同期した字幕(アラビア語RTL、英語)、アニメーションキーワード、インフォグラフィック、カメラパンチイン、ブランドロゴ、効果音、ラウドネス正規化を追加します。また、別の言語への吹き替え(新しい音声とリップシンク)も行います。

動画編集 とは?

このスキルは、ユーザーがアップロードしたトーク動画を、ソーシャルメディア向けのプロフェッショナルなリール/TikTok/ショート動画に自動変換するエージェント機能です。具体的には、ffmpeg、ヘッドレスChromium、GSAPアニメーションエンジン、sherpa-onnx Whisper音声認識を用いて、クラウドサンドボックス内で完全オフライン動作します。編集モードでは、話者の音声や意味を一切変えずに、単語レベルで同期したダイナミックな字幕、発言内容に基づくアニメーションキーワード、タイムラインに合わせたインフォグラフィックやUIカード、カメラパンチイン、ブランドロゴの配置、効果音の追加、ラウドネス正規化を自動実行します。さらに、ダブモードでは、音声認識、テキスト翻訳、話者の声質をクローンしたゼロショットTTS、Wav2LipとGFPGANによる高品質リップシンクまでを一貫して行い、元の動画のフレームに合わせて口の動きを新しい音声に同期させます。すべての判断(ブランドカラー、シーンデザイン、グラフィックの配置など)をエージェントが自律的に行い、ユーザーはアップロードと指示を出すだけで完成品を受け取ることができます。

対応✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/MuhammadToffaha/Video-editing/tree/HEAD/.claude/skills/short-form-video-editor

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

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

ドキュメント

オートパイロット - ユーザーが /short-form-video-editor と入力した場合の動作

ユーザーが動画(およびオプションでロゴ画像)をアップロードし、コマンドを入力します。質問せずに作業全体を実行してください。何かが本当にブロックされた場合(動画が見つからない、ffmpegがないなど)のみ停止します。コマンドの後の追加テキストはスタイル/ブランドのメモとして適用します。

  1. 入力の検索: セッションアップロード内の最新の動画(ls -t /root/.claude/uploads/*/*.{mp4,mov,webm} またはメッセージに指定されたパス)。ロゴ = 添付画像があればそれ(なければ、透かし/ヒーロー/アウトロロゴをスキップし、クリーンなテキストなしのアウトロを使用)。言語 = asr_chunks.py ... auto で自動検出。
  2. ツールキットの特定: このスキルのフォルダ(このSKILL.mdを含むディレクトリ)にtemplate/があります。新しいプロジェクトフォルダで作業:セッション内にVideo-editingリポジトリのクローンがある場合は、その中にprojects/<slug>-<YYYYMMDD>/として作成。そうでなければスクラッチパッドに作成。cp -r template/. <project>/。
  3. 依存関係の確認/インストール(一度だけ): ffmpeg、Node + Playwright Chromium(/opt/pw-browsers、playwright installは実行しない)、pip install numpy pillow sherpa-onnx、scripts/fetch_asr_model.sh。Huggingfaceへのネットワークは不可。GitHubリリース、npm、PyPIは利用可能。
  4. 以下のワークフローを最初から最後まで実行し、自身でデザイン判断を行う(ブランドカラーはロゴから取得。ロゴがない場合はコーラル/ティールのテクニカルパレット。シーンはreference/scene-patterns.mdから、実際の発言に合うものを選択)。
  5. 成果物の提供: SendUserFileでmp4を送信(レンダリング結果を表示)。その後、簡単なサマリー:スペック、追加したグラフィック、低信頼度の文字起こし箇所(耳で確認する必要あり)、映像解像度の注意点、「音声は確認していない」旨を記載。プロジェクト(work/ディレクトリを除く)と最終mp4をリポジトリに保存し、セッションで指定されたブランチ(指定がない場合はmain)にプッシュ。依頼がない限りPRは作成しない。
  6. 60秒の動画で約15〜25分(文字起こし約3分、レンダリング約4分、エンコード約2分)かかると見込む。開始時にユーザーに1行でその旨を伝え、その後は完了まで静かに作業する。

ダブモード - 翻訳 + 新しい音声 + リップシンク(Glowクリップで一度テスト済み:アラビア語→英語)

ユーザーが「口が言葉に合わせて動くように」別の言語での動画を希望する場合に使用。

  1. スクリプト: 編集モードと同様に文字起こしと確認を行い、その後自分で翻訳をdata/phrases.<lang>.jsonとして作成 = [[win_start, win_end, "text with *key words and DISPLAY|spoken overrides (多単語トークン内はNBSP)"], ...]。元のフレーズウィンドウはそのまま維持し、カメラ/グラフィックのビートが生き残るようにする。近接するウィンドウはマージしてもよい。英語の場合、1ウィンドウあたり約2.5〜3語/秒を予算とし、詰め込みすぎず、意味を保持し、新しい主張は追加しない。発音オーバーライドの例:*COSRX|Cosrex、Axis-Y|Axis\u00a0Y。
  2. モデル: scripts/fetch_dub_models.sh(確認用にfetch_asr_model.shも)。
  3. 音声(デフォルト = 話者にクローン): work/ref.wavを作成 = 話者の元の音声からポーズで区切られたクリーンなクリップを4〜5個(約15秒、16kHzモノラル、連結)。python3 -I scripts/tts_clone.py data/phrases.en.json work/ref.wav 8 <total_seconds> -> work/voice_en.wav + 実際の音声スパンを含むdata/transcript.source.json。YourTTS(coqui、fetch_dub_models.shでダウンロード)が音色をゼロショットでクローン。スクリプトは行ごとにNテイク生成し、Whisperの読み返しがスクリプトに最も一致するテイクを保持し、タイムストレッチ(0.72〜1.25倍、ピッチ保持)で元のウィンドウの約90%を埋める。Glowクリップでの実績:中央ピッチ144 Hz(話者154 Hz、ストックKokoro音声123 Hz)、長期スペクトル類似度0.96(対0.90)、全行が正しく読み返される。ブランド名はDISPLAY|spokenで発音を指定し(スコアリングから除外 - 自動)。フォールバックtts_phrases.py = ストックKokoro音声(明瞭だが話者の声ではない)。アクセント:モデルは音色/ピッチを転送するが、ネイティブアクセントは転送しない。「エジプトなまりの英語」を約束せず、達成された内容を説明する。
  4. 元の解像度フレームへのリップシンク: ffmpeg -t <end> -i src -vf fps=30 work/raw/%05d.png; ffmpeg -i work/voice_en.wav -ac 1 -ar 16000 work/en16k.wav; MODELS=work/models python3 -I scripts/lipsync2.py work/raw work/en16k.wav work/ls --model wav2lip_gan_96.onnx --enhance 0.7(最初に--range a bでテスト。4CPUで1700フレームの場合、フル実行約25分:Haarボックス、全フレームの2dfan4ランドマーク、次にフレームごとにWav2Lip + GFPGAN)。lipsync2 = ランドマークアライメント済みFFHQ-512クロップ、スムーズ化ランドマーク、ランドマーク顔ボックス上のWav2Lip、GFPGAN復元を0.7でブレンド、口形状マスク(鼻には触れない)、貼り付け。その後scripts/01b_upscale_lipsynced.sh。古いlipsync.py(粗いHaarクロップ:ぼやけた唇、舌のようなアーティファクト - ユーザーから「非常に悪い」と評価)は使用しない。EDTalk-256も試したがより悪い(幽霊のような口)。モデル:facefusion-assetsのGitHubリリースから2dfan4、gfpgan_1.4、wav2lip_gan_96。
  5. 視覚的同期確認: 各タイルの下にオーディオエンベロープを重ねた口のコンタクトシート。無音ギャップでは口が閉じており、オーディオバーが上がっているときに開いて変化している必要がある。ピクセル相関メトリクスはノイズが多すぎるため、これに依存しない。
  6. グラフィックス: python3 -I scripts/build_transcript.py work/en16k.wav(英語のソースjsonではmax_charsを約22に設定)、composition/transcript.jsを再生成、その後scene.jsのコピーとトリガーワードを新しい言語で書き換え(LTR:.row/.chunkの方向をltr、Interフォント、ストライク原点左、フロー矢印左→右)。多単語トークンは文字起こし内では別々の単語:単一単語を検索(ts('skin',0,43.5))、ts('your skin')は不可。
  7. 通常通りレンダリング(LAST_SRC_FRAME=<n> scripts/02_render_all.sh、キュー、SFX)し、VOICE=work/voice_en.wav OUT=out/name-en.mp4 scripts/03_mix_and_encode.shでミックス。
  8. サマリーで正直に報告: Wav2Lipは約100pxの顔で柔らかくややぼやけた口(近くで見るとわかる)、頭や手の動きは元の話者のまま、音声は合成音声、話者は自分の肖像が吹き替えられたバージョンを承認すべき、AI吹き替えとラベル付けを検討すべき。低信頼度だったソースの翻訳フレーズがあれば名前を挙げる。

ショート動画エディター(キャプション + モーショングラフィックス + SFX)

2つのモード:編集(言語を維持し、キャプション/グラフィックス/SFXを追加)とダブ(別の言語に翻訳、新しい音声、新しい音声に合わせて唇を再アニメーション - ユーザーが英語/翻訳/吹き替え/リップシンクと言ったときに起動)。57秒のエジプトアラビア語薬局プロモーション(Glow Cosmetics)で実証済みのパイプライン。出力:1080x1920 @30、H.264/AAC、-14 LUFS。 動作例プロジェクト:https://github.com/MuhammadToffaha/Video-editing の projects/glow-kbeauty-reel/

「プロフェッショナル、テンプレートではない」を定義するルール

  • 話者、声、意味をそのまま保持する。主張(数値、「100%」、価格)をでっち上げない。グラフィックに話されていないテキストが必要な場合、汎用的なものにする(カテゴリ名、見出しラベル)。
  • すべてのビジュアルは話されたフレーズをサポートし、単語でトリガーされる(ts('word'))。フレーズの開始ではない。カードは次のカードが入る前に終了。重なるゴーストはなし。
  • 1つのビジュアル言語:ブランドカラー(ロゴからサンプリング)+ 白 + ダークインクガラスパネル、ラテンラベルはInter、見出し/キャプションはCairo(アラビア語)。ミントは成功状態のみ。
  • レイアウトゾーン(1080x1920、話者の顔はおよそy 790-1110):カードはy 235-735(1.15倍ズーム後も顔の上には決して重ならない)、キャプションはy~1545、下部220pxと上部130pxは主要コンテンツを置かない(プラットフォームUI)。ソースごとに顔の位置を再確認。
  • 保持デバイス(適度に):文の開始時にはパンチインスナップ(1.12-1.15倍)とその間のゆっくりしたドリフト、2〜4秒ごとにグラフィック、アクティブワードキャプションハイライト、打ち消し線/チェック/カウントアップマイクロアニメーション、ブランド名が言われたときのヒーローロゴモーメント、ブランドエンドカード。
  • SFX:カードイン時にウーシュ、要素にポップ/チック、成功時にチャイム、ロゴにサド。音量は音声の約-10dB。ユーザーが提供しない限り音楽はなし。

ワークフロー

  1. 検査: ffprobe、コンタクトシート(ffmpeg -vf "fps=1/6,scale=239:-1,tile=5x2")、末尾のエンドカード(WhatsApp/CapCutの黒フレーム)を見つけ、話者の位置を記録。ソースは通常低解像度(スマートフォン/WhatsApp):lanczosでアップスケールし、映像はソフトになるがグラフィックはシャープなままであることをユーザーに伝える。
  2. プロジェクト: cp -r <skill>/template/. my-project/ && cd my-project; cp <logo> assets/; python3 -I scripts/extract_logo.py assets/logo_original.png assets/logo_white.png(ブランドの16進コードを出力)。composition/style.cssと#wm/#outroの--coral/--brandを更新。
  3. 準備: END=<トリム秒> scripts/01_prepare.sh input.mp4(フレーム、16kHz wav、音声)。
  4. 文字起こし(サンドボックス内でHFアクセス不可。GitHubリリースは使用可能): scripts/fetch_asr_model.sh。その後
    • python3 -I scripts/asr_chunks.py work/asr16k.wav <lang|auto> 3.2 a、2.4と4.5で繰り返し。Whisperはチャンク末尾を切り捨てる。3つの仮説を自分でマージし、自身の言語知識で修正。
    • 不確かな単語/ブランド名:python3 -I scripts/asr_probe.py work/asr16k.wav ar,en 14.0-16.8 14.5-16.6 ...(enパスはラテンブランド名のスペルを出力)。重複するウィンドウ間で一貫しているもののみ信頼。残りは最終メッセージとREADMEで低信頼度としてリストアップ。推測された名前に基づいてグラフィックを作成しない。
  5. タイミング: python3 -I scripts/pauses.py work/asr16k.wav -> ポーズが信頼できるフレーズ境界。data/transcript.source.jsonを[start, end, "text"]フレーズとして作成(data/transcript.source.example.json参照。*word = アクセントピル。多単語ラテン名内ではNBSPを使用。RTLテキスト内のラテンブランド:アラビア語の接頭辞وをブランドに接着させない、و Brandと記述)。その後python3 -I scripts/build_transcript.py work/asr16k.wavとecho "window.TRANSCRIPT=$(cat data/transcript.json);" > composition/transcript.js。これにより、各フレーズ内の音節重みで単語時間を分配し、エネルギーの谷にスナップさせ、バランスの取れた2〜4単語のキャプションチャンクを作成。健全性チェック:無音内に単語開始がないこと。
  6. シーンのデザイン: composition/scene.jsで(reference/scene-patterns.md参照)。card(t0,t1,{y,h,html})、pop、fade、draw、cue、tsを使用。サンプルシーンをパターンとして使用:フックカード、ブランドチップ(各名前が言われたときに埋まるスケルトンスロット)、カテゴリタイル、移動ドット+チェック付きA→Bマッチ図、打ち消し線チップ、フローノード、星評価、チェックリスト行、ロードマップ、棒グラフ、トラストリング、ヒーローロゴリビール、ブランドアウトロ。finish(<seconds>)を設定 = 音声終了 + アウトロ約1.7秒。
  7. レンダリング + QA: 最初にいくつかのテストフレームをレンダリング(node scripts/render.mjs <f> <f+1> work/test)、Pillowでコンタクトシートを作成し、確認。その後scripts/02_render_all.sh(4ワーカー、合計約8 fps)、node scripts/render.mjs cues work/cues.json && python3 -I scripts/sfx.py work/cues.json work/sfx.wav、OUT=out/name.mp4 scripts/03_mix_and_encode.sh。ソースがエンドカードで終わる場合、LAST_SRC_FRAME=<n>を渡して最後のクリーンなフレームでフリーズ。
  8. 成果物の提供: mp4を送信(SendUserFile)、スペック、低信頼度の文字起こし箇所、映像解像度の限界、および音声は耳で確認していない(聞くことができない)こと - ラウドネスメーターと開始対エネルギーテストのみで確認したことを記載。

すでに解決済みの落とし穴(再学習しないこと)

  • Pythonのstr.split()はNBSPで分割する - split(' ')を使用(build_transcript.pyでは既にそうなっている)。
  • SVG <rect>のアニメーションにCSS scaleYを使用すると、ヘッドレスChromiumで反転/オフセットする - 代わりにattr:{y,height}をトゥイーンする。ストローク描画:draw(path,t,d)。
  • 非表示で開始する要素にはCSS opacity:0(クラスhid)とimmediateRender:falseのトゥイーンが必要。すべてのトゥイーンはシーク可能でなければならない(ワーカーは開始フレームに直接ジャンプする)。
  • backdrop-filter付きのカードは、ビデオフレームが同じページ(#bg img)にある場合のみブラー効果がかかる - そのためフレームはページ内で合成される。
  • 空のブラーカードは壊れて見える:トリガーワードでカードを開始するか、話されたときに光る薄暗いプレースホルダー行/スロットを表示する。
  • アラビア語には実際の形状が必要:Chromium + Cairo woff2(unicode-rangeでアラビア語/ラテン語を分割)は機能する。Pillow/ffmpegのdrawtextは機能しない。
  • sherpa-onnxのWhisperには単語タイムスタンプがなく、末尾を切り捨てる。そのため短いウィンドウ+ポーズアンカリングが必要。
  • opencv 5.xにはCascadeClassifierがない(4.10.0.84に固定)。Haar顔ボックスは手/シャツに誤検出があり、約30%のフレームを見逃す -> 中央値ボックス外れ値除去+ROIセカンドパス+補間(lipsync.pyでは既に実装済み)。
  • Kokoro/WhisperスタイルのTTSはCOSRXを「シーオーエスアールエックス」と読み上げる:DISPLAY|spokenオーバーライドを使用。
  • GitHub MCP create_repositoryは403になる可能性がある - ユーザーにリポジトリを作成してもらい、その後add_repo + クローン(パスが存在する場合は新しいディレクトリにクローン)。

関連スキル