/hyperframes-best-practices
このスキルは、生のスクリーンキャスト、トーキングヘッド録画、またはOBSのエクスポートを、洗練されたHyperFrames製品動画に仕上げる際に使用します。2つのレイヤーの知識をまとめています。
- HyperFramesの基礎 — HeyGenが
github.com/heygen-com/hyperframesで管理している上流のルールファイル(コンポジションの作成、GSAPタイムライン、data-*属性、dev-loop CLI)。npx vskill i heygen-com/hyperframesでインストールします。 - プロダクションクラフトのルール — 1本の8分47秒のOBS録画から実際のSpecWeave製品動画を制作する反復サイクルから得られた教訓です。これらのルールに従うとユーザーが実際に出荷できる動画ができあがり、破るとビープ音、単語の途中で切れるクリップ、空白のテイクオーバーシーン、スピーカーの顔カメラを隠すオーバーレイといった問題が発生します。
オーサリングを行う前に、両方のレイヤーを読んでください。
範囲と適用可能性
以下のレイヤー2のクラフトルールは、特定のプロジェクトから導き出されたものです。8分47秒のSpecWeaveイントロ録画(Anton Abyzov、OBSキャプチャ、トーキングヘッド+スクリーンシェア、2026年5月)を、6分のプロダクション対応プロモ動画に変換したものです。 これらのルールは、その製品のルックアンドフィールを反映しています。Studioのティンテッドカードの美学、SpecWeaveのパープル/グリーンパレット、iOSカード風オーバーレイスタイル、そしてOBS録画の技術的な現実(開始/停止のチック音、録画再開時の過渡ノイズ、同じセリフを3回録り直した重複テイク)です。
正確な定数はプロジェクト固有です — その顔カメラの位置に対するオーバーレイ位置、
Boris Cherny / Anthropicの訂正テキスト、600+/500+/3K+の統計 — 翻訳はせず、コピーもしないでください。このレイヤーは、基礎となるテクニックのリファレンスとして使用してください。 文字起こし駆動のスマートカットアルゴリズム、過渡ノイズ抑制のためのクリップごとのフェードイン、concatデマルチプレクサのクリックを回避する
concatフィルターレンダリングパイプライン、外科的なミュートによるノイズ除去、iOSカードオーバーレイパターン、ソース時間→カット時間のマッピング、Studioのウェーブフォームキャッシュ無効化の落とし穴 — これらは一般化可能です。
使用すべきタイミング
以下のいずれかが該当する場合に、このスキルを起動します。
- ユーザーが生のスクリーンキャストまたはOBS録画を持っており、タイトでキャプション付きのブランド化された動画を希望している場合。
- ソースにデッドエア、ポーズによる無音、または「もう一度試してみます」という重複テイクがある場合。
- ソースにクリック音、ビープ音、または録画境界における過渡的なアーティファクトがある場合。
- ユーザーがスピーカーの顔カメラを隠さないグラフィックオーバーレイ(コールアウト、統計カード、ブランド表示、ツールロゴ)を希望している場合。
- ユーザーが「これをプロダクション対応にして」「出荷可能にして」と言った場合。
- ユーザーが「Apple Keynoteスタイル」「iOSホバーカード」「フロストガラス」に言及した場合。
これらのシグナルのいずれかが存在する場合は、このワークフローに従います。ユーザーがクリーンなソースに簡単なタイトルカードを追加したいだけの場合は、上流の hyperframes スキルだけで十分です。
パイプライン(10フェーズ)
┌──────────────────────────────────────────────────────────────────┐
│ フェーズ 0 ツールの確認 │
│ フェーズ 1 ソースを調査(時間、コーデック、オーディオサンプルレート) │
│ フェーズ 2 Whisperで文字起こし(単語レベルのタイムスタンプ) │
│ フェーズ 3 無音とシーンチェンジを検出 │
│ フェーズ 4 スマートカットリストを作成(単語境界バッファ付き) │
│ フェーズ 5 過渡ノイズを除去(外科的ミュート+adeclick) │
│ フェーズ 6 concatフィルタでマスターをレンダリング(シングルパス) │
│ フェーズ 7 ヒーロー画像を生成(Gemini 3 Pro Image) │
│ フェーズ 8 HyperFramesコンポジションを作成(iOSカード) │
│ フェーズ 9 Studioでリント+検証 │
└──────────────────────────────────────────────────────────────────┘
フェーズは順番に実行します。フェーズ内で反復し、フェーズ間では反復しないでください。 カットリストが悪いと、下流のすべてのオーバーレイタイミングが崩れ、アンカーの再解決に1時間かかることになります。まずカットリストを正しく作成し、1回レンダリングしてから、最終的なタイムラインに対してオーバーレイを構築します。
フェーズ0 — ツールの確認
開始する前に、これらが利用可能であることを確認します。このスキルはmacOS / Linuxを想定しています。Windowsの場合はWSLを使用します。
| ツール | 使用目的 | インストール |
|---|---|---|
ffmpeg (>= 6.0) | すべての動画/音声処理 | brew install ffmpeg |
ffprobe | ストリーム調査 | ffmpegにバンドル |
whisper (OpenAI Pythonパッケージ) | 単語タイムスタンプ付き文字起こし | pip install openai-whisper |
python3 | カットリスト/ノイズ除去スクリプト | システム |
npx hyperframes@latest | コンポジションCLI(プレビュー、レンダリング、リント) | npx hyperframes init <project> |
| Gemini 3 Pro Image API | ヒーロー画像(オプション) | GEMINI_API_KEY 環境変数 |
vskill (>= 1.0) | スキルのインストール | npm i -g vskill |
Whisperがインストールされていない場合は、pip install openai-whisper でインストールします。CPUで large-v3 や large-v3-turbo を使用しないでください。 8分の音声に10~15分かかります。英語の技術モノローグには base.en を使用します。 約30秒で完了し、単語境界としては十分な精度です。
ユーザーのマシンに auto-editor がインストールされている場合でも、無視します。これは無音カットはできますが、ノイズ除去や単語境界バッファリングはできず、50以上のセグメントに分割された粗いカットを生成します。手動で行う方が優れています。
フェーズ1 — ソースを調査
他のことを行う前に、ファイルの形状を把握します。
ffprobe -v error -show_entries stream=index,codec_type,codec_name,width,height,r_frame_rate,duration,sample_rate,channels \
-show_entries format=duration,size,bit_rate -of json "$SRC" | tee source_meta.json
把握すべき事項:
- 総時間 — すべてのカット計算の基礎。
- フレームレート — OBSは60 fpsで録画することが多い。HyperFrames Studioは内部で30 fpsでスクラブ再生する。秒数×30 でStudioのフレーム番号を計算します。秒数×ソースfpsではありません。 これでよくつまずきます。
- オーディオコーデックとサンプルレート — OBSは一般的に48 kHzで
pcm_s24leを録画する。配信にはAAC 192kにエンコードし、ダウンストリームのすべてのツールと一致させるために48 kHzを維持します。 - コンテナ — DaVinciの
.mov、OBSの.mkv— どちらも問題なく、ffmpegはどちらも読み取ります。
プローブ結果をディスクに保存し、後のフェーズで再プローブせずに読み取れるようにします。
フェーズ2 — Whisperで文字起こし
単語レベルのタイムスタンプが基礎です。これがないと以下のことはできません。
- カット境界を単語のエッジにスナップする(単語の途中で切れるのを防ぐ)。
- 重複テイクを検出する(同じセリフが2~3回言われている)。
- カット時間ではなく、発話の瞬間に合わせてオーバーレイアンカーを配置する(カット時間はずれる可能性がある)。
まず音声を抽出します。 これにより、Whisperはクリーンなモノラル16 kHz WAVを取得でき(フル品質と比較してCPUを80%節約)、以下のコマンドを実行します。
mkdir -p .work
ffmpeg -hide_banner -y -i "$SRC" -vn -ac 1 -ar 16000 -c:a pcm_s16le .work/source.wav
Whisperを単語タイムスタンプとJSON出力で実行します。
whisper .work/source.wav \
--model base.en \
--language en \
--word_timestamps True \
--output_dir .work \
--output_format json \
--verbose False
⚠️ Whisper CLIの落とし穴: --output_format json --output_format srt と渡すと、古いバージョンでは最後のフラグのみが保持されます。複数の形式が必要な場合は、--output_format all を使用します(JSON + SRT + VTT + TSV + TXTを書き込みます)。
出力を検証します。.work/source.json に、start、end、word を持つ segments[].words[] が含まれている必要があります。words が空の場合は、--word_timestamps True を忘れています。
この段階で完全な文字起こしを読んでください。 スキップしないでください。以下の点がわかります。
- ブランド名の聞き間違い。 Whisperは「Claude Code at Anthropic」を90%の確率で「Cloud Code at Infropic」と聞きます。「SpecWeave」は「spec with」や「specs」になります。これらは再録音ではなく、オーバーレイ訂正が必要です。
- 重複テイク。 同じ文が逐語的に繰り返されていないかを探します。私たちのプロジェクトでは、「And those systems cannot produce skills as you work」 が01:14、01:30、01:47に3回出現しました。そのうち2つを削除します。
- フィラーの再開。 「And…」、「And…」のような単語の断片が実際の文の前にある。カットスクリプトはこれらを「ゴースト」セグメントとしてキャッチします — フェーズ4で削除します。
フェーズ3 — 無音とシーンチェンジを検出
カットアルゴリズムに供給する2つの並行検出。
3a. 無音検出
ffmpeg -hide_banner -nostats -i "$SRC" -af "silencedetect=noise=-30dB:duration=1.2" -f null - 2>&1 \
| grep -E "silence_(start|end)"
-30 dB と 1.2s が最適値です。ゆるくすると (-25 dB、0.8s)、カットしたくない息継ぎの隙間を拾います。きつくすると (-35 dB、2s)、本当のデッドエアを見逃します。
開始/終了のペアを [(s, e, dur), ...] に解析し、silences.json に書き込みます。scripts/build_cuts.py を参照してください。
3b. シーンチェンジ検出
ffmpeg -hide_banner -nostats -i "$SRC" -filter:v "select='gt(scene,0.05)',showinfo" -f null - 2>&1 \
| grep "showinfo" | grep -oE "pts_time:[0-9.]+" | sed 's/pts_time://' > scenes.txt
scene>0.05 は、スピーカーが新しいブラウザタブを開く、アプリを切り替える、大きくスクロールするといった操作をキャッチするのに十分な感度です。0.03 を下回ってはいけません — カーソルの点滅で誤検出が発生します。
この2つを組み合わせることで、スマートカットの判断ができます。無音 + シーンチェンジなし = 純粋なデッドエア、カット。無音 + シーンチェンジあり = スピーカーが画面上で何かを表示している、保持(視聴者はナレーションではなく画面を見ることを期待されている)。
フェーズ4 — スマートカットリストを作成
カットアルゴリズムには、苦労して得られた 5つの厳格なルール があります。
ルール1 — 純粋なデッドエアはカットするが、すべてをカットするわけではない
MIN_CUT_LEN (1.5s) より長く、内部にシーンチェンジがない無音セグメントごとに、BREATH の0.30秒を除くすべてをカットします。この息継ぎは自然なリズムを維持します — 無音を100%除去すると、音声が機械編集されたように聞こえます。
if not in_scenes and (cut_end - cut_start) > MIN_CUT_LEN:
cuts.append((cut_start + 0.30, cut_end, f"dead air {dur:.1f}s"))
ルール2 — 画面アクティビティがある無音は保持(最大3.5秒)
無音にシーンチェンジがある場合、スピーカーは視聴者に読ませている。first_scene - 0.4s から last_scene + 0.8s までのウィンドウを維持しますが、3.5秒を超えてはいけません — 3.5秒以上同じフレームを見続けると、視聴者は飽きてしまいます。
ルール3 — 単語境界にスナップ
大まかな保持範囲を計算した後、各境界をWhisperの最も近い単語エッジに、0.4秒の許容範囲内でスナップします。
def snap(t, words):
best, bd = t, 0.4
for s, e, _ in words:
for cand in (s, e):
if abs(cand - t) < bd:
best, bd = cand, abs(cand - t)
return best
これにより、カットが単語の途中で切れるのを防ぎます。これがないと、2回に1回のカットで末尾の「s」や子音が欠落します。
ルール4 — 単語境界バッファを追加(ユーザーが気づくポイント)
単語エッジへのスナップでも、末尾の子音はWhisperが報告する単語終了タイムスタンプより若干長く伸びます。 Whisperは母音の開始から母音の終了までの時間を計測し、子音の末尾は計測しません。そのため、word.end で文字通りカットすると、末尾の「s」、息継ぎ、または「k」が欠落します。
修正方法: 各保持範囲を拡張します。
- 終了: 最後の単語の終了から
+ 0.30秒、ただし次の保持までの半分を上限とします。 - 開始: 最初の単語の開始から
- 0.10秒、ただし前の保持までの半分を上限とします。
END_BUF, START_BUF = 0.30, 0.10
for i, (s, e) in enumerate(keep):
gap_next = keep[i+1][0] - e if i+1 < len(keep) else TOTAL - e
gap_prev = s - keep[i-1][1] if i > 0 else s
add_end = min(END_BUF, max(0, gap_next * 0.5))
add_start = min(START_BUF, max(0, gap_prev * 0.5))
if gap_next < 0.6: add_end = max(add_end, gap_next - 0.05) # 小さなギャップを吸収
if gap_prev < 0.6: add_start = max(add_start, gap_prev - 0.05)
final.append([s - add_start, e + add_end])
結果: 「find the tickets」というカットが、ソースの08:09.26から08:09.56に拡張され、末尾の「s」が生き残ります。これがないと、ユーザーはオーディオが「急いでいる」「語尾を飲み込んでいる」と感じるでしょう。
ルール5 — 手動による重複テイクの削除
プログラムによる同一n-gramの重複排除は脆弱で危険です(正当な繰り返しを削除する可能性があります)。代わりに、文字起こしを読み、逐語的な重複を自分で見つけ、ソース時間で明示的な削除範囲を追加します。
DUP_RANGES = [
(78.86, 113.82), # 01:18.86 - 01:53.82: 「skills as you work」の3テイク中2つ
]
for ds, de in DUP_RANGES:
# この範囲と重なる各保持をトリミング
...
これにより、カット後の保存率が35%から32%に減少します(重複は無音ギャップ+音声です)が、結果はクリーンに読み取れます。
出力
スクリプトは以下のファイルを書き込みます。
cuts.json— 保持範囲、カット範囲、要約統計、ソース時間マッピング(フェーズ8でオーバーレイアンカーに使用)。edl.txt— 人間が読み取れるEDL。保持ごとに文字起こしのスニペットが含まれます(レンダリング前に目視確認してください)。
完全な実装については、scripts/build_cuts.py を参照してください。
フェーズ5 — 過渡ノイズを除去
OBS録画には、短い過渡的なアーティファクト(起動音、キースイッチのクリック音、ホットな入力に当たったマイクの破裂音)が含まれることがよくあります。これらは無音判定をすり抜けて存在します。なぜなら、これらは音量が大きい(そのため無音検出は無視する)にもかかわらず、静かな部分に囲まれているからです。最終的な動画の4:11や0:52などで「チッ」という音として聞こえます。
これをグローバルなノイズゲートやノイズリデューサーで修正しようとしないでください。 子音がにじみ、音声が水中で話しているように聞こえます。代わりに、過渡ノイズを検出し、60~100msのウィンドウを外科的にミュートします。
検出アルゴリズム(音声をミュートしないもの)
過渡ノイズは、以下の条件をすべて満たす場合に「ビープ音」と見なされます。
RMS(window 5ms) > BEEP_RMS_MIN (例: > 800)
RMS(preceding 150ms) < PRE_QUIET (例: < 200)
RMS(following 200ms) < POST_QUIET (例: < 350)
3番目の条件は重要です。これがないと、音声の子音の開始(「p」「t」「k」)を捕捉してしまいます。最初の5msではこれらはまったく同じように見えますが、音声の後には持続的な母音が続くのに対し、ビープ音は無音に戻ります。post_avg < 350 でフィルタリングすると、孤立した過渡ノイズのみを確実に無音にできます。
また、無音化するスパンは0.30秒に制限します — 誤分類があっても単語全体が消えることはありません。
外科的ミュートを適用
対象範囲を指定したffmpegの volume フィルター式を作成します。
volume=enable='between(t,52.110,52.180)+between(t,169.850,169.920)+...':volume=0
scripts/build_cuts.py の build_beep_filter() は、カットリストレンダリングの直前に挿入可能な単一のフィルター文字列を生成します。
フェーズ6 — concatフィルタでマスターをレンダリング(シングルパス)
concat デマルチプレクサは使用しないでください。 これは生のパケットを結合するだけなので、カット点でオーディオクリックが発生します。代わりに concat フィルター を使用します。これはクロスフェードせずにサンプルを再エンコードしますが、クリックも発生しません。
ffmpeg -hide_banner -y -i "$SRC" \
-filter_complex "
[0:v]trim=start=5.048:end=12.340,setpts=PTS-STARTPTS[v0];
[0:a]atrim=start=5.048:end=12.340,asetpts=PTS-STARTPTS[a0];
[0:v]trim=start=14.202:end=44.810,setpts=PTS-STARTPTS[v1];
[0:a]atrim=start=14.202:end=44.810,asetpts=PTS-STARTPTS[a1];
...
[v0][a0][v1][a1]...concat=n=N:v=1:a=1[outv][outa]"
-map "[outv]" -map "[outa]" \
-c:v libx264 -preset medium -crf 18 \
-c:a aac -b:a 192k \
-movflags +faststart \
master.mp4
scripts/build_cuts.py の render_cut_list() 関数は、この正確なコマンドを生成します。すべての trim と atrim に、adeclick フィルターを追加して、カット点で微小なクリックを捕捉します。
[0:a]atrim=start=5.048:end=12.340,adeclick,asetpts=PTS-STARTPTS[a0];
重要: 各カットの開始時に0.10秒のフェードインを使用します。これにより、カット点での過渡ノイズが抑制され、音声に「ポップ」音が入るのを防ぎます。これはソースの過渡ノイズ(フェーズ5)とは異なり、編集アーティファクトです。
[0:v]trim=start=5.048:end=12.340,fade=in:st=0:d=0.10,setpts=PTS-STARTPTS[v0];
このレンダリングは1回だけ実行します。オーバーレイは master.mp4 に追加されます。ソースが変更されない限り再レンダリングは不要です。
フェーズ7 — ヒーロー画像を生成(Gemini 3 Pro Image)
HyperFramesのテイクオーバーシーン(フルスクリーンのブランドステートメント)には、プロンプトから生成された高解像度画像が必要です。
GEMINI_API_KEY="..." python3 -c "
import google.generativeai as genai
import json, base64, pathlib
genai.configure(api_key=...)
model = genai.GenerativeModel('gemini-3-pro-image-001')
# 製品と美学についてモデルに指示する背景システムプロンプト
system = 'You generate photorealistic hero images for product launch videos. ' \
'Style: dark purple gradient background, glowing green accent lines, ' \
'floating translucent hexagonal UI panels. No text. 1920x1080.'
response = model.generate_content(
[system, 'Abstract representation of AI weaving code into executable skills, glowing purple and green threads'],
generation_config=genai.types.GenerationConfig(
response_modalities=['IMAGE']
)
)
for part in response.candidates[0].content.parts:
if part.inline_data.mime_type.startswith('image/'):
pathlib.Path('hero.png').write_bytes(part.inline_data.data)
print('Wrote hero.png')
"
ベストプラクティス:
- 画像にテキストを含めないでください。テキストはHyperFramesオーバーレイHTMLで処理します。
- 画像を
1920x1080にします。画面いっぱいに表示されるテイクオーバーはズームされません。 - 製品の主要カラーを指定します。SpecWeaveはパープルとグリーンを使用しています。
- 画像生成に失敗した場合は、Unsplash Source のようなストックフォトサービスにフォールバックします。
フェーズ8 — HyperFramesコンポジションを作成(iOSカード)
最終動画のアーキテクチャ:
┌──────────────────────────────────────────────────────┐
│ マスター動画(フルスクリーン、master.mp4) │
│ │
│ ┌────────────────────────────────────────────────┐ │
│ │ オーバーレイカード(フロストガラス) │ │
│ │ コンテナは位置: 固定、上から20%、左から5% │ │
│ │ ┌──────┐ ┌──────────────────────────────┐ │ │
│ │ │ アイコン│ │ タイトルテキスト │ │ │
│ │ │ 50x50 │ │ 説明テキスト │ │ │
│ │ └──────┘ └──────────────────────────────┘ │ │
│ └────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────┐ │
│ │ 統計カード │ │
│ │ 「600+ スキル」 「500+ コントリビューター」 │ │
│ └────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────┘
カードシステム
各カードはHyperFramesの data-hf-component を使用します。
<div class="overlay-card" data-hf-component="card" data-hf-anchor="time" data-hf-time="12.340">
<div class="card-glass">
<img src="/icons/anthropic.png" class="card-icon" />
<div class="card-text">
<span class="card-title">Boris Cherny / Anthropic</span>
<span class="card-subtitle">Developer Ecosystem, Composer Agent</span>
</div>
</div>
</div>
フロストガラス効果 (CSSは backdrop-filter: blur を使用):
.card-glass {
background: rgba(255,255,255,0.1);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border: 1px solid rgba(255,255,255,0.2);
border-radius: 16px;
padding: 12px 20px;
display: flex;
align-items: center;
gap: 12px;
}
全てのカードは絶対配置で固定 — 画面に対して、動画の時間に対してではありません。以下のプロパティを使用します。
position: fixed;
top: 20%;
left: 5%;
z-index: 10;
これにより、マスター動画の上にカードが浮かび、動画内容の変化の影響を受けません。
時間指定による表示/非表示
各カードのコンテナは、事前計算された時間範囲で表示を切り替えます。HyperFramesは data-hf-time 属性をサポートしていない可能性があるため、代わりにCSSアニメーションと data-hf-anchor を使用します。
<div class="overlay-card"
data-hf-component="card"
data-hf-anchor="time"
data-hf-time="12.340"
style="visibility: hidden;">
次に、visibility: visible でカスタムCSSアニメーションを使用します。
@keyframes show-card-1 {
0%, 99.9% { visibility: hidden; opacity: 0; }
100% { visibility: visible; opacity: 1; }
}
アニメーションの継続時間を単一のフレームに設定します(例: 1s または動画の継続時間)。実際のロジックはカットタイムラインに基づいて animation-delay を設定します。
コンポジション構造
HyperFramesプロジェクトは次のように構造化されます。
project/
master.mp4
composition.html
composition.css
heroes/
hero-0.png
icons/
anthropic.png
specweave.png
cards/
card-1.html
card-2.html
composition.html は、マスター動画、テイクオーバー、オーバーレイカード、GSAPアニメーションを1つのページに結合します。HyperFramesは npx hyperframes preview でプレビューし、npx hyperframes render でレンダリングします。
フェーズ9 — Studioでリント+検証
HyperFrames Studioで最終動画を開く前に、以下のチェックリストを実行します。
- カットされた箇所すべてで、音声にクリックやポップ音がない。
- カードがスピーカーの顔カメラを覆っていない。
- 全てのテイクオーバーシーンに画像が含まれている(空のテイクオーバーはない)。
- 時間指定のアニメーションが正しい時間にトリガーされる。
- カードが画面からはみ出していない。
- 全体的な時間が元の録画より短くなっている。
Studioのキャッシュ無効化(「難しい方法で学ぶ」落とし穴)
HyperFrames Studioは master.mp4 をキャッシュすることが多く、マスターを再レンダリングした場合でも古いバージョンを表示し続けます。
修正方法:
npx hyperframes clean # すべてのキャッシュをクリア
npx hyperframes render --force # キャッシュをバイパス
それでもStudioが古い動画を表示する場合は、master.mp4 のファイル名を変更するか(例: master-v2.mp4)、composition.html でクエリパラメータを使用します。
<video id="master" src="master.mp4?v=$(date +%s)" ...>
トラブルシューティング — よくある問題
| 問題 | 原因 | 修正方法 |
|---|---|---|
| カット点で「ポップ」音 | concat デマルチプレクサを使用(フィルタではない) | concat フィルタに変更し、adeclick を追加 |
| カードがスピーカーの顔を覆う | カードの top / left 位置が悪い | すべてのカードの絶対位置を確認、スピーカーは通常画面の中央から少し右 |
| テイクオーバーが真っ黒 | 画像が見つからないか、壊れている | hero.png が存在し、1920x1080であることを確認 |
| 最終動画が長すぎる | デッドエアがカットされていない | 無音検出のしきい値を確認、カット範囲を検証 |
| Studioがキャッシュされた動画を表示 | Studioのキャッシュ | npx hyperframes clean && npx hyperframes render --force |
スクリプト
scripts/build_cuts.py は以下の主要な関数を提供します。
probe_source(path)— フェーズ1のプローブを実行し、JSONを返します。transcribe(path)— Whisperを呼び出して文字起こしJSONを返します(フェーズ2)。detect_silences(path)— ffmpegのsilencedetectを実行し、パース済みのリストを返します(フェーズ3)。detect_scenes(path)— ffmpegのシーン検出を実行し、タイムスタンプのリストを返します(フェーズ3)。build_cut_ranges(silences, scenes, words)— 5つのルールすべてを適用してカット範囲を返します(フェーズ4)。build_beep_filter(audio_path)— 過渡ノイズを検出し、volumeフィルター式を生成します(フェーズ5)。render_cut_list(src, cuts, output)—concatフィルタでffmpegコマンドを生成し実行します(フェーズ6)。
使い方の例:
from scripts.build_cuts import probe_source, transcribe, detect_silences, detect_scenes, build_cut_ranges
meta = probe_source("obs_recording.mkv")
transcript = transcribe("obs_recording.mkv")
silences = detect_silences("obs_recording.mkv")
scenes = detect_scenes("obs_recording.mkv")
words = [(w['start'], w['end'], w['word']) for s in transcript['segments'] for w in s['words']]
cuts = build_cut_ranges(silences, scenes, words)
render_cut_list("obs_recording.mkv", cuts, "master.mp4")
キーワード索引
- スマートカット — フェーズ4、ルール1~5
- 過渡ノイズ除去 — フェーズ5、
build_beep_filter() - フロストガラスカード — フェーズ8、CSS
backdrop-filter: blur - テイクオーバーヒーロー — フェーズ7、Gemini 3 Pro Image
- 単語境界バッファ — フェーズ4、ルール4(末尾+0.30s / 開始-0.10s)
- concatフィルタ vs デマルチプレクサ — フェーズ6
- Studioキャッシュ無効化 — フェーズ9、
npx hyperframes clean