Communitygithub.com

ccreator-space/video-storytelling

ロングフォームのトーキングヘッド動画のビジュアルレイヤーを、個別のグラフィックの連続ではなく、カメラが動き回る一つの永続的な世界として設計・構築します。動画編集、モーショングラフィック追加、スクリプトのビジュアルデザイン、編集計画、または「混乱している」「テキストが多い」「AIが作ったと明らかにわかる」と判断された編集の修正を依頼された際に使用します。永続的な世界、カメラ文法、スポットライトルール、空間的オープンループ、装飾とトークンの規律、トランスクリプトのタイミング、検証ゲートをカバーします。

video-storytelling とは?

このスキルは、ロングフォームのトーキングヘッド動画において、視聴者が9分経過しても方向感覚を失わない、一貫したビジュアル世界を構築するための手法を提供します。従来の「シーン思考」、つまり数秒ごとに新しいグラフィックを表示する方法は、視聴者の理解を頻繁にリセットし、「混乱する」「情報過多」という漠然としたフィードバックを生み出します。このスキルは、永続的な世界(一度描いた要素は決して再描画しない)、カメラワークを編集とする考え方、スポットライトルール(常に一つの要素のみを完全な明るさにする)、空間的オープンループ(視覚的に未完了のものを残して後で回収する)、厳格なトークン規律(ストローク、フォントサイズ、色数を制限)という4つの原則に基づいています。このスキルは、Claude CodeやCursorなどのAIエージェントが、スクリプトやトランスクリプトのタイミングに基づいて、各セクションの生成コードを記述する形で適用されます。動画のビジュアルデザイン、編集、またはそれらの修正を依頼されたときに使用され、最終的には視聴者にとって理解しやすく、プロフェッショナルな印象を与える動画を生み出します。

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/ccreator-space/edit-flow/tree/HEAD/.agents/skills/video-storytelling

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

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

ドキュメント

ビデオストーリーテリング

ロングフォームのビデオのビジュアルレイヤーを、視聴者が9分経過しても方向感覚を失わないように構築する方法。スクリプトがあるトーキングヘッド動画(ニュース解説、単一テーマの深掘り、比較、チュートリアル、ランキング形式の記事など)に適用されます。

この手法が置き換える失敗は「シーン思考」です。数秒ごとに新しいグラフィックを表示すると、視聴者は数秒ごとに理解を再開しなければならず、個々のグラフィック自体に問題はないため、フィードバックは「わかりにくい」や「情報が多すぎる」といった漠然としたものになり、具体的な欠陥として指摘されません。

中立的な練習用ビートシートについては、リポジトリルートの docs/STORYTELLING-WORKBOOK.md を参照してください。再利用可能なデザインシステムはこのスキルの reference/design-system.md に、実践的なオープンループ形状は reference/patterns/wall-of-slots/ にあります。プライベートなソースビデオは必要ありません。

これは hyperframes-video-beats とは異なります。そちらはトーキングヘッドの上にオーバーレイカードを配置するスキルです。こちらはビデオが 主題としているもの をデザインします。

1 · 4つの原則

一つの永続的な世界

ビデオは単一の空間に存在し、決してリセットされません。視聴者がすでに見たものはすべて、置かれた場所にそのまま存在し続け、新しい素材はそれを置き換えるのではなく追加されます。一度描画された要素は、再描画されたり、移動されたり、ラベルが変更されたりすることはありません。

このスキルの他のすべてはこれに依存しています。空間が変化し続ければカメラの行き場はなく、画面上に他に何もなければスポットライトは意味をなさず、リセットされる世界ではオープンループを開いたままにしておくことはできません。

世界はまた、滞在する価値がなければなりません。そのため、何かを構築する前に空間的な文法を決定し、ランタイム全体を通してそれを維持します。リファレンスビルドでは、左から右へは結果へ向かう動き、上は人間へ向かう動きで画面上で唯一の暖色、下は記録システムへ向かう動きです。最初の2分間でこれを学習した視聴者は、残りのビデオを無料で読むことができます。

意味を持たせるために、意図的に、文法を一度だけ破ります。リファレンスビルドでの10分間で唯一の右から左への動きは、「再開率」という言葉に合わせて、解決済みのチケットがキューに戻される場面です。それまでの3分間、方向が何かを意味していたため、この動きは言葉を使わずに伝わります。

カメラが編集である

新しいグラフィックにカットするたびに、視聴者は方向感覚を失います。静止した空間を動き回ることは、視聴者に何の負担もかけません。プッシュインは「すでに理解しているものの一部をより詳しく見る」と読まれ、プルバックはこれまでに構築したすべてのものがまだそこにあるため、その努力が報われる場所です。

3つの高度で作業し、隣接する高度間を移動します。

高度表示内容使用目的
世界空間全体方向付け、見せ場、「ここが今の場所」
領域議論中のサブグラフランタイムの大部分
詳細一つの要素数値、状態変化、決定

詳細から世界へのジャンプは、意図的な見せ場のビートでない限り混乱を招きます。その場合、それは利用可能な最良の動きです。

学習にそれぞれ再構築を要するルール:

  • フレーミングは正確な世界のウィンドウとして指定し、倍率としては指定しない。 ウィンドウの境界はラベルの間に収まる必要があります。フレーミングを「scale 0.6」と指定すると、フレームの端で単語が半分に切られます。
  • 同じ目的には同じウィンドウを再利用する。 オリエンテーションショットが特定のウィンドウである場合、常にその正確なウィンドウを使用します。ほぼ同一のフレーミングはドリフトとして認識されます。
  • 持続時間は移動距離に応じて変化させ、グローバルなプリセットは使用しない。
  • カメラ移動と全画面ワイプは連続して実行し、決して重ねない。 同時に行うと、コンテンツを断ち切ります。カメラを先に、次にワイプです。
  • カバーレイヤーは、カメラがその下を移動する前に不透明になる。 順序が逆だと、移動の一部が露出し、ジャンプカットのように見えます。
  • フレーム端から60px以内にラベルを配置しない。 要素がはみ出るのは「世界が続いている」と読まれますが、グリフの途中で切れた単語はバグのように見えます。マスクではなく配置で解決します。フェザーは約1800px/秒で移動する刃を捕らえることができません。
  • 同じ被写体に対する2つの連続した動きは、グリッチのように見える。 リフレームが完了し、その後ワイプが開始するのは、ズーム、完全停止、そして2番目のモーションであり、クライアントはこれを「グリッチとポーズ」と呼びます。これらを1つのジェスチャーに統合します。共有の対称イージング(power2.inOut)、同じフレームに着地させ、パネルがフッテージを押しのけているように見せます。関連:可視フッテージの移動で front-loaded イージング(power3/4.out)を使用すると、移動の約90%が最初に集中し、最後は這うようになります。これらは要素の登場時(這うように見える動きが落ち着きとして読まれる)に予約してください。(実例のイントロでクライアントから指摘された修正が発生しました。)

注意はスポットライトである

どの瞬間も、完全な明るさで光る要素は正確に一つだけ。すでに描画された他のすべては、控えめだが判読可能な状態を保つ。 これは必須です。このルールによって、世界が十数の要素にまで成長しても決してごちゃごちゃしているように感じさせず、プルバックを圧倒的ではなく読みやすくするのです。

階層は、アクティブとクワイエットの比率から生まれ、すべてを暗くすることからではありません。リファレンスビルドの最初のプロトタイプは最も明るいピクセルが101/255で、960x540では判読不能でした。修正は、より暗くすることではなく、より明るいインクを使用することでした。

状態ターゲット輝度 (Y, 16-235)リファレンスでの不透明度
アクティブなストローク+ラベル200-2351.0
コンテキスト、描画済みで依然として関連あり120-1500.56
消費済み、役割を終えた85-1050.33
任意のラベル、任意の状態決して90未満

実装は、説明されているナレーションビートごとに呼び出される一つの関数です(build_s01.py, lit()):

def lit(t, active, warm=(), dur=0.5, floor=FLOOR):
    active = list(active) + [g + "-l" for g in active if g + "-l" in order]
    for gid in order:
        if gid not in opac:      # 未描画:照らすものなし
            continue
        tgt = 1.0 if gid in active else (WARM if gid in warm else floor)
        if gid not in active:
            tgt = min(tgt, MUTED.get(gid, 1.0))
        ...

その中には、重要な3つの詳細があります:

  • ラベルは常にその要素の状態を継承する(-l サフィックスの折り込み)。照らされている要素の下にあるラベルが読めない場合、それはまさに修正しようとしている欠陥です。
  • 役割を終えた小道具は不透明度0に引退する(MUTED キャップ経由)。0.3にミュートすると、セクションの残りの間、説明のつかない紙吹雪が画面上に残ります。ジェネレーターのルール:後で開始する lit() の前に mute() を発行します。そうしないと、トゥイーンが完了したときにミュートが上書きされます。
  • 不透明度イベントはタイムライン順に発行する必要がある。そうしないと、トラッカーが古い状態を認識し、間違ったターゲットを計算します。順序不同の発行時にエラーを発生させる seq() ガードを保持します。
  • ウィンドウごとに、要素ごとに一つの不透明度の権威。 同じ要素の不透明度を異なる値に駆動する2つの同時アクティブなトゥイーンは、スタンドアロンのセクションではスムーズにレンダリングされますが、アセンブルされたマスターでは約10Hzでストロボを発生させます。これは、勝っているトゥイーンがフレームごとに切り替わるためです。リファレンスビルドでは、この欠陥がすべてのドックで出荷されました。lit() のようなスイープが明示的な明るく/ミュートと重なる場合、後に開始するトゥイーンが唯一のドライバーとなり、スイープはそれらのIDをスキップします(lit(..., skip=(...)))。ゲート:アセンブルされたレンダリングをスキャンし、すべての遷移ウィンドウで1フレームのアウトアンドバックの輝度ポップを確認します(リファレンスビルドの qa/v4/flicker/qa-flicker.mjs)。

オープンループは空間的である

「これについては後で戻ってきます」とは決して言いません。世界の中に視覚的に未完成のものを残し、それに戻ります。視聴者が見ることのできる約束は、視聴者が未達成だと感じることのできる約束です。

仕組みは形状が何であれ同じです:

  1. フックの中で、空間に、約束をするライン上にそれを植え付ける。
  2. すべての境界でそれを再表示する。 任意のセクションの受け渡しは境界です。再表示には約2秒かかり、これはリテンションの仕組みです。これをスキップすると、見せ場が何も報われないことになります。
  3. それを目に見えて進行させる。 視聴者は不完全さが縮小するのを見なければなりません。
  4. 開いたときと同じイメージで閉じる。

スクリプトから形状を選びます:

スクリプトの形状世界不完全なもの
N個の並列項目背骨上のN個のソケット空のスロット(reference/patterns/wall-of-slots/ を参照)
一つのプロセス、深いレイアウトされた完全なパイプライン壊れた、または欠落したリンク
レベルまたは階層上方に構築されるスタックスタックの最上部はゴースト
比較一つの共有軸上の2つの列一方の列が空、または未記入のスコアカード
ニュースまたは発表タイムライン、またはランドスケープマップ右側、未来、が空白
チュートリアルまたはビルドアロングゴースト化された完成したアーキテクチャまだ構築されていないすべてのノード

アイテムをそのスロットに渡すのは、ライブカメラの動き(約1.4秒)であり、満たされた状態の事前に作成された画像へのカットではありません。視聴者は、今学んだばかりのものがタイルになるのを見ます。ビデオに数字やカウンターがある場合は、その同じ動きの中で、オドメーターのように、両方の数字に同じ開始、持続時間、イージングを使用してロールします。さもないと、ロール中にそれらは一つのバンドにマージされます。

カウンターには数字だけでなく名前が必要です。 隅の数字は、視聴者にシーケンス内のどこにいるかを伝えますが、現在のアイテムが何であるかは伝えません。9分経過すると、「03」は何も伝えません。数字と、現在のアイテムに名前を付ける1〜2語のラベル(SUPPORT、VOICE AI)を、同じプレート化学で、数字と同じリジッドフィクスチャとして移動し、同じオドメーターロール内で入れ替えてペアにします。リファレンスビルドのクライアントレビューではまさにこれが求められていました。ビジュアルは良好でしたが、どのユースケースが画面に表示されているかを視聴者は依然として見失っていました。

2 · 規律

言葉にできないものは描かない

すべての形状は、ラベル付き要素、ラベル付き要素間のコネクター、移動する被写体、または背景のいずれかです。それ以外はありません。

これは、理解度を7/10と評価し、原因を特定したミュートテストのレビューから生まれました。図はきれいでしたが、装飾はそうではありませんでした。意味のあるものと同じ太さとパレットで描かれた、ラベルのない十数の形状。そのため、初めて見る視聴者はシグナルとテクスチャを区別できず、決して解読されることを意図していなかったものを解読することに実際の注意力を費やします。これが「情報過多」が言葉から形状へと移行したものです。

予算:セクションあたり画面上約20語。 文はありません。ラベルは1〜2語で、その要素の下に配置します。リファレンスセクション1は、84秒間で21語です。

当然の帰結として、アンチパターンのビジュアルは推奨事項に決して重ねて表示しません。 まず世界をほぼ黒にし、または良い図がある場所ではないところに反例を置きます。

視聴者に一つの追跡対象を与える

状態が目に見えて変化する、単一の移動する被写体でストーリーを運びます。データ行とスコアバーを持つチップ、ドキュメント、リクエストなどです。行が埋まり、バーが動き、境界線の色が変わります。視聴者は、その一つのオブジェクトを見るだけでセクション全体を追跡できる必要があり、それは決してテレポートしてはいけません。描画されたコネクターに沿って一定の速度で移動します。

一つのグローバルトークンセット

完全な詳細は reference/design-system.md にあります。

トークン値
ストローク1.5 / 2.5 / 4 / 7、その他はなし
タイプ22 / 30 / 42 / 60 / 84
半径10 / 22 / 40、常に superellipse(2)

5色、5つの固定された意味、装飾はゼロ。暖色は人間が関与していることを意味し、その他のものが暖色になることは決してありません。タイプには純粋な白は決して使用しません。暗い背景でハレーションを起こします。

これが防ぐ失敗(最初のビルドのクラフトレビューから):「すべての決定は局所的かつ正確に行われた。しかし、全体的な決定は行われなかった。」 18種類のストローク幅と9種類のフォントサイズ、そのほとんどが0.2刻みで、個々には見えず、全体として致命的です。目は階層ではなくノイズを得ます。ビルドに失敗するトークンリンターでゲートします。

モーション

登場は cubic-bezier(0.16,1,0.3,1)、終了は登場よりも速く、持続時間は質量に応じて変化するため、290pxのノードと40pxのラベルは同じように減速せず、back.out はセクションごとに正確に一回、それに値するビートでのみ使用します。

クロスフェードは絶対に使用しません。 全画面レイヤーは、すでに不透明な背景上でクリップによって出入りします。任意の瞬間において、ピクセルはグラフィックまたはフッテージのいずれかです。

3 · ビルド契約

  • セクションごとに一つのジェネレーター。 scripts/build_<id>.py は compositions/<id>.html のみを書き込みます。生成されたHTMLは編集せず、ジェネレーターを編集します。セクションルート index-*.html は手動で管理されるため、フレーミングの変更はそこに行います。
  • 共有モジュールは共有されたままにします。 共有ジオメトリを定義するものはすべて、すべてのセクションによってインポートされます。セクションが並列エージェントによってビルドされる場合、それらが共有モジュールに触れることを禁止します。分岐したジオメトリは、すべてのハンドオフを静かに壊します。
  • アセンブリの前にSVG defsを名前空間化します。 各セクションは独自の gEdge、shadow、edgeFade を定義します。一つのアセンブルされたDOMでは、url(#id) はドキュメント順の最初の一致に解決されるため、以前のコンポジションがアンマウントすると、後続のすべてのグラフィックは何も描画しません。リファレンスビルドでのコスト:すべてのゲートが緑色の35秒間の空の画面。アセンブルされたレンダリングを見て初めて発見されました。
  • すべてを単語レベルのトランスクリプトからの単語の開始にタイミングを合わせ、アンカーワードの0.15〜0.25秒前に入ります。セクションを均等にビートに分割することは絶対に避けます。
  • ギャップを監査します。 何も起こっていない約1.5秒以上の部分はデッドスクリーンです。ジェネレーターにそれらを出力させます。
  • カットに空気を残します。 攻撃的なポーズキャッピングは、文の境界でほぼゼロのギャップを生成し、クライアントはそれを「スタッター」やジャンプカットとして聞きます。スピーカー自身のノルムに対して較正します。スピーカーの中央値よりも約10倍タイトな文境界ギャップにフラグを立て(リファレンススピーカーの中央値は470msで、フラグが立てられた接合部は20〜40msでした)、4〜8フレームの空気を挿入して修復します。言葉は決して触れません。空気は、トラックの実際のルームトーンのドナースライスで、10msのフェードが適用されたものです。anullsrc は決して使用しません。-50dBFSのフロアに対するデジタル無音は、可聴なドロップアウトです。ビデオはフレームを保持します。文の間ではトーキングヘッドはほぼ静止しており、4〜8フレームのホールドは目に見えません。挿入のみの変更はトランスクリプトを決定論的にシフトするため、再トランスクリプションは必要ありません。挿入のエッジはスピーチエンベロープを尊重する必要があります。ドナートーンを単語の末尾に1msの精度で突き当てると、ポップが発生します。フェードインは少なくとも単語のテールの自然な減衰の間に行う必要があります。ffmpeg の acrossfade はここでは壊れています。これは2つのトラックのクロスフェードであり、挿入ではありません。最適なギャップは「存在するが、話されていない」と感じられるものです。厳密に変更のない言語のビデオでは、関連するディテールにホールドすることで、ギャップが計画された一時停止として感じられます。
  • 視差は最初の2分間で確立し、それ以降は変更しない。 視差の強度は、参照フレームを確立するために一定である必要があります。ビデオの途中で変更すると、奥行きの手がかりが壊れます。
  • 影は一貫した光源から落ちる。 リファレンスでは、左上からの光源で、影は右下に落ちます。すべての要素は同じ影のルールに従います。
  • カラーグラデーションは一つの意味のみを持つ。 グラデーションが状態を示す場合、そのグラデーションはその状態に対してのみ使用され、装飾としては使用されません。
  • フォントは一つのフェイスファミリーから、最大2つのウェイト。 リファレンスは、ヘッドラインに1つのウェイト、ボディコピーに1つのウェイトを使用します。可変フォントは使用しません。一貫性がすべてです。

4 · 検証ゲート

以下は、コミット前に自動化ゲートを通過する必要があるチェックです。 詳細な実装については、リポジトリルートの SCRIPTS.md および QA.md を参照してください。

  1. トークンリント:すべての生成されたグラフィックは、指定されたストローク、タイプ、半径のトークン(reference/design-system.md に定義)のみを使用している必要があります。カスタムトークンは許可されません。
  2. ワンアクティブチェック:各フレームで、完全な明るさ(不透明度1.0)の要素は正確に一つだけである必要があります。ビデオ全体をスキャンして違反をチェックします。
  3. ラベル可読性:すべてのラベルは、最小輝度(Y >= 90)を満たしている必要があります。背景に対してラベルをサンプリングして検証します。
  4. オープンループ監査:各「プロミス」(フック)は、ビデオの後半で対応する「ペイオフ」が必要です。スクリプトをスキャンして、約束されたが果たされていないループを特定します。
  5. カメラ移動範囲:すべてのカメラ移動は、定義された3つの高度(世界、領域、詳細)の間であること。許可されていない高度間のジャンプをチェックします。
  6. 時間的制約:すべてのグラフィックの出現は、単語の開始の前(+0.15〜0.25秒)であり、決して後ではありません。
  7. ミュート順序:mute() イベントは、同じIDに対する後続の lit() イベントの前に発生しなければなりません。
  8. 不透明度の権威:各要素の不透明度は、任意の時点で一つのアクティブなトゥイーンのみによって駆動されている必要があります。重複するトゥイーンをチェックします。
  9. クロスフェード禁止:ビデオ内のどこにもクロスフェード遷移があってはなりません(不透明度の変更またはクリップのみ)。
  10. 装飾チェック:ラベル付き要素、コネクター、移動する被写体、または背景として分類されない描画要素は、存在してはなりません。

これらのゲートは必須です。どのゲートも失敗した場合、ビルドは不合格となり、修正してから再送信する必要があります。

関連スキル