コンテンツ制作 · nateherkai/hyperframes-student-kit

cut-silences

動画編集パイプラインの Agent 1。トーキングヘッド(語りかけ)動画の録音から無音部や不要な間(デッドエア)を削除します。単語レベルの文字起こしに基づき、無音のカット、ポーズのトリミング、ギャップの除去、または素材動画のテンポ感を引き締めたい場合に使用します。編集リスト(EDL)、後続エージェント用のタイムスタンプ再同期済み文字起こし、およびオプションとして ffmpeg を介したカット済み動画を生成します。言い間違い、重複、言い直し(false start)のカットは行いません(それは cut-mistakes エージェントの役割です)。

L4 高権限 · 段階的認可と監査V1 コミット固定コマンド実行ネットワーク通信ファイル書き込みDual-pass Audit
Author nateherkaiGitHub nateherkai/hyperframes-student-kit ↗Stars 1070License NOASSERTION(仓库根 LICENSE,实为 MIT 文本)Commit 0d30152a82
管理レベルは Skill の能力と推奨統制措置を示すものであり、品質や安全性の認証、利用可否の判定ではありません。使用の可否はユーザーおよび管理者が決定します。Agent 環境によって制約が異なるため、自動保護を仮定しないでください。第三者製 Skill の著作権は原著作者に帰属し、利用リスクは利用者が負います。

1仕組みと動作原理

パイプライン全体はモデルによる推論ではなく決定論的アルゴリズムに基づいて動作します。先頭・末尾のデッドエアと --gap を超える単語間のポーズのみを処理し、発話内容は一言も変更しません。

.claude/skills/cut-silences/scripts/cut-silences.mjs
Pure pause/silence trimmer. Takes any word-level transcript (ElevenLabs Scribe … shape, or { words: [{ text, start, end }] }) and removes silences only:
同じコメント内で「It does NOT cut repeats, false starts, or mistakes — that is Agent 2's job.(重複、言い直し、間違いはカットしません。それは Agent 2 の仕事です)」と明確に境界付けられています。出力は完全に再現可能であり、パイプラインの第1段階に最適です。

先頭および末尾のデッドエアは --head-pad / --tail-pad に従って直接カットされ、2つの独立した削除区間としてマージ処理に送られます。

.claude/skills/cut-silences/scripts/cut-silences.mjs
// head + tail dead air const headEnd = words[0].start - opts.headPad; if (headEnd > 0) deleteRanges.push({ start: 0, end: headEnd, reason: "head trim before first word" });
SKILL.md のパラメータ表に基づき、デフォルトの head-pad は 0.22 秒、tail-pad は 0.34 秒です。動画が存在しない場合は、文字起こしに含まれる audio_duration_secs または最後の単語の end タイムスタンプがフォールバックとして使用されます。

単語間のポーズは完全にゼロにするのではなく、文脈に応じて「自然な呼吸」の間(長めのポーズ: 0.24秒、文末: 0.20秒、その他: 0.14秒)を保持します。

.claude/skills/cut-silences/scripts/cut-silences.mjs
if (gap < opts.gap) continue; … const sentenceBreak = /[.!?]$/.test(prev.text ?? ""); const keep = gap >= 2 ? 0.24 : sentenceBreak ? 0.2 : 0.14;
--gap(デフォルト 0.55秒)未満のポーズには一切手を加えません。これは「話し言葉のリズムを保つ」ための閾値です。--gap を小さくするとテンポは締まりますが、不自然に細切れになるリスクが高まります。

残される呼吸の間は、意図的に後続文の冒頭側に寄せられます(前文の末尾側に 55%、後続文の先頭側に 45% を配分)。

.claude/skills/cut-silences/scripts/cut-silences.mjs
// Bias the kept breath slightly toward the end of the previous phrase. const delStart = prev.end + keep * 0.55; const delEnd = next.start - keep * 0.45;
これは聴感上の配慮です。前文の語尾余韻のあとに余裕を持たせることで、次の文の立ち上がり(アタック音)が削られるのを防ぎます。

削除区間をマージした後に補集合を計算して保持区間(keep ranges)を取得し、40ms 未満の断片的な区間は破棄します。

.claude/skills/cut-silences/scripts/cut-silences.mjs
if (cursor < duration) keepRanges.push({ start: cursor, end: duration }); const usableKeepRanges = keepRanges.filter((r) => r.end - r.start >= 0.04);
補集合アプローチにより、EDL は削除リスト兼保持リストとして機能します。40ms の下限設定により、ffmpeg が意味のない極小スライスを生成するのを防ぎます。

文字起こしは同一の削除リストに基づいて編集後のタイムラインに再マッピングされ、元動画との照合用に source_start / source_end が保持されます。

.claude/skills/cut-silences/scripts/cut-silences.mjs
const editedWords = []; for (const word of words) { if (inDeleted(word)) continue; … start: Number((word.start - removedBefore(word.start)).toFixed(3)),
removedBefore(t) は時刻 t より前に削除された秒数を累積する線形マッピングと同等です。これにより、後続のビート検出や validate-beat-sync.mjs での再計算が不要になります。

レンダリングには ffmpeg の trim/atrim + concat フィルターグラフを使用します。一度 *.silence-filter.txt に書き出してから -/filter_complex 経由で渡し、デフォルトではレンダリングを実行せず計算のみを行います。

.claude/skills/cut-silences/scripts/cut-silences.mjs
lines.push(`[0:v]trim=start=${r.start.toFixed(3)}:end=${r.end.toFixed(3)},setpts=PTS-STARTPTS[v${i}];`); … const ffArgs = [ "-y", "-i", videoPath, "-/filter_complex", scriptPath, "-map", "[v]", "-map", "[a]", "-c:v", "libx264", "-preset", "medium", "-crf", "18", "-c:a", "aac", "-b:a", "192k", "-movflags", "+faststart", outputPath, ];
映像と音声を同一の区間セットで同期トリミングし、音ズレ(A/V ドリフト)を防ぎます。--apply が指定されない場合は「hint: re-run with --apply to render the cut video」というヒントを出力するのみにとどまります。

2コア機能

01先頭・末尾のデッドエアおよび閾値を超える単語間ポーズのカット(純粋な無音のみ、単語自体は無変更)
02単純なゼロ間隔化ではなく、文脈に応じた「自然な呼吸」(長ポーズ/文末/その他の3段階)の保持
03後続処理や手動レビューで直接利用可能な EDL(削除区間+保持区間+パラメータ+再生時間)の出力
04Agent 2 やビート同期検証へ引き渡すタイムスタンプ再同期済み文字起こしの生成(再度の時間合わせが不要)
05過剰カットを抜き取り確認できる人間可読な決定サマリー(カットされた上位15箇所の最大ポーズを含む)の提供
06ドライランとレンダリングの分離:デフォルトでは EDL・文字起こし・サマリーの書き出しと ffmpeg コマンドの表示のみを行い、--apply 指定時のみ動画を処理
07パラメータ調整(--gap / --head-pad / --tail-pad / --output / --out-dir)と推奨プリセット値の提供
08複数の単語レベル文字起こし形式(ElevenLabs Scribe / 汎用形式)への対応、および type による非単語イベントのフィルタリング

3外部依存関係

KindDependency / Endpoint
cliNode.js(跑 cut-silences.mjs)
cliffmpeg(trim/atrim + concat 重编码,仅 --apply 时执行)
cliffprobe(无 audio_duration_secs 时探源片时长)
apiElevenLabs Scribe(**前置步骤**:由仓库级 scripts/transcribe-elevenlabs.mjs 上传音频取词级时间戳;本次侦察未在本 skill 目录内发现任何调用代码)
cli本地 Whisper / whisper.cpp(文档列出的无 key 替代转录路线)

4推奨統制措置と判定根拠

安全運用のための推奨統制措置
Agent 向け
段階的・都度認可、サンドボックス推奨
管理者向け
承認フロー、ロールバック可能、全履歴監査
判定根拠(ファイルパスと抜粋)
  • scripts/: ローカルスクリプトまたはコマンドの実行: node .claude/skills/cut-silences/scripts/cut-silences.mjs <transcript.json>
  • 网络端点: 外部ネットワークアクセスの宣言: 前提ステップの外部エンドポイント(リポジトリレベルのヘルパーによるもので、本ディレクトリ内ではありません): api.elevenlabs.io/v1/speech-to-text(音声を POST して単語レベルの文字起こしを取得)
  • 本地工作目录: ファイル読み書きおよび成果物の出力: <stem>.silence-edl.json(保持/削除区間 + パラメータ + 再生時間)
監査ノート: 評価対象は本スキル自身のディレクトリ(SKILL.md + 11.8KB の mjs ファイル1つ)です。唯一の実行可能コードは完全なローカル Node スクリプトであり、単語レベルの文字起こしを読み込み、区間を計算し、EDL・文字起こし・サマリー・フィルターを出力します。生成されるサブプロセスは固定バイナリである ffprobe と ffmpeg の2つのみで、ネットワーク呼び出し 0 件、認証情報の読み込み 0 件、環境変数へのアクセス 0 件、削除や破壊的操作も 0 件です。明記すべき点として(ただし**リスク評価の引き上げ要因とはしません**)、SKILL.md の前提条件(Prerequisites)には文字起こし取得のためにリポジトリレベルの `scripts/transcribe-elevenlabs.mjs` が指定されており、このヘルパーは ELEVENLABS_API_KEY を読み取り、音声を api.elevenlabs.io にアップロードします(素材の外部送信とクレジット消費を伴います)。ただしこれは本スキルのディレクトリ外にあり、本スキル自体は「任意の単語レベル文字起こし」のみを要求し、汎用の `{ words: [...] }` や API キー不要のローカル Whisper も明示的にサポートしているため、文字起こしは本スキルの責務ではなく上流の成果物とみなされます。同時に評価された edit-video(🟠)との違いはまさにここにあり、edit-video の SKILL.md では外部サービス呼び出しがメインフローのステップ2に組み込まれ、コストや認証に関する説明も同梱されています。

5二重目の独立検証

  • [ok] 目录文件清单与 Outputs 表对照 — 目录仅 SKILL.md + scripts/cut-silences.mjs;SKILL.md 列出的 5 类产物中 3 类无条件写、filter.txt 与 mp4 受 --video/--apply 门控,与源码 writeFileSync/spawnSync 分支一致。
  • [ok] 网络面反例搜索 — 目录内 0 处 fetch/URL/网络模块导入;SKILL.md 出现的 `node scripts/transcribe-elevenlabs.mjs ...` 是仓库级前置命令,文件名不含 http,且未被本脚本引用。
  • [ok] 凭证面反例搜索 — 0 处 process.env/API_KEY/TOKEN/.env;脚本对 process 的导入仅 argv/exit(`import { argv, exit } from "node:process";`)。
  • [ok] 「只删沉默」是否被代码强制 — 删除区间只由 head/tail pad 与 gap>opts.gap 的停顿生成三处 push 产生,源码无重复词/相似度/语义判断,与文档声明一致,无夸大。
  • [ok] 重定时映射正确性 — start = word.start - removedBefore(word.start),removedBefore 只累加严格位于其前的删除量,因此不会出现负值或跳变;edited_duration = duration - removedTotal 与被删总量自洽。
  • [ok] 文档参数 vs 脚本 argv — --video/--out-dir/--output/-o/--gap/--head-pad/--tail-pad/--apply 全部在 argv 解析中定位到,未知 --flag 会 die,与 SKILL.md 表格一致。

6結論

  • 完全な決定論的アルゴリズムでモデルによる推論を含まないため、第1段階において完全な再現性とリグレッションテストが可能。実行環境に依存せず常に同一の結果が得られます。
  • 聴感上の配慮が徹底されており、文脈に応じて 0.24 / 0.20 / 0.14 秒の呼吸の間を残し、余白を後続文の冒頭側に寄せる配分(55% / 45%)を行うことで、機械的な「間ゼロ化」よりも遥かに自然に仕上がります。
  • 生成物の監査性が高く、EDL には params / removed / removedPct が含まれ、decisions.md にはカットされた上位15箇所のポーズが記録されるため、過剰なカットがないか素早く確認できます。
  • 再同期済み文字起こしにより、タイムライン調整のオーバーヘッドを第1段階で完結させ、後続のビート検出や納品前検証での再計算コストをゼロにします。
  • 豊富な調整ノブと実践的な推奨値(--gap 0.55 で純粋な無音を約15〜20%削減)が用意されており、カットが過剰だった場合の2つの修正指針も示されています。
  • 最適な用途: 適しているケース:単語レベルの文字起こしがあるトーキングヘッド長尺動画の初期ラフカット(15〜20%の純粋な無音の自動除去)、監査可能な EDL を必要とするパイプライン、およびマルチエージェント動画編集ワークフローの決定論的な起点。
    不向きな用途: 適していないケース:単語レベルのタイムスタンプがない文字起こし(段落レベルや通常の SRT は不可)、言い間違いや録り直しの削除が必要な場合(cut-mistakes の担当)、すべての呼吸の間を完全に残す必要がある対談インタビュー、およびスクリプト自体に「どこをカットすべきか」の判断を期待するシナリオ(本スキルは数値ルールにのみ従います)。
    Install Agent-Ready
    ① Verified Mirror 2026-09-28
    Option A · Direct DownloadDownload cut-silences.tar.gz
    sha256: 484001b000655549…
    Option B · Copy Guide for Agent
    install.json
    Agent はこの JSON ガイドから自動的にダウンロードして検証します。
    ② Upstream GitHub
    GitHub Repo ↗
    Pinned to commit 0d30152a82.