Communityコーディング&開発github.com

gfx-html

ユーザーがオンスクリーングラフィック、タイトル、またはオーバーレイをリクエストしたときに使用します。HTMLテンプレート契約、Chromeヘッドレスフレームレンダリング、アルファチャンネルを保持したムービーエンコード、そしてproject.jsonのoverlaysブロックをカバーします。

gfx-html とは?

このスキルは、ビデオ編集やライブ配信において、HTMLテンプレートを使用してオンスクリーングラフィック(テロップ、タイトルカード、数字のオーバーレイなど)を生成・配置するためのものです。ユーザーが「テロップを作って」や「タイトルカードを追加して」といった指示を出すと、このスキルが起動します。コアとなる設計原則は、すべてのグラフィックをフレーム番号(`?t=<秒>`)の純粋関数として定義することです。これにより、CSSアニメーションに依存せず、フレームレンダリングが決定的かつキャッシュ可能になり、一貫した結果が得られます。スキルはまず`presets/graphics/*.html`から既存のテンプレートを再利用するか、新しいHTMLテンプレートを作成します。その後、`python engine/ve.py gfx <slug>`コマンドを実行し、ヘッドレスChromeを使用して各フレームをPNG画像としてレンダリングし、アルファチャンネルを保持したままQuickTime RLE(qtrle)やProRes 4444などの形式にエンコードします。最後に、このグラフィックをプロジェクトのタイムラインにアンカー(`segment_id`と`offset_frames`を使用)として配置し、編集によるずれを防ぎます。レンダリングパフォーマンスの見積もり表示、フレームのキャッシュ、そしてアルファプローブやブランクページチェックなどの品質確認も行います。主にClaude CodeなどのAIエージェント環境での使用を想定しています。

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/businessbaum/vedit/tree/HEAD/.agents/skills/gfx-html

Installed? Explore more コーディング&開発 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

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

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

ドキュメント

gfx-html は何をしますか?

グラフィックは、ヘッドレスChromeによって1フレームずつレンダリングされ、アルファムービーにエンコードされるHTMLページです。完全なリクエストテキストは$ARGUMENTSに格納されます。最初のトークンは通常、プロジェクトスラッグです。動詞名はビルドコントラクトに従います。python engine/ve.py --helpが競合した場合に優先されます。

このレーンを機能させるルール

すべてのグラフィックは ?t=<秒> の純粋関数です。 CSSアニメーション、GSAPタイムライン、requestAnimationFrame、トランジションは使用しません。ページは location.search から t を読み取り、レイアウトを計算し、1つの静的フレームをレンダリングします。

これはスタイル上の好みではありません。chrome --headless --screenshot は「ページがロードされたように見えるとき」に実行されます。このビルドには仮想クロック、Emulation.setVirtualTimePolicy、beginFrame はありません。そのようにサンプリングされたCSSアニメーションページは、実行のたびに異なるピクセルを返します。これにより、コンテンツアドレス可能なキャッシュ(同じキー、異なるピクセル)が破壊され、目に見えるカクツキが発生します。

t の純粋関数は、同じ単純なループでサンプリングされた場合、決定論的でキャッシュ可能です。これがすべての違いです。

事前に提示する予算

Chromeは定常状態でフレームあたり約430〜470 msでレンダリングし、コールドスタートは7.9秒かかります。30 fpsで5秒のグラフィックは150フレームであり、シングルスレッドで約65秒かかります。エンジンは4つのChromeプロセスを並列化し、フレームごとのPNGをキャッシュするため、変更のないグラフィックの再レンダリングは無料で行われます。ただし、最初のレンダリングは瞬時ではありません。

長いグラフィックを開始する前に、フレーム数と推定時間をユーザーに伝えてください。短いグラフィックを推奨します。6秒間保持するテロップは、6秒間のモーションを必要としません。0.4秒のフェードイン、ホールド、0.4秒のフェードアウトで十分です。

ステップ1 - テンプレートを選択または作成する

テンプレートは presets/graphics/*.html にあります。作成する前に再利用してください。テンプレートは、以下のことを行う単一の自己完結型HTMLファイルです。

  • location.search から t(秒)とそのプロパティを読み取ります。
  • すべての位置/不透明度を t から純粋な算術演算で計算します。イージング関数は問題ありません。これらは純粋です。
  • 透明なボディ上にレンダリングします。背景色を塗ってはいけません。
  • assets/fonts/ のフォントを @font-face と file:/// URL を使用して使用します。システムフォントに依存しないでください。このボックス上のChromeが解決するフォントは、QCコントロールレンダリングが想定するものと同じではありません。
  • 1920x1080で、かつプラットフォームのキャプションセーフエリア内で読みやすいこと。output.platform を確認してください。下3分の1に配置するテロップは、TikTokのUIの下に隠れてしまいます。

レイアウトの詳細、イージング規則、およびプロパティコントラクトは docs/graphics.md にあります。ここでは繰り返しません。

ステップ2 - フレームをレンダリングする

python engine/ve.py gfx <slug>

フレームごとに、エンジンはChromeをargvリストとして呼び出します。おおよそ以下のようになります。

chrome.exe --headless=new --disable-gpu --no-sandbox --hide-scrollbars
           --user-data-dir=<win-path>\prof --default-background-color=00000000
           --window-size=1920,1080 --screenshot=<win-path>\frame_0007.png
           "file:///C:/.../template.html?t=0.233&title=..."

レーン全体を担う2つのフラグがあります。

  • --default-background-color=00000000 は、本物のアルファを生成するものです。確認済み:コーナーピクセルは 0 0 0 0 を読み取ります。これがないと、不透明な黒が生成され、オーバーレイがビデオを覆い隠します。
  • file:/// URLは、実際のWindowsパスである必要があります。Git Bashの $PWD パスは黙って失敗します。3つの異なるHTMLファイルが、空白のダークモードエラーページの同一のmd5を生成し、終了コード0、もっともらしいファイルサイズを返します。これが、QCチェック(g)が既知の空白ハッシュと比較する理由です。

フレームは .cache/html/ にキャッシュされ、キーは sha256(html_content + t + params + renderer + renderer_version) です。テンプレートを変更するとすべてのフレームが無効になります。これは正しい動作です。

ステップ3 - アルファを保持してエンコードする

同じコマンドです。ve gfx はフレームをレンダリングし、1回のパスでエンコードします。別個のエンコード用の動詞はありません。なぜなら、隣にムービーのないPNGシーケンスは、下流で何も使用できない中途半端なアーティファクトだからです。

PNGシーケンスをQuickTime RLE (qtrle、argb) に変換します。ProRes 4444と生のPNGシーケンスもアルファを正しく維持します。VP9-in-WebMは、このビルドではアルファを黙って破棄します。-metadata alpha_mode=1 を使用しても同様です。使用しないでください。また、プローブせずにユーザーのアセットから受け入れないでください。

出力は .cache/ovl/<xx>/<key>.mov に配置され、<key>.json サイドカーファイルが付随します。

ステップ4 - オーバーレイをアンカーする

overlays[] エントリを記述します。id、kind: "html"、template、props、anchor、duration_frames、layer、render です。

anchor は常に {segment_id, offset_frames} です。絶対タイムラインポジションを使用してはいけません。 タイムラインポジションは、有効なセグメントの累積和から導出されます。上流の誰かがセグメントを無効にした瞬間、すべての絶対ポジションが間違ったものになり、すべてのグラフィックがずれます。アンカーされたオーバーレイは、セグメントとともに自動的に移動します。これはエディターが期待する動作です。

layer はコンポジットの順序を決定します。数値が大きいほど手前に表示されます。キャプションは最後に焼き付けられ、グラフィックの上に表示されます。

ステップ5 - 完了と宣言する前に検証する

3つのチェックがあり、すべて低コストです。

  1. アルファプローブ。 コーナーフレームから1つのraw rgbaピクセルを読み取り、 a = 0 をアサートします。QC (d)。
  2. ブランクページチェック。 フレームがそれぞれ単一のフラットカラーではないことをアサートします。QC (g)。これにより、不正な file:/// URL、読み込みに失敗したフォント、JSエラーが検出されます。これらはすべて、もっともらしいファイルサイズで終了コード0を返します。最初、中間、4分の3のフレームをサンプリングし、すべて が均一である場合にのみ失敗します。ここのすべてのテンプレートは不透明度0で開くため、動作中のグラフィックのフレーム0は正当に空白であり、それだけで判断すると正しいレンダリングが失敗します。

ve gfx は、作成したばかりのものに対して自動的に両方を実行し、いずれかが失敗した場合は終了コード2で終了します。 3. 決定論。 1つのフレームを2回レンダリングし、ハッシュを比較します。それらが異なる場合、テンプレート内の何かが t の純粋関数ではありません。それを見つけてください。このチェックが存在するのは、それがキャッチする障害が、キャッシュされたレンダリングと新しいレンダリングが一致しなくなるまで目に見えないからです。

次に、中間点の静止画をユーザーに表示します。スクリーンショットが1コマンドで取得できるのに、散文でグラフィックを説明しないでください。

障害モード

症状原因修正方法
オーバーレイがビデオを黒で覆う--default-background-color がない、またはテンプレートが背景を塗るフラグを追加する。ボディを透明にする
すべてのフレームが同一、もっともらしいファイルサイズ不正な file:/// URLによる空白のエラーページ実際のWindowsパスを使用する。空白ハッシュに対してアサートする
同じキー、異なるピクセル(実行間)テンプレートが t の純粋関数ではないすべてのCSSアニメーションとrAFを削除する
テキストが間違った書体でレンダリングされるシステムフォントのフォールバックassets/fonts/ から @font-face を file:/// URL で使用する
エンコード後にアルファが失われるVP9/WebMqtrle argb または ProRes 4444 を使用する
上流の編集後にグラフィックがずれる絶対タイムラインアンカー{segment_id, offset_frames} にアンカーする
レンダリングに数分かかる430 ms/フレームが下限グラフィックを短くするか、それを受け入れる。キャッシュにより2回目の実行は無料

Individual skills in this repo

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

businessbaum/vedit

This skill should be used when the user asks for subtitles or on-screen text of what is being said - "brenn die Untertitel ein", "mach Untertitel", "Untertitel drauf", "leg Untertitel drüber", "brenn die Subs ein", "mach die Captions", "Wort für Wort Untertitel", "Karaoke-Untertitel", "korrigier den Untertitel-Text", "burn in the captions", "add subtitles", "burn the subs", "word-by-word captions", "fix a caption typo". Covers ASS generation, the pixel-width grouping rule for German, the font table, and burn-in through libass.

businessbaum/vedit

This skill should be used when the user asks for mechanical tightening of material that is already selected - "mach den Rohschnitt", "bau den Rohschnitt", "schneid die Ähms raus", "nimm die Füllwörter raus", "entferne die Pausen", "kürz die Pausen", "schneid die Versprecher raus", "mach den Radioschnitt", "straff das", "build the rough cut", "cut the fillers", "remove the ums", "tighten the pauses", "trim the dead air", "cut the retakes", "radio edit". Turns kept story blocks into enabled segments in project.json. Does not decide what the video is about - that is cut-story.

businessbaum/vedit

This skill should be used when the user asks to decide what the video is actually about before any mechanical cutting - "bau die Story", "was soll ins Video", "was kann raus", "welche Themen bleiben", "kürz das auf 6 Minuten", "mach daraus ein kurzes Video", "wo ist der Hook", "sortier die Themen", "worum geht es hier eigentlich", "build the story", "decide what stays", "structure this", "cut this down to N minutes", "find the hook", "reorder the topics". This is the CONTENT-selection pass that writes the "story" block in project.json; it runs after transcribe and before cut-rough.

businessbaum/vedit

This skill should be used when the user asks for the finished video file - "exportier das", "render das fertig", "mach das final", "renderte das Video", "mach den Endexport", "bau das Video zusammen", "mach es fertig für YouTube", "gib mir die MP4", "export the final", "render the final cut", "make the master", "export for TikTok", "give me the mp4". Covers segment rendering with the cache, guarded concat, the one-pass audio, loudness normalisation and the single mux.

関連スキル