1仕組みと動作原理
「言い間違い」の処理を3ステップのパイプラインに分割:機械的な候補検出 → 必須のレビューゲート → 承認されたカット点のみレンダリング。判断はLLM/人間に、計算はスクリプトに委ねます。
### 1. Find candidates (mechanical) … ### 2. Review (the gate — REQUIRED) … ### 3. Apply approved cuts
吃音(stutter)の判定=隣接する2つの単語トークンが同一かつ間隔が0.5秒未満。デフォルトでは前者を削除し後者を残します。
const closeGap = b.start - a.end < 0.5; if (a.token === b.token && closeGap) { … // remove the first utterance, keep the second cut: { start: Number(a.start.toFixed(3)), end: Number(b.start.toFixed(3)) },
リテイクや言い直しの検出は静的なルール列挙に依存せず、ポーズ/文末/16秒の上限でチャンク分割した上で、ストップワード除外後のシグネチャを Jaccard 類似度で比較します。
if (gap > 0.85 || (sentenceEnd && elapsed >= 7.5) || elapsed >= 16) { … const stop = new Set("a an and are as at be but by for from i if in is it of on or so that this to was we with you your they their there what when where why how like um uh".split(" ")); … const score = jaccard(sigs[i], sigs[j]); const sameOpening = sigs[i].slice(0, 4).filter((t, idx) => t === sigs[j][idx]).length >= 2; if (score >= 0.34 || (score >= 0.24 && sameOpening)) {
「短い先頭チャンク + 素早い再開」を言い直し(ファルスクスタート)と判定し、種別を retake から false_start へ変更します。
const isFalseStart = sameOpening && firstLen < 6 && segments[j].start - segments[i].end < 12; … type: isFalseStart ? "false_start" : "retake",
検出器は「決定を行わない」ことを明示しており、強調のための重複と言い間違いが機械的に同形となるため、SKILL.md は文脈を1件ずつ確認することを義務付けています。
This is MECHANICAL detection only. It proposes candidate cut ranges with rich … context + a confidence + a default recommendation, but it does NOT decide.
承認リストは apply-cuts.mjs を通じて EDL + リタイム済み文字起こしに変換されます。--apply 指定時のみ ffmpeg trim/atrim + concat でレンダリングし、デフォルトはドライランです。
if (approved.some(c => c.start < 0 || c.end > duration)) die('Cut range is outside source duration bounds'); … lines.push(`[0:v]trim=start=${r.start.toFixed(3)}:end=${r.end.toFixed(3)},setpts=PTS-STARTPTS[v${i}];`); … const ff = spawnSync("ffmpeg", ["-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], { stdio: ["ignore", "ignore", "inherit"] });
2コア機能
3外部依存関係
| Kind | Dependency / Endpoint |
|---|---|
| cli | Node.js(跑两个 mjs 脚本) |
| cli | ffmpeg(trim/atrim + concat 渲染,libx264/aac) |
| cli | ffprobe(转录未带时长时探源片时长) |
| cli | npx serve(只服务本地审查页 HTML,非上传) |
| cli | node scripts/build-edl-review.mjs(仓库级共享复核工具,不在本 skill 目录内) |
4推奨統制措置と判定根拠
- scripts/: ローカルスクリプトまたはコマンドの実行: node .claude/skills/cut-mistakes/scripts/find-cut-candidates.mjs <transcrip
- 网络端点: 外部ネットワークアクセスの宣言: 唯一の HTTP 面は人間による確認フェーズの `npx serve . -p 8080 -n` のみ(ローカル静的サーバーで、生成済みレビューHTMLを配信するだけでメディアのアップロードは行いません)
- 本地工作目录: ファイル読み書きおよび成果物出力: <stem>.cut-candidates.json / <stem>.cut-candidates.md(デフォルトでは文字起こしと同じディレクトリ、または --out-dir に出力)
5二重目の独立検証
- [ok] 目录文件清单与产物对照 — 3 个文件(SKILL.md、find-cut-candidates.mjs、apply-cuts.mjs);SKILL.md 承诺的 *.cut-candidates.json/.md 与 *.mistakes-edl.json/transcript.json/decisions.md/filter.txt 均在两个脚本的 writeFileSync 目标中逐一定位到。
- [ok] 网络面反例搜索 — 目录内 0 处 fetch/https 导入;唯一 URL 形态字样是 SKILL.md 的本地命令 `npx serve . -p 8080 -n` 与仓库级脚本名,不构成执行期外发。
- [ok] 凭证面反例搜索 — 0 处 process.env/API_KEY/TOKEN/.env;spawnSync 列表仅 ffprobe/ffmpeg,环境变量未被子进程继承修改。
- [ok] 「只渲染已批准切点」是否被代码强制 — apply-cuts.mjs 第 49-51 行以 --cuts 文件为唯一输入并校验数组与非空范围;find-cut-candidates.mjs 不含任何写视频/批准逻辑,两脚本互不自动串接。
- [ok] 文档参数 vs 脚本 argv — find 脚本解析 <transcript> 与 --out-dir(Usage 行自述一致);SKILL.md 给的命令两种形态都能对上。apply-cuts 解析 --cuts/--video/--output/--out-dir/--apply,与 SKILL.md 的调用示例逐项一致。
- [ok] 上游转录服务是否被算作本 skill 行为 — SKILL.md 只写「Requires a word-level transcript」,未指名任何服务或 key;ElevenLabs helper 属仓库级 scripts/,故按『判级对象=skill 自身目录』记入 reason/risks 而不改档。
6結論
fca023adfb7af7d9…