---
name: gitruck-gtrk-oralcut
description: "智能口播剪辑闭环——开剪前主动检查同目录独立口播音频，有则先对轨换声，再通过同合云剪掉废话/重复/长停顿，产出客户端(gtrk)+剪映+PR 三方工程。当用户想「剪口播/剪个视频/智能剪辑/去掉废话和停顿/把这条口播剪一版/出剪映草稿/生成剪辑工程/oral cut」时使用本 skill。凡涉及把口播毛片做成可二次精修的剪辑工程，优先用本 skill 驱动 gtrk CLI，不要手搓 ffmpeg。"
license: "MIT"
metadata:
  decimalai-skill-id: "aff81c08-7f75-4510-a564-937580f18d7d"
  decimalai-version-id: "25949db3-b015-43a1-a18b-0743691315ee"
  decimalai-version: "2"
  decimalai-body-sha256: "f1e3da895990c6a24e4cf3a9643697f2c8d0b4cf6e8b8a85eba3488b507b8125"
  decimalai-name: "gitruck/gtrk-oralcut"
  decimalai-format: "1"
  decimalai-invocation: "model"
  decimalai-category: "design-media"
  decimalai-source: "https://app.decimal.ai/s/gitruck-gtrk-oralcut@2/SKILL.md"
---
# 口播剪辑（gtrk-oralcut）

> **⚠️ 用户要的是「完整包装的成片」而非只剪干净？先去 `/gtrk-talking-head`（口播链图纸）。**
> 那张图纸把本命令接进全链：外录音轨对轨换声 → 多段拼接 → 本命令粗剪 → 拆分/B-roll/字卡/BGM/字幕 → 客户端出片。
> 本 skill 是**命令手册**（怎么跑 oralcut），那张是**场景图纸**（怎么串全链），配合用不冲突。

把用户的口播毛片，用 `gtrk` CLI 跑通「**检查独立口播音频 →（如有）先对轨换声 → 本地抽音频/720p → 只传抽出物（毛片永不上传）** → 云端智能口播剪辑 → 拉回三方工程文件 →（可选）**本地 ffmpeg 渲染成片**」，再把产物目录 + 三端打开方式回给用户。**CLI 是手、你是脑。**

> **本 skill 已含你需要的全部信息**（参数、取值、执行、读报告、排错），照它做即可，不用也无法去查外部文档。（源仓库另有一份更全的工具无关版 `AGENT.md`，那是给在仓库里开发的人看的，与你无关。）

## 前置：CLI 装没装 + 体检

先跑 `gtrk doctor`（它顺带验证 `gtrk` 命令本身在不在）：
- **`gtrk` 找不到 / command not found** → CLI 没装 → 让用户装 `npm i -g @gitruck/cli@latest`（需先有 Node.js），再重试。
- 报「缺 API Key」→ 让用户先跑一次 `gtrk init`（一次性配 Key + 剪映目录，**交互式、需真终端**，你别替他跑）。
- 报云端连不上 / 剪映目录没配 → 照提示让用户处理。
- 全绿就往下走。

### ffmpeg 依赖（本地抽音频 / 渲染必需，缺了你来装）

oralcut 现在**本地预处理**（探原片几何 + 抽 16k 单声道 mp3 / 压 720p 代理）和 **本地渲染**都靠 `ffmpeg`/`ffprobe`。看 `gtrk doctor` 里「本地渲染 (ffmpeg)」这行：

- **已就绪** → 往下走。
- **未找到** → 你来装（CLI 不自下不自分发）：**先确认确实没有**（doctor 已查过 `~/.gitruck/ffmpeg` 与系统 PATH），缺了再拉 `ffmpeg` + `ffprobe` 两个可执行文件放到 `~/.gitruck/ffmpeg/`（Windows 即 `ffmpeg.exe`/`ffprobe.exe`）。
  - **国内用户优先国内加速站点**：GitHub 官方静态构建（BtbN / gyan.dev）直连慢，走 GitHub 加速代理（pass-through）或同合云自建镜像拉，下载后**核对 sha256**。
  - 装好复跑 `gtrk doctor` 确认转绿。
- 用户自己装过 ffmpeg 并配了 PATH → doctor 会从系统探到直接用；**绝不去改用户的环境变量/PATH**（CLI 一律绝对路径调用）。若装在别处，用 `--ffmpeg-path <目录>` 指给它。

## 开剪前硬闸：主动发现独立口播音频，先对轨再 oralcut

**无论用户有没有主动提到外录音频，执行 agent 都必须在第一次 `gtrk oralcut` 之前检查毛片所在目录。** 用户给的是目录时，先列出其中的视频与音频；用户给的是单个视频时，也要查看它的同目录。识别 `wav / mp3 / m4a / flac` 等独立音频，并按文件名、同一拍摄批次与数量关系判断是否是该视频的口播外录：

- 唯一视频 + 唯一口播音频，或名称可明显配对（如 `03思考_视频_V01.mp4` ↔ `03思考_音频_V01.flac`）→ **直接视为一组，不用反问用户**。
- 多个视频/音频且配对有歧义 → 在任何上传或 oralcut 计费前，让用户确认映射关系。
- 文件名/上下文明确是 BGM、配乐、伴奏或环境声 → 不是口播外录，不走对轨。

发现可配对的独立口播音频后，固定顺序：

```bash
gtrk audio align "<毛片>" "<外录>" --json
gtrk oralcut "<align 结果 JSON 的 output，即 *_extaudio.mp4>" [原有参数…] --json
```

- **MUST 先 align、再 oralcut。MUST NOT 先剪机内声，事后再把外录硬塞进工程或另剪一版补救。** align 产物已经把外录换进视频，后续 oralcut 的每个画面切点会天然同步作用到外录声。
- align 高置信自动完成时，后续输入必须切换为结果 JSON 的 `output`，不要继续拿原毛片跑 oralcut。
- align 低置信时会产 `*_align.gtrk`：停下让用户在客户端拖齐并保存，再跑 `gtrk audio align --resume "<对齐工程>" --json`；拿到换轨产物后才允许继续 oralcut。
- align 失败时如实停下排错；除非用户明确同意，**不得静默回退到机内声开剪**。
- 换轨产物是后续工程依赖素材，必须提醒用户留存；原毛片保留不动，作为内录保底。
- **文稿路径要在换轨前记住**：若原毛片靠同名 `.txt` 自动探稿，换轨后的 `_extaudio.mp4` 通常匹配不到原同名文稿，后续必须显式传 `--script "<原文稿路径>"`。

没有发现独立口播音频，才直接对原毛片执行 oralcut。

## 把用户的话变成一次调用

> **每次调用都必须带 `--json`**（成功时 stdout 只出一行结果 JSON、人读日志转 stderr），你才能解析结果 + 读报告。不是可选项。

从用户消息里取这几样，缺关键的就问：

1. **毛片路径**（必需）：口播原视频的本地路径。没有就问。
2. **文稿**：用户给了逐字稿/文字稿**文件** → `--script <txt文件路径>`（接的是 .txt 文件路径，不是稿子正文）；没给则不传（CLI 会探毛片同名 `.txt`，有就自动按有稿剪、更准；无则云端无稿智能重建）。
3. **节奏**：用户说「快/紧凑/卡点狠」→ `--preset compact`；「稳/别删太多停顿」→ `--preset steady`；没特别说就不传（CLI 默认 `concise` 精练）。
4. **只要某端**：只要客户端 → `--formats gtrk`；只要剪映 → `--formats jianying`；只要 PR → `--formats xml`（全部格式见下表、逗号可多选）；默认三端全给（`gtrk,jianying,xml`）。

## 完整参数规格 —— 按用户需求因势象形、自由组合

**你手上有云端全部参数（下表）。按用户的具体诉求自由决定用哪些、怎么配——需要就调、没提就跑默认（默认已是给多数人调好的）。** 只有一条要求：**名字 / 取值 / 范围照下表用**（别记错拼错）；万一传越界，云端会报 `6016` 并附具体原因，照着改即可——乱传不会产出错误成片，只会明确报错。

| 用户想要 | CLI 怎么传 | 取值 · 默认 | 说明 |
|---|---|---|---|
| 有稿对齐（更准） | `--script <txt>`（或毛片同名 `.txt` 自动） | 10–50000 字 · 缺省无稿重建 | 有稿逐字对齐质量最佳；无稿智能重建终稿 |
| 换语种 | `--lang <码>` | `zh-CN`/`en-US`/`ja-JP`… · 默认 `zh-CN` | 不传即 CLI 默认发 `zh-CN`；主推中文，余语种尽力而为 |
| 产哪些工程格式 | `--formats <逗号列表>` | `xml`/`fcpxml`/`otio`/`jianying`/`capcut`/`gtrk` · CLI 缺省 `gtrk,jianying,xml` | 可多选 |
| 顺带出成片视频 | `--render` | 开关 · 缺省不渲 | **本地** ffmpeg 按 gtrk EDL 渲染 mp4（毛片仍不上传、云端不渲染）；需 ffmpeg 就绪 |
| 成片画质 | `--crf <n>`（配 `--render`） | 整数 14–28 · `18` | 本地渲染用；越小越清晰 / 越大体积越小 |
| 成片编码 | `--codec <c>`（配 `--render`） | `h264` · `h264` | 本地渲染用；当前仅 h264 |
| 指定 ffmpeg 位置 | `--ffmpeg-path <目录>` | 路径 · 缺省 `~/.gitruck/ffmpeg`→系统 | 用户 ffmpeg 装在非标准位置时指给它 |
| 节奏松紧 | `--preset <名>` | `steady`/`concise`/`compact` · 默认 `concise` | 不传即 CLI 默认发 `concise`（精练）；见下方预设表，铺底后可逐项覆盖 |
| **剪不准 / 剪掉真内容 / 有话没剪进去** | `--visual-assist` | 开关 · 关 | 开则**本地改传 720p 代理**（非上传原片）+ **视觉找补兜底**：画面说话检测保护疑似漏识别段不被误剪并重识别捞回（需说话人面部基本可见）；上传体量比纯音频大、处理耗时增加，但不额外计费、绝不凭空生成 |
| 别随说话人节奏自适应 | `--no-adaptive-rhythm` | 一元 flag：传即关闭 · 自适应默认开 | 是否定 flag（不接受 `=值` 赋值）；关了改用固定标点停顿表 |
| 剪映草稿目录（非标准位置） | `--jianying-draft-dir <目录>`（或 `auto`） | 路径 · 读 init 配置 / 自动探测 | 出剪映可直开草稿需要它 |
| 工程落盘到别处 | `--out <目录>`（或 `-o`） | 路径 · 缺省 `<毛片同目录>/<毛片名>-video-project-<时间戳>` | 想把产物放指定位置时用 |

**更细的节奏散参数**（无一等 flag，用 `--param 键=值` 或嵌套 `--params-json`）：

| 参数 | 传法 | 取值 · 默认 | 说明 |
|---|---|---|---|
| `punctuation_breaks` | `--params-json '{"punctuation_breaks":{"。":0.6,"，":0.3}}'` | 每标点 0–5 秒 · 见预设表 | 逐标点停顿；键只能是 `，、；：。！？—……` 和 `paragraph`（段落） |
| `intra_gap_max` | `--param intra_gap_max=0.4` | 0–5 · `0.35` | 句内停顿超此值算气口、触发收紧 |
| `intra_gap_target` | `--param intra_gap_target=0.05` | 0–5 且 <max · `0.10` | 气口收到的目标秒数 |
| `pad_in` / `pad_out` | `--param pad_out=0.15` | 0–5 · `0.05` / `0.08` | 保留片段头 / 尾呼吸留白 |
| `render.audio_crossfade_ms` | `--params-json '{"render":{"audio_crossfade_ms":12}}'` | 0–50 · `8` | 切点淡化毫秒，`0`=硬切；**需配 `--render`**（属成片音频淡化，不开 --render 云端忽略此字段） |

**节奏预设表 · 完整值**（选最贴内容类型的，再逐项覆盖散参数；「默认」列 = 不选预设时的基线，也即各标点的默认停顿）：

| 参数（秒） | `steady` 稳健 | `concise` 精练 | `compact` 紧凑 | 默认 |
|---|---|---|---|---|
| 适用 | 讲述 / 教学 | 自媒体中长视频 | 短视频 / 广告 | 通用 |
| `、` / `，` / `；` | 0.18 / 0.25 / 0.36 | 0.12 / 0.18 / 0.26 | 0.06 / 0.08 / 0.12 | 0.15 / 0.20 / 0.30 |
| `：` / `—` | 0.45 / 0.55 | 0.32 / 0.40 | 0.15 / 0.18 | 0.35 / 0.45 |
| `。` `！` / `？` | 0.55 / 0.60 | 0.40 / 0.45 | 0.18 / 0.20 | 0.45 / 0.50 |
| `……` / `paragraph`（段落） | 0.75 / 1.20 | 0.55 / 0.90 | 0.25 / 0.40 | 0.60 / 1.00 |
| `intra_gap_max` / `intra_gap_target` | 0.45 / 0.15 | 0.35 / 0.10 | 0.25 / 0.05 | 0.35 / 0.10 |
| `pad_in` / `pad_out` | 0.05 / 0.10 | 0.05 / 0.08 | 0.03 / 0.05 | 0.05 / 0.08 |

> **因势象形举例**：「教学口播、别删太狠、句号后多顿一下」→ `--preset steady --params-json '{"punctuation_breaks":{"。":0.7}}'`；「英文短视频卡点狠、顺便渲染成 mp4」→ `--lang en-US --preset compact --render`；「上次有句话没剪进去」→ `--visual-assist`。用户**自己点名**某参数+值 → 照他原样 `--param`/`--params-json` 透传（CLI 底层支持任意云端参数）。
>
> **以上就是你需要的全部参数——本 skill 自足，别去别处查**（`gtrk oralcut --help` 也随时列全部 flag）。官网另有一份面向开发者的原始 HTTP API 文档，那是给人看的，你不必也无法访问。

## 执行（每次都带 `--json`）

> **产物落点纪律（MUST · 全文见随包 `AGENT.md` 同名一节）**：交付物只写入工程目录或用户显式指定的输出路径；引用媒体用原路径，不复制到 agent 工作目录；临时文件放系统 temp，用完即删。
> 交付物 MUST NOT 先写 agent 自有目录再拷进工程；中转本身即违规，体积不是豁免理由。

```bash
gtrk oralcut "<毛片绝对路径>" [--script "<txt路径>"] [--preset steady|concise|compact] [其它参数…] --json
```

- `--json`：人读日志走 stderr，**成功时 stdout 只有一行结果 JSON**：
  `{ ok, outDir, files:{gtrk:[],jianying:[],xml:[]}, jianyingDraftPath, rendered, report, errors, taskId, fileId, pricing }`（`rendered`=本地渲染成片路径，未开 `--render` 时为 `null`）
- **计费**：按上传物音频时长（≈毛片时长）计。CLI 在抽音频之前查一次实时价格，往 stderr 打一行「计费提示」（单价 + 本次预估积分），`--json` 结果的 `pricing` 里也有；给用户交代时**原样转述**，别自己报数字、别引用旧价。查不到时这一行是「实时价格暂不可用，以服务端结算为准」，照实说即可。
- **想先报价再开跑**（用户问「要花多少」、长片要先确认）：同一条命令加 `--dry-run`，只探测并报价，零抽取、零上传、零计费、不建任何目录，`--json` 时 stdout 一行 `{ok, dry_run:true, source, duration, pricing}`。
- **命令失败**（毛片路径错 / 鉴权失败 / 参数越界 6016 等）→ **进程非 0 退出、报错打到 stderr、stdout 无 JSON**。先看退出码，非 0 就把 stderr 的报错如实回给用户、别当成功。
- 默认会自动打开产物目录（用户能直接看到文件）；纯脚本/无头环境才加 `--no-open`。
- 云端处理是分钟级，耐心等命令返回。
- **毛片 > 2 小时跑不了**：CLI 在上传前就会拦下（零抽取、零上传、零扣费），不是跑到一半才失败。
  遇到超长毛片**先分段再逐段剪**，切段用流拷贝、秒级完成、不重编码：
  `ffmpeg -ss 0 -t 2400 -i "<毛片>" -c copy "<毛片名>_seg01.mp4"`（2400s = 40 分钟/段）。
  各段各出一份工程，逐段精修互不影响。

## 跑完读报告、给用户交代、按需调整（因势象形的另一半）

`--json` 的 stdout 那行带 **`report`**（云端返回的原始剪辑报告对象，字段按需读、个别可能缺，读前判空）——读它，别只回一句"剪好了"：

- `duration_before` → `duration_after`：剪了多少（如 114.7s → 68.6s）。
- `script_source` + `final_script`：终稿来源与内容（`script_source`=`user` 用户给稿 / `rebuilt` 智能重建）。**无稿重建（`rebuilt`）时务必把 `final_script` 回给用户核对**——那是机器猜出来的终稿，可能跟本意有出入。
- `dropped[]`：剔掉了哪些段（元素 `{start,end,asr_text,reason}`，`reason`：`retake` 重读 / `misread` 口误·弃读·终稿外内容）——可挑几条告诉用户「去掉了这些重录 / 口误或非终稿内容」。
- `coverage`（0–1）：终稿覆盖率。**低于 0.6（附 `low_coverage`）= 文稿与实拍严重不符** → 提醒用户核对文稿、或考虑无稿重跑。
- `uncovered_script[]`：**文稿里有、实拍没找到的段（漏读）** → 如实告诉用户「『xx』这段没在录像里找到」；疑似是漏识别而非真漏读时，建议加 `--visual-assist` 重跑。
- `review_points[]`：建议人工复核处（`{time,note}`，识别置信度偏低）。
- `insufficient_breaks[]`：源素材留白不足、停顿没达到设定值的位置（`{time,want,got}`）——想让停顿更足可调 `--preset`/散参数，但受原素材限制。
- `rhythm_preset`（实际采用的预设名、无预设为 `null`）/ `adaptive_rhythm`（自适应是否生效；生效时另有 `pause_profile` 说话人停顿画像，调参参照）/ `analysis_degraded`（是否降级到纯机械规则）。
- 开了 `--visual-assist`：`suspect_omissions` / `stt_recovered`（找回了哪些字）/ `visual_assist_degraded`。
- `ok`：`true` = 全部格式成功、`errors` 为空；只要有一个格式失败 `ok` 即 `false` 且 `errors` 非空（其余格式仍可用）→ 如实说哪个格式没出来、为什么，别谎报三端都好。

**据此因势象形调整**（同一毛片可反复剪对比）：覆盖率低 / 漏读多 → 开 `--visual-assist` 或核对文稿重跑；节奏不满意 → 调 `--preset` / 散参数重跑；某格式失败 → 补 `--jianying-draft-dir` / `--reupload` 重跑。

跑完确认 `files.gtrk[0]` 在；要剪映确认 `jianyingDraftPath` 非空。

## 回给用户（三端打开方式）

- **客户端**：在同合云桌面客户端（OpenCut Gitruck Edition）里「打开工程」选 `files.gtrk[0]`（…/gtrk/project.gtrk）。
- **剪映**：已自动落到剪映草稿目录（`jianyingDraftPath`），开剪映在项目列表里找与 `jianyingDraftPath` 末级目录**同名**的草稿即可。
- **PR/FCP**：Premiere 里「文件 > 导入」`files.xml[0]`（…/xml/premiere.xml）。
  同时提醒用户：若导入时弹出「链接媒体」框（素材被移动、改名，或路径在这台机器上无效），链接前先确认目标文件；勾着「自动重新链接其他媒体」时，Premiere 会按**文件名**在所选位置查找其余缺失素材并自动链上，链错也不提示——同合云素材多以编号命名，不同工程里同名文件很常见，链完要在项目面板「媒体路径」列逐条核对，拿不准就取消该选项、逐个链接。用户反馈 PR 里素材脱机时，先问素材是否移动过、路径在这台机器上是否有效；**MUST NOT** 建议勾「自动重新链接其他媒体」一把链完。

产物目录名形如 `<毛片名>-video-project-<时间戳>`，靠文件名 + 时间认出是哪一次剪辑。时间戳只精确到秒，同一目录下同名毛片同一秒再起一次（如 `clip0.mp4` 与 `clip0.mov` 并行）时，后到的那份追加 `-2`。剪映草稿根是所有毛片共用的一层目录，不同目录下的同名毛片（换卡后重复的 `C0001.MP4` 之类）同秒开剪也会撞名：后到的那份草稿改叫 `…-2`，原草稿不动。最终落点以 `outDir` 与 `jianyingDraftPath` 为准，别按名字去猜。

## 下一步（按请求范围决定接不接力）

口播工程剪好，可能就是用户要的全部，也可能只是成片一条龙的第一站。确认 `ok=true`、`files.gtrk[0]` 与 transcript 就绪后，**看用户这次要多少**：

- **请求覆盖下游 → 顺势接力**：用户要成片、出片、完整包装、一条龙，或点名要 B-roll、字卡、BGM、字幕中的任一项；或这个会话里先前已说过「一路做到成片」。这时不追问「要不要继续」，直接触发 `/gtrk-splitter`（把这条工程 + transcript 拆成 beat 级分镜派单，agent 再跑 `gtrk split` 产 `dispatch.json`），驱动后续各车道生产+铺轨。一句话交代即推进：「口播工程已就绪，我接着把它拆成分镜派单」。
- **窄请求或判不清 → 停在交工**：用户只要剪辑工程、剪映 / PR 草稿、去停顿去废话、剪一版；或只说「帮我剪个视频」，看不出要不要成片。这时交付三端打开方式后停下，**一句话交代下一步，不发问**。示范：「剪辑工程已就绪（三端打开方式见上）。要往成片做的话，下一步是拆成分镜派单，再配 B-roll、字卡、BGM 和字幕，你说一声我就接着做。」

⚠️ **上面的说法只是举例、不是白名单**——判据是「**用户的请求覆盖不覆盖下游**」，换个说法照样得听懂。只要把剪好的口播渲染成 mp4（`--render`）不算覆盖下游，那是本 skill 自己的产物。**判不清按窄请求处理**，也不为此在开剪前先发问：误停只多一句话，用户说「继续」就接上；误接力会跑一串工具调用、往工程里写拆分稿与候选轨，回退还要清理。

### 作为图纸的一步被调用时

如果你是在按某张图纸（`/gtrk-talking-head` 等）跑粗剪这一步，剪完**交回图纸**：以图纸的停点与模式为准（口播链是 §四 检查点①，必停），本节的接力规则不适用，MUST NOT 自行接力到 `/gtrk-splitter`。

### 逃生门：两种信号都要认（范围 + 节奏）

**请求覆盖下游时，用户若还表达了范围保留或节奏保留，就停在这一步、别自动接力。** 两者语义正交，认漏一个都会误冲：

- **范围信号 = 走多远**（我只要这一个产物）：「只要这版剪辑工程」「先不往下」「暂不出片」。
- **节奏信号 = 怎么走**（每步停等我）：**「逐步推进」**（这是本仓公约立法定名的正式模式名，
  定义就是「每步停等确认」，用户会照着这么说）、「一步步来」「先 X 然后我们再说」
  「我看看再定」「等我确认」。

⚠️ **上面的词只是举例、不是白名单**——判据是「**用户表达了节奏/范围保留**」，换个说法照样得听懂。
典型误判：「先智能剪口播 **然后我们逐步推进**」——用户说了「然后」，明确表示还要往下，
**范围**逃生门逐字不成立；但**节奏**逃生门成立 ⇒ **SHALL 停**。不要因用户说「然后」就忽略明确的逐步推进要求。

停下时**必须交代下一步是什么、他说一声就继续**，别退化成事事请示。示范：
「口播工程已就绪。按你说的逐步来，我先停在这。下一步是拆成 beat 级分镜派单，你说一声我就接着做。」

**请求覆盖下游、又没有这两类信号时，照旧自动接力**，别问「要不要继续」。

> 原则：**agent 替用户跑 CLI / 接力 skill，用户只对话**——别让用户自己去终端敲下一条 gtrk 命令。

---

## 改工程：走 `gtrk patch`，不要裸手改 JSON

跑完之后要**微调某个片段**（挪位置 / 改时长 / 切开 / 改音量）时，一律用 `gtrk patch`：

```bash
gtrk patch move --project <dir> --clip <clip_id> --to 5.0
gtrk patch trim --project <dir> --clip <clip_id> --out -1s
```

**MUST NOT 直接编辑 `.gtrk` 的 JSON。** 片段时码是两套并存的（`clip_st`+`clip_ed` 与
`clip_st`+`duration`）：改一份不改另一份，客户端优先读 `clip_ed`、后端又不强校验它 ⇒
`gtrk patch` 替你做恒等式同步 + 帧对齐 + 写前全档校验。

> 参数手册在 `AGENT.md` 的「元素级编辑：`gtrk patch`」一节与 README 命令参考。
> 本节**只指路不搬手册** —— 搬过来就会长出会漂移的副本。
