overlays:音声に同期したグラフィックをPremiereに配置
2つのスキル、1つのワークショップ
こちら (overlays):配置と編集 | ワークショップ (motion-design):制作 |
|---|---|
トランスクリプト、.prprojのタイムライン、フレーズアンカーとして書かれた計画 | 唯一のRemotionプロジェクト:motion-design/src/、src/illustration/内のオーバーレイコンポジション(BrandedVideo、LowerThirdTrack、Screencast、Scene、FondAnime) |
ソーシング:写真、Bロール、GIF(gifs.py)、ウェブキャプチャ、メールカード(mail-cards.py) | public/:フォント、scenes/<video>/(シーンメディア)、sfx/(音声) |
サイトデモの録画(screencast-record.py) | テーマ(src/illustration/theme.ts)、サウンドパレット(reference/sound-palette.md、scripts/make-sfx.py、scripts/son.py) |
render-segments.py、screencast-render.py、montage-tella.py:ワークショップ内でレンダリングを開始し、すべてをPremiere XMLに配置 | 音楽、ミックス |
2つのフォルダは隣接している必要があります(<skills>/overlaysと<skills>/motion-design)。スクリプトは../motion-designを通じてワークショップを見つけます。新しいシーンコンポーネントはmotion-design/src/illustration/scenes/に記述され、新しいサウンドはワークショップのシンセレシピに追加されます。
インストール(マシンごとに1回、プラグインインストール):bash "${CLAUDE_PLUGIN_ROOT}/install.sh" --data "${CLAUDE_PLUGIN_DATA}"。
手動で行う場合、4つのスキルフォルダを隣接してコピーし、キットのルートからbash install.shを実行します。プラグインアップデート後、ワークショップのnode_modulesリンクは解除されるため、セットアップ行を再実行してください。詳細はキットのINSTALL.mdを参照してください。
編集の黄金律(デフォルト設定、チャンネルに合わせて調整)
動画は音声によって支えられます。グラフィックは述べられた内容を再説明するのではなく、そうでなければ感じるだけだったもの(固有名詞、引用、場所、タイトル、数字)をアンカーするか、話題になっているものを表示します(ドキュメント、サイト、図表)。
2レベルの装飾:
- 軽め:チャプターごとに1つのプレミアム+45〜60秒ごとに1つのローワーサード。イントロ(0〜30秒)と結論部分を除く。
- 密(デモ、調査、チュートリアル動画):映像の60〜70%にアニメーションシーン。各シーンは音声に同期。3秒以上モーションがないシーンは不可。トーキングヘッドの位置は維持。
指定がない場合は希望レベルを尋ねてください。デフォルトではアニメーション化しないこと:イントロ(視聴者は残るかどうかを決める)、親密な逸話(アニメーションは感情を殺す)、サスペンスを高める質問、結論とコールトゥアクション、形容詞のリスト。
カメラで発言されたスクリプトからの逸脱(数字、用語、概算)は画面上で修正します:ラフカットはそのレポートでフラグを立て、計画は新しいテイクを求めずに正しい値を音声に合わせて配置します。
ルール0:基準タイムラインはPremiereプロジェクトであり、ラフカットではない
順序は常に:ラフカット(rough-cut) -> 編集者がPremiereで編集をレビューし変更する -> オーバーレイ。この2つの間に、カットは移動し、クリップは削除され、長さは変化します。ラフカットで計算された時間は30秒から1分ずれ、要素が動画の終了後に配置されることがあります。
ラフカット後はハードストップ。たとえユーザーが「ラフカットしてからオーバーレイ、あなたに任せる」と言ったとしても、ラフカットXMLを納品し、ユーザーがPremiereでそれを承認するまで待ちます。それ以前は、計画も時間も配置も行いません。時間に依存しないもの(画像やGIFのソーシング)だけは先に進めることができます。
python3 scripts/timeline-from-prproj.py "/path/clip.MOV" --list # どのシーケンスがクリップを持つか
python3 scripts/timeline-from-prproj.py "/path/clip.MOV" --sequence "Derush_v1"
# -> <clip>_transcription.json(SEQUENCE時間内の単語)+ <clip>_timeline.json(クリップ -> シーケンスのマップ)
選択したシーケンス内のフッテージのクリップを読み取り(tick = 254016000000/s)、<clip>_Derush_vN_work/words_premiere.json(プロジェクトのトランスクリプト、すでにラフカットで再調整済み)の単語を引き継ぎます。複数のシーケンスがクリップを持つ場合、推測は拒否(コード2)し、どれかを尋ねます。1つのシーケンスに複数のクリップがある場合:すべてを順番に渡します(A.MOV B.MOV --sequence "...")。各タイムラインエントリと各単語はmediaを持ち、出力は最初のクリップの名前を取ります。クリップの先端でカットされた単語は、クリップ内で開始している場合(カットの少なくとも80ミリ秒前)は保持されます。完全にカットされた単語は、それを狙うアンカーを壊します:アンカーを前の単語 + offsetに移動します。最後に配置された要素がシーケンスの実際の終了前に残ることを確認してください。
ラフカットのcuts_final.jsonやマップを再利用しないでください。Premiereプロジェクトがない場合(クリップのみ):python3 scripts/transcribe.py "/path/clip.mp4"(ローカルwhisper.cpp、Apple Siliconで15分のフッテージに約5分)。
ユーザーが編集を返却したら、まず比較を実行してください:彼らがPremiereで行った変更は最も信頼できるフィードバックです。彼らのシーケンスをラフカットXMLと比較し、繰り返されるギャップを修正、チェック、ルールに変換し、その後でのみオーバーレイ計画を記述します。ユーザーが最終編集を承認したら、納品されたオーバーレイXMLでも同じことを行います:削除、移動(2フレーム以上)、リサイズ、追加(V1に貼り付けられた独自のフッテージはカウントしない)されたものは、修正、チェック、ルールになります。何も削除または移動されていない場合、その納品方法は正しい:維持します。
パイプライン
0.(オプション)Bロール
クリップの隣にあるBrolls/フォルダ、ファイル名はNN_description_K.mp4(番号、説明、バリアント):
python3 scripts/match-brolls.py "/path/clip.mp4" # -> <clip>_broll-script.json(記入用)
各Bロールについて:バリアント(file)、時間(timecode MM:SS、トランスクリプトで確認)、durationSec(null = ネイティブ長)。V2に配置します。サイトデモより前に実行してください(--forceでファイルを上書き)。選択前にバリアントのコンタクトシートを確認してください(ファイル名はしばしば嘘をつきます:「street-photography-portrait」が夜の都市のドローンショットだったなど)。話者が文字通り示していない文にBロールを配置しないでください。Bロールが再生されている間はオーバーレイサウンドを追加しないでください。
0 bis.(オプション)イラスト写真
人、作品、書籍、場所を引用する動画の場合:
- マニフェスト:動画のスクリプトから ->
illustrations-manifest.json:参照スクリプトは任意の形式(テキスト、Markdown、ドキュメント)で可能:正しい綴りと表示すべきものを提供します。{"version": 1, "dest": "Illustrations", "items": [ {"n": 1, "categorie": "reference", "nom": "First Last", "sujet": "portrait", "url": "https://...", "fallback_urls": [], "note": "source: ..."}]} - URL:まず無料ソース(Wikimedia Commons、公式サイト、オープンアクセス博物館)、次に
python3 scripts/serp_images.py "Name Title" --num 5 --min-width 1200(SerpAPI経由のGoogle画像検索、キーSERPAPI_API_KEY)。画像が正しいか確認してください(サムネイルを見て、ページタイトルだけを見ないこと;オークションロットページは罠です)。動画が販売される場合は権利を確認してください。 - ダウンロード:
python3 scripts/source-illustrations.py illustrations-manifest.json->Illustrations/NN-category-name-subject.ext(バイト確認、幅測定;URLがない場合は終了コード1)。 - タイミング:
python3 scripts/match-photos.py "/path/clip.mp4"-><clip>_photos-script.json。時間はトランスクリプト内の名前のあいまい検索で事前入力されます(音声認識は固有名詞を歪めます)。常に各時間をトランスクリプトと照らして手動で再確認してください(あいまい検索は最初の言及ではなく後の言及を取ることがあります);enabled: falseで写真を削除します。写真はV3に配置され、Bロールより優先されます(写真と重なるBロールはXMLから削除され、ログに記録されます)。
写真処理:決してクロップしない(ネイティブ比を維持、縦長はそのまま)。写真は無地の背景に配置され、四方に余白があります(フレームの約86%)、上下端に触れる全画面フィットではありません。マニフェストに.webpを含めないでください(PremiereはXMLで長さ0のメディアとして読み取ります:sips -s format jpegで変換)。幅800ピクセル未満の写真はぼやけます:render-segments.pyがLOW RES警告を出力しますので、納品前にリストを確認してください。シーンで表示される書籍の表紙は、ウェブから取得した出版社のビジュアル(公式サイト、HDモックアップ)でなければならず、話者自身のフッテージから引き出した画像ではありません。
話者が物体を表示している場合、何もそれを覆ってはいけません。 トランスクリプトをスキャンして、「こちら」「ご覧のとおり」「これ」「見て」といった、作品への言及付近のフレーズを探します:話者は本やカメラをレンズに向けて持っています。その時間帯には全画面写真を配置しないでください(編集者は納品された編集からそのようなカバーをすべて削除しました);カバーはデモの前か後、またはまったく配置しないでください。
0 ter. GIFとミーム(基本、オプションではない)
2〜4分ごとに1つのGIF。ムードや自己嘲笑の瞬間(「これは非常に難しい」「全部作り話です」)に使用。イントロには決して使用せず、技術的な文章を文字通り説明するためには使用しません。gifシーン(オーバーレイ、白枠、ループ)で、単語に合わせて到着し、効果音が付きます。
python3 scripts/gifs.py chercher "that's a bug" --planche gifs-sheet.jpg # リスト+番号付きコンタクトシート
python3 scripts/gifs.py prendre <id> --nom bug --public <video> # ソースMP4+シーンのデータ
選択前にコンタクトシートを確認してください(GIPHYのタイトルは内容を示しません;英語での検索がより効果的です)。prendreはMP4(.gifではない)をIllustrations/gifs/にダウンロードし、gifs.json(すべてのGIFのソース)を保持し、motion-design/public/scenes/<video>/gifs/にコピーし、gifシーンのdata(src、srcW、srcH、loopSec)を出力します。キーGIPHY_API_KEY(無料)。GIFはしばしば保護された作品を再利用します:販売される動画では控えてください。
1. フレームレートとクリップのフォーマット(重要)
ffprobe -v error -select_streams v:0 -show_entries stream=r_frame_rate,width,height -of csv=p=0 "/path/clip.mp4"
render-segments.pyはJSONで指定されていない場合、クリップのレートとサイズを読み取ります。30のJSONを60のクリップで使うと、すべてが2倍ずれます。29.97の場合、nシーケンスフレームはn x 1.001 / 30秒続き、各レンダリングはクリップをカバーする必要があります(tailFramesとTenirFinコンポーネントが処理します)。クリップはそのメディアのレートで記述されます:Premiereは<in>を29.97(<file>のレート)で読み取り、クリップの<rate>ではありません;スクリプトは<ntsc>TRUEでin = round(t x fps x 1000/1001)を書き込みます。
縦9:16(リール):同じパイプライン、同じJSON。ローワーサードは縦を検出し、キャプションゾーンの上に移動します;写真はそのまま残ります(背景に帯);16:9のBロールは幅を埋めるスケールになります。リールルール(納品と最終編集の比較から):写真は2〜3秒(デフォルト2.5)、ローワーサードは関連するポートレート写真と同じ長さで、それと同時に開始、ストックBロールは要求がない限り使用しない、話者が物体を示している間はカバーを配置しない。常に1つのローワーサードを静止画としてレンダリングし、グレーフレームに合成してシリーズ前に縦レイアウトを確認します。
2. 提案前に読む
トランスクリプト全体を読んでください。特定:人の名前(ローワーサード「nom」)、作品のタイトル(「oeuvre」)、場所(「lieu」)、用語や動き(「term」)、強い引用(プレミアムquote-full)、パートの区切り(section-titleまたはチャプターカード)、印象的な数字(statシーン)、話題になっているドキュメント、やり取り、サイト(証明シーン、デモ)。引用されたすべての名前、作品、本はどこかに表示されているか(ハンギングシーン、写真、カード)、表示されない理由が記述されている必要があります。各図の内容は話者自身の言葉で読んでください(トランスクリプトを再読)、解釈しないでください:誤った図(ファネルの間違ったレベルに配置されたプロファイル)は言い換えから生じます。
3. すべてのプレミアムは一文で構想する
「何を見たいか:文は大きく、イタリック、左にアクセントルール、帰属は小さく。」説明が「テキストが表示される」の場合、それはプレミアムではありません:ローワーサード、または何もなし。
4. 基本カタログ
| タイプ | コンポーネント / 種類 | トラック | データ | 長さ |
|---|---|---|---|---|
motion(全画面プレミアム) | quote-full | V5 不透明 | text、author?、source? | 10〜14秒 |
lower-third | lower-third-nom | V6 アルファ | name、years?、tag? | 6秒 |
lower-third | lower-third-oeuvre | V6 | title、author、year? | 6秒 |
lower-third | lower-third-lieu | V6 | place、date | 6秒 |
lower-third | lower-third-term | V6 | term、subtitle? | 6秒 |
section-title | V6 | eyebrow?、title | 4秒 | |
scene | 「アニメーションシーン」参照 | V5 / V6 / V7 | data、cues | 音声に従う |
名前とその作品が10秒以内に引用された場合:作品をtagに持つ単一の「nom」ローワーサード。話者自身による引用:quote-full、authorなし(声が署名)。アニメーションは最後の18フレームにわたる自動フェードアウトで終わります。
5. 単語単位の時間(重要)
決して推定しない:<clip>_transcription.jsonで単語を調べ、そのstartを取ります。要素は単語の開始時に表示されます(ローワーサードは最大0.5秒先行してもよい;文の開始に同期すると、早すぎるアナウンスと読まれます)。render-segments.pyは有効な時間なしのセグメントを拒否し、すべての時間をトランスクリプトと照らしてチェックします(OK / WARN / UNKNOWN)。JSONのフレームレートも確認してください(ステップ1)。
6. 記述前に計画を提示する
| # | 時間 | 長さ | タイプ | コンポーネント | 理由 |
|---|---|---|---|---|---|
| 1 | 01:24 | 6秒 | lower-third | lower-third-nom | First Lastの最初の言及 |
| 2 | 02:14 | 12秒 | motion | quote-full | パート1のピボット引用 |
JSONの記述とレンダリングの前に承認を待ちます。
7. レンダリングとインポート
(cd ../motion-design && npm ci) # 1回のみ
python3 scripts/render-segments.py "/path/clip.mp4" # すべて:レンダリング+XML
python3 scripts/render-segments.py "/path/clip.mp4" --lower-thirds-only
python3 scripts/render-segments.py "/path/clip.mp4" --photos-only
python3 scripts/render-segments.py "/path/clip.mp4" --scenes scenes.json --dry-run
スクリプトは各セグメントをレンダリングし、motion-design/public/scenes/<video>/に書き出し、すべてのセグメントを参照するPremiere XMLを生成します。.prprojにインポートするには:Premiereで「ファイル」→「インポート」でXMLを選択し、シーケンスとして読み込みます。--dry-runは、実際にレンダリングせずにセグメント時間とコンポーネントを検証します。
8. サイトデモの自動録画
python3 scripts/screencast-record.py "https://example.com" --duration 15 --output demo.mp4
指定されたURLのサイトを録画し、指定された長さ(秒)の画面キャプチャを生成します。出力ファイルはIllustrations/screencasts/に保存されます。録画はブラウザのデフォルト解像度とフレームレートを使用します。
9. メールカード
python3 scripts/mail-cards.py "subject" "body text" --from "[email protected]" --to "[email protected]" --output card.png
メールの内容を視覚的に表現したカード画像を生成します。出力はIllustrations/mail-cards/に保存されます。
10. サウンドエフェクト
python3 scripts/make-sfx.py "type" --duration 0.5 --output sfx.wav
python3 scripts/son.py "description" --duration 1.0 --output sound.wav
make-sfx.pyは指定されたタイプの基本的なサウンドエフェクト(例:「click」、「whoosh」、「ding」)を生成します。son.pyはより複雑なサウンドを説明から合成します。出力はmotion-design/public/sfx/に保存されます。
11. レンダリング後の配置
レンダリングとXML生成後、すべての要素(Bロール、写真、GIF、サウンドエフェクト、画面キャプチャ、メールカード)は適切なトラック(V2、V3、V5、V6、V7)に配置され、トランスクリプトの単語に同期します。render-segments.pyはすべての配置を含む単一のPremiere XMLファイルを生成します。
12. 納品と確認
XMLファイルをユーザーに提供します。ユーザーがPremiereでインポートし、配置を確認します。ユーザーからのフィードバックに基づいて、必要に応じて調整を行います。