Communitygithub.com

ericrisco/rsc-harness

生の9:16素材をポスト可能な縦型ショート動画に編集します。無音除去、高速ジャンプカット、文字起こしからの歌詞字幕焼き込み、ビートに合わせたカットとズーム、UIにかぶらないセーフエリア配置、プラットフォーム対応のMP4出力を行います。スクリプトやフック、キャプション文章は作成せず(`video-shorts`の役割)、RemotionのReactコンポジションも構築せず(`remotion-video`の役割)、投稿タイミングの決定もしません(`social-publisher`の役割)。

rsc-harness とは?

このスキルは、生の映像素材(トーキングヘッド、スクリーン録画、ナレーション、Bロールなど)を受け取り、ポスト可能な縦型ショート動画(1080x1920)に編集する技術スタックです。具体的には、ffmpegとWhisperXを用いた再現可能なパイプラインを提供し、無音除去、ビート同期カット、単語単位の強制アライメントによる歌詞風字幕の焼き込み、プラットフォーム対応のH.264 MP4エクスポートを自動化します。このスキルは、あくまで映像のカット・キャプション・出力に特化しており、脚本やフックの執筆は`video-shorts`、Reactベースの動画構築は`remotion-video`に委ねます。主な対応プラットフォームはClaude Code, Cursor, CodexなどのAIエージェントで、CapCutやRemotionといった代替ルートへの言及も含みます。成果物は`ffprobe`で検証可能なMP4ファイルと、カットリスト、ASS/SRT字幕、ビートグリッドなどの中間成果物です。

対応✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/ericrisco/rsc-harness/tree/HEAD/skills/shortform-editing

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

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

ドキュメント

ショートフォーム編集 — 素材を投稿可能なショート動画にカットする

あなたは編集室の技術者です。 誰かが本物の映像(トーキングヘッドのテイク、スクリーン録画、ナレーション、Bロールなど)を差し出し、あなたはそれをポスト可能な縦型ショート動画に仕上げます。無音を除去し、カットは高速に、字幕は単語単位で焼き込み、モーションはビートに合わせて、規定通りの出力を行います。あなたはピクセルとタイミングをエンコードします。言葉を書いたりフックを選んだりはしません。

厳格基準は検証可能なファイルです:焼き込み字幕入りの1080x1920 H.264 MP4で、ffprobeで確認できること。さらには中間成果物(カットリスト、.ass/.srt、ビートグリッド)も含みます。ffprobeで結果を確認し、仕様を満たしていなければ完了ではありません。

スコープ:3つのスキルが「縦型動画」に関わる — 自分の役割を理解せよ

依頼内容担当先成果物
脚本、フック、ビート、画面上のキャプションテキスト、編集決定シートを作成する../video-shorts/SKILL.md.md 脚本ファイル
実映像をカット/キャプション/出力する(ツール非依存)ここ編集済み .mp4 + キャプション/カットファイル
Remotion React コンポジションプロジェクト(<TransitionSeries>、ヘッドレスレンダリング)を構築する../remotion-video/SKILL.md.tsx プロジェクト

ワンライナーのルーティング:映像入力 → カット、キャプション、出力 → このスキル。 言葉や計画 → video-shorts。Reactコードベース → remotion-video。この3つの中でツールポータブルなのはあなただけです。

最初にルートを選べ

ツールを選ぶ前にカットを始めてはいけません。選択は「誰が実行するか」と「再現性が必要か」に依存します。

状況ルート理由
再現可能 / バッチ / CI / 「これを40クリップに適用」ffmpeg + WhisperXスクリプト可能、決定論的、GUI不要 — 同じ入力、同じ出力
リポジトリがすでにRemotionプロジェクト@remotion/captions既存のコンポジショングラフを再利用;シェルアウトしない
人間が1本の動画を手作業で仕上げるCapCut クリックパス単一の手動パスで最速、自動キャプション+自動ビートマーカー機能付き

このスキルの残りの部分はffmpeg + WhisperX パイプライン(再現可能なパス)であり、RemotionとCapCutのルートは違いがある箇所で注記します。長いコマンドブロックは references/ffmpeg-pipeline.md に、キャプションの詳細は references/captions.md にあります。

再現可能なパイプライン(順序通り)

これが骨子です。上から下に実行し、各ステップが次のステップにデータを渡します。

1. 文字起こし用にクリーンなモノラル16kHzオーディオトラックを抽出する。

ffmpeg -i in.mp4 -vn -ac 1 -ar 16000 a.wav

理由:モノラル16kHzはWhisperモデルが期待する形式です。ステレオ48kHzを入力すると時間を浪費し、精度に変化はありません。

2. 単語レベルのタイムスタンプで文字起こしする。 セグメントのタイムスタンプだけでは不十分です。単語ごとのキャプションには単語ごとのタイミングが必要です。

whisperx a.wav --model large-v3 --output_format json --highlight_words True

WhisperX(v3.8.5)はfaster-whisperにwav2vec2の強制アライメントを組み合わせ、100ミリ秒未満の精度で単語タイミングを提供します。これはカラオケハイライトの最低限の精度です。faster-whisper単体でも word_timestamps=True で動作しますが(約10%のオーバーヘッド)、単語境界のズレが大きくなります。理由:強制アライメントが必要な理由 — Whisperのネイティブ単語タイムスタンプは補間されておりジッターが発生しますが、強制アライメントは各単語を音声に正確に固定します。 インストール方法とJSONの構造については references/captions.md を参照してください。

3. 無音を検出し、ビデオとオーディオを一緒にカットする。 これが多くの人が間違えるステップです。

# パス1:無音範囲を検出する(発話しきい値)
ffmpeg -i in.mp4 -af silencedetect=noise=-25dB:d=0.3 -f null - 2> silence.log

silenceremove を単体で使うとオーディオのみのフィルターであり、ビデオが非同期になります — 決してワンショットで使わないでください。silence.log から silence_start / silence_end の行を解析し、保持範囲に反転させ、両方のストリームから同じ範囲を削除する select + aselect フィルター(または trim+concat グラフ)を構築します。しきい値:発話 noise=-25dB:d=0.3;音楽 noise=-40dB:d=1。フィルター生成のスニペットは references/ffmpeg-pipeline.md にあります。

4. ビートグリッドを構築する(音楽に合わせてカットする場合のみ)。

python -c "import librosa; y,sr=librosa.load('music.wav'); \
_,b=librosa.beat.beat_track(y=y,sr=sr,units='time'); print(*b,sep='\n')" > beats.txt

beats.txt はビート時間(秒)のリストです。CapCutはこれらのマーカーを波形に自動的に配置します。librosa(またはaubio)はスクリプトで同じグリッドを提供します。

5. カットポイントとズームキーフレームを最も近いビートにスナップする。 各カット時刻を beats.txt 内の最も近い値に丸めます。ビートに合わせたズームパンチはエネルギーを感じさせます。ビート同期の「使用すべきでない場合」については後述します。

6. カラオケ .ass キャプションを焼き込む。

ffmpeg -i tightened.mp4 -vf "ass=captions.ass" -c:a copy captioned.mp4

.ass は、ステップ2の単語タイムスタンプとセーフゾーンマージンから構築された単語ごとの \k タイミングを保持します。生成の詳細とテンプレートは「カラオケキャプション」セクションにあります。

7. プラットフォームマスターをエクスポートする(「出力仕様」を参照)。

カラオケキャプション

単語ごとのキャプションが特徴的なルックです。セグメントタイムスタンプではなく、単語タイムスタンプから構築してください。

  • タイミング。 各単語の画面上のハイライトは、強制アライメントによる開始/終了時刻から来ます。.ass では、\k<センチ秒> タグが単語ごとにカラオケフィルを進めます。セグメントタイミングから単語ごとに作成するとジッターが発生し、間違った単語にハイライトが当たります — 常にステップ2の単語ごとのタイムスタンプを使用してください。
  • 無音視聴での可読性。 大きく太いサンセリフ体、太い輪郭/ストローク、必要に応じてドロップシャドウ。人々はミュートで見ています:一目で読めない場合、スマホでは失敗です。画面上で一度に2行以内 / 約6単語以内に抑えてください。
  • セーフゾーン — 見落としがちな点。 キャプションは縦方向の中央帯に配置し、下部には配置しないでください。プラットフォームのUI(右側のアイコン、下部のキャプション/CTA/プロフィール)は、下部の約15~20%と右端を覆います。キャプションとキーテキストは、1080x1920 フレームの中央約80%に収めてください。下部に焼き込まれたキャプションはTikTokのボタンの後ろに隠れます — これが「キャプションが壊れている」という最も多い原因です。

最小限の .ass スタイルブロック(完全なテンプレートは references/captions.md にあります):

[V4+ Styles]
Style: Karaoke,Montserrat,64,&H00FFFFFF,&H0000FFFF,&H00000000,&H64000000,-1,0,0,0,100,100,0,0,1,5,2,5,80,80,640,1

末尾の 640 が行を中央帯に持ち上げます。太い Outline(5)はどんな背景でも可読性を保ちます。

Remotion ルート: Remotionプロジェクト内であれば、@remotion/captions — createTikTokStyleCaptions({ captions, combineTokensWithinMilliseconds }) を使用してトークンをページ分割します。低い値(200~500 ms)は単語ごとのポップ、高い値(1200~2000 ms)はフレーズ単位のページになります。 durationMs はv4.0.261で追加されました。 CapCut ルート: テキスト → 自動キャプション → 生成、その後スタイル変更。

ビート同期

ビートグリッド(ステップ4)は秒のリストです。カットポイントとズームキーフレームを最も近いビートにスナップして、モーションが音楽に合うようにします。

  • 悪い → 良い。 単語の途中でカットをビートに正確に合わせると、ミスと認識されます → カットを、発話境界も尊重する最も近いビートに微調整してください。ビートよりも言葉を優先してください。
  • ビートカットをすべきでない場合。 言葉が価値を伝えるトーキングヘッドの説明動画では、明瞭さがリズムに勝ります。人の話の途中でビートカットすると、その人の話し方が途切れます。ビート同期はBロールのモンタージュ、トランジション、音楽主導のセグメントにのみ使用してください。
  • トランジションは安く、速く。 ハードカットがデフォルトです。ビートに合わせてのみ、ウィップパンやズームパンチを使用します。30秒のショート動画で1秒のクロスフェードは避けてください — ペースを殺します。ショートは高速なハードカットで成り立っています。

出力仕様

ユニバーサルな縦型マスター — 3つのプラットフォームすべてでクリーンに再生される1つのファイル:

ffmpeg -i captioned.mp4 \
  -vf "scale=1080:1920:force_original_aspect_ratio=decrease,pad=1080:1920:(ow-iw)/2:(oh-ih)/2,setsar=1" \
  -c:v libx264 -profile:v high -pix_fmt yuv420p -r 30 \
  -c:a aac -b:a 192k -ar 48000 -ac 2 \
  -movflags +faststart out.mp4

yuv420p(広範な再生互換性)、+faststart(Webストリーミングで完全ダウンロード前に再生開始)、AAC-LC 48kHz。30fpsを使用。高モーションのショートでは60fpsに上げてください。

プラットフォームビデオビットレート備考
TikTok約2,000~4,000 kbps3つの中で最も軽い
Instagram Reels約3,500~4,500 kbps
YouTube Shorts (1080p)約8,000~15,000 kbps4K/60で約53,000 kbpsまで

単一の 1080x1920 H.264 MP4 @30 fps で 約250 MB以下 であれば、どこでも安全です。 出荷前に検証してください:

ffprobe -v error -select_streams v:0 \
  -show_entries stream=width,height,codec_name,avg_frame_rate out.mp4

width=1080 height=1920 codec_name=h264 が期待値です。完全なプラットフォームごとのエンコードフラグと ffprobe アサーションは references/ffmpeg-pipeline.md にあります。

アンチパターン

悪い例なぜ壊れるか良い例
silenceremove をワンショットフィルターとして使用オーディオのみ;ビデオは再生を続ける → 音声/映像の同期ずれsilencedetect → 保持範囲に反転 → select+aselect で両方のストリームをカット
セグメントタイムスタンプから単語キャプションを作成ハイライトがジッターし、間違った単語に当たる強制アライメントによる単語ごとのタイムスタンプ(WhisperX / word_timestamps)
キャプションを下部15~20%に焼き込むプラットフォームUI(ボタン、CTA、プロフィール)が隠す縦方向の中央帯、中央約80%に配置
1つの出力をすべてのプラットフォームで使い回すどこかでビットレートが不足/超過するプラットフォームごとのビットレート、または安全なユニバーサルマスター
30秒のショートで1秒のクロスフェードペースを殺し、遅く感じられるハードカット;ビートに合わせてのみウィップ/ズーム
トーキングヘッドの話の途中でビートカット話し方が途切れ、明瞭さを失うBロール/モンタージュのみビート同期;発話境界を尊重
「仕様確認」のためにエンコードを再実行数分を浪費;ファイルはすでに存在するffprobe で出力を検証;再レンダリングではなく確認
ここでキャプションのコピーやフックを書くそれは脚本であり、カットではない../video-shorts/SKILL.md にルーティング;あなたは焼き込むだけ
ffmpeg で元のファイルを上書き1つの誤ったフラグで元のファイルが消失常に新しいファイルに書き込み、in.mp4 はそのまま残す

検証とリファレンス

  • bash scripts/verify.sh <output.mp4> — ffprobe を実行し、width=1080、height=1920(9:16)、ビデオコーデック h264、オーディオコーデック aac、fpsが {30, 60} のいずれかであること、および関連する .srt/.ass キャプションファイルが存在し空でないことをアサートします。ffprobe がない場合はパス/拡張子チェックにフォールバックします。読み取り専用で、空の/クリーンなターゲットに対しては終了コード0を返すため、偽の失敗は起こりません。「ビートに乗っているか」の判断は機械的なものではなく、能力評価に委ねられます。
  • references/ffmpeg-pipeline.md — 無音検出 → 保持範囲反転 → ビデオ+オーディオを同時にカットする select/aselect フィルター生成の完全版、concat/trimアプローチ、プラットフォームごとのエンコードフラグ、ffprobe アサーション、および非同期/オーディオドリフト/faststartのトラブルシューティング。
  • references/captions.md — WhisperXのインストールと実行、単語タイムスタンプJSONの構造、セーフゾーンマージン付きの完全な .ass カラオケテンプレート、combineTokensWithinMilliseconds ガイダンス付きのRemotion createTikTokStyleCaptions() スニペット、およびfaster-whisperとWhisperXのトレードオフ。

Individual skills in this repo

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

ericrisco/rsc-harness

Use when writing the words on a single conversion page — the hero headline and subhead, the offer, the proof and testimonials, and one primary CTA — or diagnosing a page that gets traffic and does not convert, as a copy problem rather than a layout one. NOT the paid ad that drives the click (that is `ads`), NOT the visual layout the words sit in (that is `design`), NOT the experiment that picks the winning variant (that is `ab-testing`).

ericrisco/rsc-harness

Use when you need to render an actual video file with Remotion — React compositions, the Composition/Sequence/TransitionSeries graph, transitions, burned-in word-by-word captions from a transcript, automatic silence removal, b-roll overlays, headless CI renders, and a final MP4 or MOV. NOT writing the script, hook, beats or caption text (that is `video-shorts`), NOT mastering audio to LUFS or building an RSS feed (that is `podcast`), NOT structuring the narrative arc (that is `course-storytelling`).

ericrisco/rsc-harness

Use when a Reels/TikTok/Shorts account needs its next video ideas scored into a ranked backlog, grounded in its own performance log plus dated trending sounds, each bet logged so its outcome feeds the next batch. NOT scripting a chosen idea (that is `video-shorts`), NOT pillars or cadence (that is `shortform-strategy`), NOT packaging a finished cut (that is `shortform-packaging`).

ericrisco/rsc-harness

Use when a vertical short is shot or scripted and you need the upload-form copy and cover that win the feed — the hook line, the first-frame on-screen text, the search-led caption, a tight hashtag set, and the cover frame; it learns from what performed via the 02-DOCS log. NOT inventing the idea (that is `shortform-ideation`), NOT scripting or directing the cuts (that is `video-shorts`), NOT executing the edit (that is `shortform-editing`), NOT scheduling the post (that is `social-publisher`).

ericrisco/rsc-harness

Use when the unit of work is a TikTok/Reels account, not one clip: positioning, sustainable cadence and format mix, ride-or-skip on a trend or sound, recurring series, diagnosing a flat account, and the dated learning loop. NOT the single script or hook variants (that is `video-shorts`), NOT the idea backlog (that is `shortform-ideation`).

ericrisco/rsc-harness

Use when planning a posting schedule, building a multi-platform content calendar, or reshaping one source asset into channel-native posts across X, LinkedIn, Instagram, Threads, Bluesky, TikTok, Facebook or YouTube — cadence, best-time slots, per-platform format limits, API publish caps, and a dated CSV or JSON calendar a scheduler can import. NOT the brand voice the posts speak in (that is `brand-voice`), NOT the editorial strategy of what to make (that is `content-engine`).

ericrisco/rsc-harness

Use when connecting a real TikTok account to code via the Content Posting, Display and Business Account APIs — OAuth, chunked video publish with status polling, and pulling views, watch time and impression sources, then logging that performance into the wiki as a dated feedback record. Covers short-lived tokens breaking a cron, unverified pull-from-URL ownership, and rate limits. NOT what to post or how to package it (that is `shortform-strategy` and `shortform-packaging`).

ericrisco/rsc-harness

Use when scripting or directing the edit of a single vertical short that has to hold attention from the first frame — turning a topic, a clip or a long video into a shot-by-shot script and an edit decision sheet, fixing a hook that dies in second three, generating hook variants to test, and planning cuts and on-screen text. NOT scheduling or cross-platform cadence (that is `social-publisher`), NOT running the editorial calendar (that is `content-engine`), NOT defining the durable brand tone (that is `brand-voice`).

ericrisco/rsc-harness

Use to judge whether a short-form clip is worth publishing — scores a reel, short or podcast excerpt 0-100 on ten weighted criteria with automatic penalties, then ranks a batch and says where the cut-off falls. Run it on transcript candidates before rendering. NOT writing the hook or caption (that is `shortform-packaging`), NOT inventing the idea (that is `shortform-ideation`), NOT executing the edit (that is `shortform-editing`).

関連スキル