> For the complete documentation index, see [llms.txt](https://getsquish.gitbook.io/squish/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://getsquish.gitbook.io/squish/zh/can-kao/cli.md).

# CLI

```
squish <video> [--density 3x3|4x4|5x5|6x6] [--start <t>] [--end <t>] [--out <dir>] [--json]
squish mcp                 启动 MCP server（stdio）
```

`<t>` = 秒数（`90`) 或纸张上标注的 timecode（`1:30`, `1:07.3`）。见 [时间值](#time-values) 以了解完整语法，并查看 [MCP 服务器](/squish/zh/can-kao/mcp.md) 关于 `squish mcp`.

要求：Node ≥ 20， `ffmpeg` + `ffprobe` 在 PATH 中。所有内容都在你的机器上运行——参见 [隐私与数据流](/squish/zh/primitive/privacy-and-data-flow.md).

## 标志

| 标志          | 值                                | 必需 | 默认值      | 约束                             | 含义                                                                      |
| ----------- | -------------------------------- | -- | -------- | ------------------------------ | ----------------------------------------------------------------------- |
| `--density` | `3x3` \| `4x4` \| `5x5` \| `6x6` | 否  | `3x3`    | 必须是四个值之一                       | 每张纸的帧数：9 / 16 / 25 / 36。 `3x3` 恢复 *发生了什么；* 发生； `4x4`–`6x6` 还原 *如何* 完成的。 |
| `--start`   | 时间（`<t>`)                        | 否  | `0`      | ≥ 0 且在片段结束之前                   | 缩放窗口的开始，使用 **源视频的时钟** （绝对时间——绝不相对于前一个窗口）。                               |
| `--end`     | 时间（`<t>`)                        | 否  | 片段结束     | 必须晚于 `start`；超过片段结束的值会被截断到该结束点 | 缩放窗口的结束，绝对时间。                                                           |
| `--out`     | 目录                               | 否  | 位于输入文件旁边 | 如果不存在则（递归）创建                   | 输出纸张写入的位置。                                                              |
| `--json`    | —                                | 否  | 关闭       | —                              | 打印机器可读报告（[下方](#--json-output)）到 stdout，而不是人类可读摘要。                       |

## 位置参数

恰好一个位置参数：本地视频文件的路径（任何 ffmpeg 能解码的内容都可以）。它会解析为绝对路径；相对路径会相对于当前工作目录解析。

## 用法错误

任何输入问题都会打印错误消息 **以及用法文本** 到 stderr，并退出 `1`。具体条件和消息如下：

| 条件                          | 消息                                                     |
| --------------------------- | ------------------------------------------------------ |
| 没有位置输入                      | `missing <video> input`                                |
| 第二个位置输入                     | `one video per run — got a second input: <arg>`        |
| 无法识别的标志                     | `未知标志：<arg>`                                           |
| `--density` 缺失或不在枚举中        | `--density 必须是 3x3\|4x4\|5x5\|6x6 之一`                  |
| `--start` / `--end` 缺失或无法解析 | `--start 需要一个时间值——秒数（90）或时间码（1:30）` （同样的格式适用于 `--end`) |
| `--out` 缺少其目录               | `--out 需要一个目录`                                         |
| `squish mcp` 带有尾随参数         | `squish mcp 不接受任何参数`                                   |

运行 `squish` 时如果不带任何参数，会打印用法文本并退出 `1`; `--help` / `-h` 会打印用法文本并退出 `0`.

## 时间值

`--start` 和 `--end` 接受：

* 纯秒数： `90`, `67.4`
* 与纸张上标注完全一致的 timecode： `1:30`, `120:30` （分钟没有上限）， `1:07.3` （小数秒），或者 `01:02:03` (`h:mm:ss`)

纸张上显示的任何内容都可作为有效输入——参见 [往返属性](/squish/zh/can-kao/sheet-format.md#round-trip-property) 在纸张格式规范中查看确切语法。

### 窗口语义

两个边界都是 **在源视频中的绝对时间** 在每个缩放层级都如此——窗口运行不会重新基准化 timecode。解析规则（在探测片段后按此顺序检查）：

* 省略 `--start` → `0`。省略 `--end` → 片段结束。
* 一个 `--end` 超过片段结束的值会 **截断** 到片段时长（“从 5:00 到结束”即使不知道时长也能工作）。
* 负的 `--start` 会失败： `start 必须是 ≥ 0 的时间`.
* 一个 `--start` 位于片段结束处/之后的值会失败： `开始时间 (<t>) 位于片段结束 (<duration>) 处或之后`.
* 空窗口（end ≤ start，包括结束截断后）会失败： `窗口为空——结束 (<t>) 必须晚于开始 (<t>)`.
* 小于 **每个单元 2 毫秒** 在所选密度下会以教学错误失败： `窗口太小，无法清晰区分：在 <X> 毫秒内横跨 <N> 个单元格（引擎以毫秒精度定位——在此密度下最小约为 <2N> 毫秒）；请缩小放大倍率或降低密度`。刚好达到下限的窗口会被接受。见 [自适应精度](/squish/zh/can-kao/sheet-format.md#adaptive-precision) 了解为什么会有这个下限。

## 输出文件

纸张会写成 `<basename>.sheet-N.jpg` (`N` （从 1 开始，按时间顺序），其中 `<basename>` 是去掉扩展名后的输入文件名——参见 [文件名契约](/squish/zh/can-kao/sheet-format.md#filename-contract)。默认目标位置是输入文件所在目录； `--out <dir>` 会覆盖它。

## --json 输出

使用 `--json`，stdout 中只会有一个 JSON 对象——冻结的 `squish-cli-v0` 契约（参见 [稳定性与版本控制](/squish/zh/can-kao/stability.md)）。键顺序是固定的：

```json
{
  "input": "/abs/path/clip.mov",
  "duration": 20.275,
  "frames": 9,
  "sheets": 1,
  "files": ["/abs/path/clip.sheet-1.jpg"],
  "warnings": [],
  "contract": "squish-cli-v0"
}
```

| 键       | 类型     | 存在                            | 含义                                                                                                   |
| ------- | ------ | ----------------------------- | ---------------------------------------------------------------------------------------------------- |
| `input` | 字符串    | 始终                            | 输入视频的绝对解析路径。                                                                                         |
| `时长`    | 数字     | 始终                            | 以下内容的时长： **完整片段** 以秒为单位——即使在窗口运行中，也从不表示窗口长度。                                                         |
| `窗口`    | 对象     | 仅当 `--start` 和/或 `--end` 被传入时 | `{ "start": <s>, "end": <s> }` —— **解析后的** 边界，以秒为单位（在默认值处理和结束截断之后），精确到毫秒。若未请求窗口则不存在。它出现在 `时长` 和 `帧`. |
| `帧`     | 数字     | 始终                            | 采样的总帧数（`纸张数 × 单元格数`）。无法读取的帧也会计入——它们会显示在 `警告`.                                                        |
| `纸张`    | 数字     | 始终                            | 生成的纸张文件数量。                                                                                           |
| `文件`    | 字符串\[] | 始终                            | 按纸张顺序排列的绝对输出路径。                                                                                      |
| `警告`    | 字符串\[] | 始终                            | 非致命问题，例如 `纸张 1 帧 3：无法读取——单元格保留为黑色`.                                                                  |
| `契约`    | 字符串    | 始终                            | `"squish-cli-v0"` ——请解析它以检测破坏性变更。                                                                    |

一次窗口运行：

```json
{
  "input": "/abs/path/clip.mov",
  "duration": 200.5,
  "window": { "start": 60, "end": 90 },
  "frames": 25,
  "sheets": 1,
  "files": ["/abs/path/clip.sheet-1.jpg"],
  "warnings": [],
  "contract": "squish-cli-v0"
}
```

没有 `--json`，stdout 中的是人类可读摘要（输出路径， `警告：` 行，以及一个 `摘要：duration=…s sheets=… frames=…` 行）。只有 `--json` 对象是稳定性契约；不要解析人类可读输出。

## 退出码

| 代码  | 含义                                                                                                                                     |
| --- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `0` | 成功。另： `--help` / `-h`.                                                                                                                 |
| `1` | 任何失败。用法错误会将消息+用法文本打印到 stderr；运行时错误（例如 `未找到输入：<path>`、窗口错误、ffmpeg 失败）会将消息打印到 stderr。运行 `squish` 时如果完全不带参数，会将用法文本打印到 **stdout** 并退出 `1`. |

stdout 除了报告之外不会写入任何内容，只有一个例外：用法文本。 `--help` / `-h` 将用法打印到 stdout 并退出 `0`；运行 `squish` 时如果 **完全不带参数** 也会将用法打印到 stdout，但会退出 `1`。将 stdout 留给机器可读输出的包装器应在解析前检查退出码。其他所有失败都只写入 stderr。

## 临时帧清理

提取的帧会进入 OS 临时目录下的每次运行专用临时目录。运行结束时它总会被移除—— **无论成功还是出错**。只会保留 `.sheet-N.jpg` 文件。

## 示例

```bash
# 概览：每约 90 秒片段生成一张 3×3 纸张，写入输入文件旁边
squish clip.mov

# 更密集的网格 + 机器可读输出
squish clip.mov --density 5x5 --json

# 缩放：以更高密度重新 squish 1:00–1:30——timecode 保持绝对
squish clip.mov --start 1:00 --end 1:30 --density 5x5

# 钻取前一张纸上发现的亚秒范围，输出到指定目录
squish clip.mov --start 1:07.3 --end 1:09 --density 4x4 --out ./sheets --json
```

缩放模式（概览 → 找到范围 → 以 `--start`/`--end` → 更精细的 timecode 重新运行）是 [导航循环](/squish/zh/primitive/the-navigation-loop.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://getsquish.gitbook.io/squish/zh/can-kao/cli.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
