Metadata-Version: 2.4
Name: jianying-tool
Version: 0.2.0
Summary: A local CLI for inspecting and editing Jianying Pro projects.
Author: lhwget
License: Apache-2.0
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: Microsoft :: Windows
Classifier: Programming Language :: Python :: 3
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pyJianYingDraft==0.3.0
Requires-Dist: mcp<3,>=2.2.0
Requires-Dist: imageio-ffmpeg<0.7,>=0.6
Requires-Dist: Pillow>=10
Requires-Dist: uiautomation>=2; sys_platform == "win32"
Provides-Extra: tts
Requires-Dist: edge-tts>=7; extra == "tts"
Provides-Extra: tts-offline
Requires-Dist: piper-tts>=1.8; extra == "tts-offline"
Provides-Extra: asr
Requires-Dist: faster-whisper>=1.2; extra == "asr"
Dynamic: license-file

# Jianying Tool

本项目是剪映专业版本地自动化工具的基础工程。当前已经支持探测、草稿检查、打包、剪映 11.x 原生封装草稿编辑、官方 MCP 服务，以及基于开源控制器的 Windows 桌面导出桥接。

## 当前基线

- Windows
- 剪映专业版 11.4.2.14459
- 默认安装目录：`%LOCALAPPDATA%\JianyingPro\Apps`（内含各版本子目录，按版本号取最新）
- 默认草稿目录：`%LOCALAPPDATA%\JianyingPro\User Data\Projects\com.lveditor.draft`

剪映装在别处时，用 `JIANYING_INSTALL_ROOT` 和 `JIANYING_DRAFT_ROOT` 覆盖；只想指定某个具体版本，用 `JY_INSTALL_DIR` 指向含 `videoeditor.dll` 的版本目录。**不要把某台机器的绝对路径写死。**

## 安装

需要 **Windows**、已安装**剪映专业版**、**Python 3.10+**。

### Python 包（CLI + MCP 服务）

```bash
# 安装
pip install "git+https://github.com/lhwget/auto_edit.git"

# 或零安装试用，不污染当前环境（需要 uv）
uvx --from "git+https://github.com/lhwget/auto_edit" jianying probe
```

配音（TTS）和转写（ASR）是可选依赖，不带它们也能正常用：

```bash
pip install "jianying-tool[tts,asr] @ git+https://github.com/lhwget/auto_edit.git"
```

装完先自检，确认能找到本机的剪映：

```bash
jianying probe
```

输出里的 `install_root` / `draft_root` 应该指向真实路径，且 `draft_root_exists` 为 `true`。找不到就按上面的环境变量覆盖。

### Agent Skills（可选）

[`skills/`](skills/README.md) 下有三个 Agent Skill。装上它们，Agent 才能跑「素材打标 → 选片 → 剪辑」的完整流程：

```bash
npx skills add lhwget/auto_edit --all
```

也可以手动拷进 Agent 的 skills 目录：

```bash
cp -r skills/* ~/.codex/skills/          # Windows: %USERPROFILE%\.codex\skills\
```

`tag-video-assets` 和 `auto-edit-from-assets` **必须同级安装** —— 它们互相按相对路径引用，只装一个引用会悬空。

> **两条通道是分开的。** 打包产物里只有 `jianying_tool` 这个 Python 包，**不含 `skills/`**；反过来拷了 Skill 也不会装 Python 包。按需分别装。

## MCP 服务

安装本项目后可以启动本地 MCP 服务：

```powershell
python -m jianying_tool.mcp_server
# 或
jianying-mcp
```

它使用官方 `mcp` Python SDK 2.x 的 `MCPServer`，通过标准输入/输出提供 MCP 服务。当前已注册 71 个工具，覆盖草稿管理、封面、完整性检查、媒体索引与重链、项目画布设置、图片/视频/贴纸/音频/字幕、文字片段、转场、滤镜/特效、动画、蒙版、抠像、背景、轨道静音、片段可见性、跨轨道移动、轨道重命名、轨道整体平移、文字气泡、花字、画面变换、静态调节、关键帧操作和 Windows 桌面导出。客户端配置示例：

```json
{
  "mcpServers": {
    "jianying": {
      "command": "C:\\path\\to\\jianying\\.venv\\Scripts\\python.exe",
      "args": ["-m", "jianying_tool.mcp_server"],
      "cwd": "C:\\path\\to\\jianying"
    }
  }
}
```

MCP 和 CLI 共用同一套原生草稿编解码、备份、并发变更检测和写入校验逻辑。

## 使用

```powershell
python -m jianying_tool.cli probe --json
python -m jianying_tool.cli drafts --json
python -m jianying_tool.cli inspect "<草稿目录>\jy演示"
python -m jianying_tool.cli doctor "<草稿目录>\jy演示"
python -m jianying_tool.cli media-resources "<草稿目录>\jy演示" --kind stickers
python -m jianying_tool.cli text-resources --query 标题 --json
python -m jianying_tool.cli bundle "C:\path\to\source-draft" "<草稿目录>\bundled-draft"
python -m jianying_tool.cli create --name demo --video "C:\path\to\video.mp4"
python -m jianying_tool.cli set-cover --draft demo --image "C:\path\to\cover.png"
python -m jianying_tool.cli project-settings --draft demo --width 1080 --height 1920 --ratio 9:16 --fps 30
python -m jianying_tool.cli subtitle --draft demo --srt "C:\path\to\subtitles.srt"
python -m jianying_tool.cli text-style --draft demo --track subtitle --segment 0 --color "#FFD166" --size 8 --bold --opacity 0.9 --y -0.72
python -m jianying_tool.cli set-text --draft demo --track subtitle --segment 0 --text "新的字幕内容"
python -m jianying_tool.cli append-text --draft demo --text "片头标题" --track text --duration 3 --color "#FFD166" --size 10 --bold --align center --stroke-color "#000000" --stroke-width 35 --background-color "#000000" --background-opacity 0.5 --background-round 0.2
python -m jianying_tool.cli text-decoration --draft demo --track subtitle --segment 0 --kind bubble --effect-id BUBBLE_EFFECT_ID --resource-id BUBBLE_RESOURCE_ID
python -m jianying_tool.cli remove-text-decoration --draft demo --track subtitle --segment 0 --material-id TEXT_DECORATION_ID
python -m jianying_tool.cli edit-text-decoration --draft demo --track subtitle --segment 0 --material-id TEXT_DECORATION_ID --kind effect --effect-id EFFECT_ID
python -m jianying_tool.cli text-style --draft demo --track subtitle --segment 0 --stroke-color "#000000" --stroke-width 45 --background-color "#000000" --background-opacity 0.6 --background-round 0.2 --shadow-color "#000000" --shadow-opacity 0.7
python -m jianying_tool.cli replace-video --draft demo --material video.mp4 --video "C:\path\to\new-video.mp4"
python -m jianying_tool.cli replace-image --draft demo --material photo.png --image "C:\path\to\new-photo.png"
python -m jianying_tool.cli freeze-frame --draft demo --track main_video --segment 0 --at 1.5 --duration 1.0
python -m jianying_tool.cli export --draft demo --output "C:\path\to\demo.mp4" --resolution 1080P --framerate 30
python -m jianying_tool.cli replace-audio --draft demo --material bgm.mp3 --audio "C:\path\to\new-bgm.mp3"
python -m jianying_tool.cli append-video --draft demo --video "C:\path\to\overlay.mp4" --track overlay --target-start 1 --speed 1.5
python -m jianying_tool.cli append-image --draft demo --image "C:\path\to\photo.jpg" --track overlay --target-start 1 --duration 3
python -m jianying_tool.cli append-sticker --draft demo --resource-id STICKER_RESOURCE_ID --track sticker --target-start 1 --duration 3
python -m jianying_tool.cli append-audio --draft demo --audio "C:\path\to\bgm.mp3" --volume 0.5 --speed 1.5 --change-pitch --fade-in 0.5 --fade-out 0.5
python -m jianying_tool.cli separate-audio --draft demo --track main_video --segment 0 --audio-track 人声
python -m jianying_tool.cli resources --kind audio-scene --query 回音 --limit 10
python -m jianying_tool.cli audio-effect --draft demo --track bgm --segment 0 --category scene --name 回音 --param 50 --param 70
python -m jianying_tool.cli edit-audio-effect --draft demo --track bgm --segment 0 --material-id EFFECT_ID --set 0=25
python -m jianying_tool.cli remove-audio-effect --draft demo --track bgm --segment 0 --material-id EFFECT_ID
python -m jianying_tool.cli clear-audio-effects --draft demo --track bgm --segment 0
python -m jianying_tool.cli transition --draft demo --track main_video --segment 0 --name 叠化 --duration 0.5
python -m jianying_tool.cli edit-transition --draft demo --track main_video --segment 0 --name 上移 --duration 0.8
python -m jianying_tool.cli remove-transition --draft demo --track main_video --segment 0
python -m jianying_tool.cli clear-track-transitions --draft demo --track main_video
python -m jianying_tool.cli edit-segment --draft demo --track main_video --segment 0 --source-start 1 --source-duration 3 --speed 1.25 --reverse
python -m jianying_tool.cli edit-segment --draft demo --track bgm --segment 0 --mute
python -m jianying_tool.cli split-segment --draft demo --track main_video --segment 0 --at 2.0
python -m jianying_tool.cli duplicate-segment --draft demo --track main_video --segment 0
python -m jianying_tool.cli add-track --draft demo --name overlay --type video
python -m jianying_tool.cli add-track --draft demo --name fx --type effect --index 0
python -m jianying_tool.cli move-track --draft demo --track overlay --index 2
python -m jianying_tool.cli rename-track --draft demo --track overlay --name foreground
python -m jianying_tool.cli shift-track --draft demo --track subtitle --delta 0.5
python -m jianying_tool.cli track-mute --draft demo --track bgm --muted
python -m jianying_tool.cli segment-visibility --draft demo --track overlay --segment 0 --no-visible
python -m jianying_tool.cli move-segment --draft demo --from-track overlay --to-track main_video --segment 0 --target-start 2
python -m jianying_tool.cli edit-segment --draft demo --track bgm --segment 0 --volume 0.3 --fade-in 0.5 --fade-out 0.5
python -m jianying_tool.cli delete-segment --draft demo --track overlay --segment 0
python -m jianying_tool.cli delete-track --draft demo --track bgm
python -m jianying_tool.cli transform --draft demo --track main_video --segment 0 --x 0.25 --scale 1.2 --rotation 8 --opacity 0.85
python -m jianying_tool.cli crop --draft demo --track main_video --segment 0 --left 0.1 --top 0.05 --right 0.9 --bottom 0.95
python -m jianying_tool.cli keyframe --draft demo --track main_video --segment 0 --property position_x --time 0 --value -0.3
python -m jianying_tool.cli keyframe --draft demo --track main_video --segment 0 --property position_x --time 2 --value 0.3
python -m jianying_tool.cli keyframe --draft demo --track main_video --segment 0 --property brightness --time 0 --value -0.2
python -m jianying_tool.cli keyframe --draft demo --track main_video --segment 0 --property brightness --time 2 --value 0.2
python -m jianying_tool.cli clear-keyframes --draft demo --track main_video --segment 0
# 对整段视频设置固定的亮度、对比度、饱和度（每项 -1 到 1）
python -m jianying_tool.cli adjust --draft demo --track main_video --segment 0 --brightness 0.2 --contrast -0.1 --saturation 0.3
python -m jianying_tool.cli resources --kind filter --query VHS --limit 10
python -m jianying_tool.cli filter --draft demo --track main_video --segment 0 --name VHS_III --intensity 70
python -m jianying_tool.cli video-effect --draft demo --track main_video --segment 0 --name 模糊 --param 65
python -m jianying_tool.cli track-effect --draft demo --track fx --kind scene --name 模糊 --start 0 --duration 5 --param 80
python -m jianying_tool.cli track-filter --draft demo --track global_filter --name VHS_III --start 0 --duration 5 --intensity 70
python -m jianying_tool.cli edit-track-effect --draft demo --track fx --segment 0 --start 1 --duration 3 --param 0=65
python -m jianying_tool.cli edit-track-effect --draft demo --track global_filter --segment 0 --intensity 85
python -m jianying_tool.cli remove-effect --draft demo --track main_video --segment 0 --material-id EFFECT_ID
python -m jianying_tool.cli clear-effects --draft demo --track main_video --segment 0
python -m jianying_tool.cli resources --kind mix-mode --limit 10
python -m jianying_tool.cli mix-mode --draft demo --track overlay --segment 0 --name 滤色
python -m jianying_tool.cli resources --kind animation-in --query 放大 --limit 10
python -m jianying_tool.cli animation --draft demo --track main_video --segment 0 --kind in --name 动感放大 --duration 1
python -m jianying_tool.cli clear-animations --draft demo --track main_video --segment 0
python -m jianying_tool.cli resources --kind text-animation-in --query 弹入 --limit 10
python -m jianying_tool.cli text-animation --draft demo --track subtitle --segment 0 --kind in --name 弹入 --duration 0.5
python -m jianying_tool.cli text-animation --draft demo --track subtitle --segment 0 --kind loop --name 晃动
python -m jianying_tool.cli mask --draft demo --track main_video --segment 0 --name 圆形 --size 0.7 --feather 18
python -m jianying_tool.cli edit-mask --draft demo --track main_video --segment 0 --size 0.72
python -m jianying_tool.cli chroma --draft demo --track main_video --segment 0 --color "#00ff00ff" --intensity 35
python -m jianying_tool.cli background --draft demo --track main_video --segment 0 --type blur --blur 0.375
python -m jianying_tool.cli remove-resource --draft demo --track main_video --segment 0 --material-id RESOURCE_ID
```

上例里的 `<草稿目录>` 默认是 `%LOCALAPPDATA%\JianyingPro\User Data\Projects\com.lveditor.draft`；`JIANYING_DRAFT_ROOT` 可以覆盖它，`JIANYING_INSTALL_ROOT` 覆盖安装目录（指向含各版本子目录的 `Apps`），`JY_INSTALL_DIR` 则指定某个具体版本。多数字命令也接受 `--root` 参数。

`bundle` 会复制可读取的草稿，并把 `draft_content.json` 中引用的本地视频、音频和图片复制到草稿的 `media` 目录，同时改写素材路径。

`create` 会创建一个新草稿并添加一条视频轨道；指定 `--duration` 可限制片段时长，默认使用素材完整时长。

`append-text` 还支持左/中/右对齐、竖排文字、描边、背景和阴影；`set-cover` 将本地 JPG、PNG、WEBP 或 BMP 图片转换成草稿卡片使用的 `draft_cover.jpg`；已有封面会备份到 `.jianying-tool-backups/covers`。它只设置草稿列表缩略图，剪映列表的缓存刷新和保存行为仍需界面验证。`inspect` 返回封面文件路径及是否存在。

剪映 11.x 打开并保存后，`draft_content.json` 通常不再是明文 JSON。本项目会自动发现本机剪映目录中的 `videoeditor.dll`，通过本地适配器解码、修改、重新封装，再同时更新项目根目录和活动时间线文件。可以用 `JY_INSTALL_DIR` 指定 DLL 所在版本目录。每次写入前都会校验编解码往返结果，并把原文件备份到项目内的 `.jianying-tool-backups`。

`replace-video` 默认按素材名查找；如果草稿中有多个同名素材，先用 `inspect` 或解码后的素材列表获取 ID，再传入 `--material-id` 精确选择。

`replace-audio` 按音频素材名或 ID 替换本地文件，保留原有片段、时间线位置、音量、淡入淡出和音频效果引用；新文件时长会同步写入素材表。

`replace-image` 按图片素材名或 ID 替换静态图片，保留原有片段的时间线、裁剪、关键帧和效果引用，并同步更新图片尺寸。

`freeze-frame` 按片段内时间提取源视频帧，作为新的可编辑图片片段放入独立视频轨道；支持固定倍速、曲线变速的正放和倒放，倒放从所选源区间的最后一帧开始映射。原视频和后续片段不会自动移动。

`export` 在 Windows 剪映桌面端执行导出，有两个适配器：

- 剪映 6 及以下走开源 `pyJianYingDraft.JianyingController`，它按 UIA 控件名（`HomePageDraftTitle:`、`ExportOkBtn` 等）驱动界面，可传入输出路径、分辨率和帧率。
- 剪映 11.x 走视觉适配器，流程是：按封面图匹配首页卡片 → 点击 → **用草稿目录变化验证打开的是哪个草稿** → 按颜色定位导出按钮和确认按钮 → 轮询新视频文件并等它停止增长 → 移动到 `--output`。

实测结论：剪映 11.4.2 虽然二进制里仍保留上述 UIA 控件名，但运行时**一个控件都不暴露**。`QT_ACCESSIBILITY=1` 和系统屏幕阅读器标志 `SPI_GETSCREENREADER` 都试过，窗口在 8 层深度内仍是 0 个 UIA 子控件，因此 11.x 无法使用参考项目那套选择器。

11.x 上无法自动切换分辨率和帧率：传 `--resolution` 或 `--framerate` 会被明确拒绝，而不是静默忽略后仍按当前设置导出。输出目录默认自动探测（Videos 及其子目录、Desktop、Downloads、Movies），也可以用 `--export-dir` 指定。

11.x 适配器的已知限制：

- 草稿封面如果是纯色或近乎无细节，没有可供匹配的特征，会报错而不是猜。可以用 `set-cover` 换一张有内容的封面。
- 多张草稿共用同一封面时，缩略图无法区分；此时靠「目录变化」验证身份，验证不通过会中止，**不会**导出错误的工程。
- 草稿必须当前在首页可见，否则需要先滚动到它。

（这次实现修掉了上一版的一个真实缺陷：旧代码固定点击第一张卡片，`draft_name` 只出现在报错文案里，第一个草稿不是目标时会静默导出错误的工程，且不验证输出文件是否存在。）

`append-video` 会复用指定的视频轨道或创建新的内部视频轨道，并支持素材起点、时长和固定倍速；对剪映模板加载的原有视频轨道也会通过原生 JSON 适配器追加片段，保留轨道及已有片段。

`append-image` 会把 JPG、JPEG、PNG、WEBP 或 BMP 静态图片作为 `photo` 素材放入视频轨道，支持时间线起点和持续时长；未指定轨道时会创建工具管理的轨道。图片素材也能继续使用 `transform`、`crop` 和 `keyframe`。

`append-sticker` 使用剪映内置贴纸资源 ID 创建贴纸片段，不复制媒体文件；贴纸轨道和时间段会自动创建并检查重叠。资源 ID 可从剪映草稿或后续资源目录查询功能获得。

`append-video` 现在支持 `--target-start` 指定时间线位置；不提供时仍会顺延到当前项目末尾。源素材截取和变速行为保持不变。

`append-audio` 可向新建或已有音频轨道追加片段，包括剪映保存后的原生轨道；同一轨道的片段不能重叠。支持开始时间、素材截取、倍速、音量和淡入淡出；指定素材起点但省略时长时，使用起点到素材末尾的剩余部分。同名文件按独立素材目录打包，不会覆盖之前的声音文件。无效时间区间和超出片段总时长的淡入淡出会被拒绝。

`append-audio --change-pitch` 和 `edit-segment --change-pitch/--no-change-pitch` 控制变速时是否让音调跟随速度；关闭 `change-pitch` 才是保持人声原音调，对应剪映的音调跟随设置。

`separate-audio` 使用本机 FFmpeg 提取视频片段的音频，按原片段的源区间、时间线位置、固定/曲线倍速、音量、音量关键帧、淡入淡出和音调设置创建独立音轨；倒放片段会先反转选中的音频区间，默认将原视频片段静音。提取失败时不会修改草稿。

`audio-effect` 支持场景音、音色和声音成曲三类音频效果；参数按资源目录顺序传入，范围为 0 到 100。

`edit-audio-effect` 按 `INDEX=VALUE` 调整已挂载效果的参数；当素材被多个片段共用时会复制效果素材，只修改选中的片段。`remove-audio-effect` 会解除引用并在没有其它片段使用时清理素材。

`clear-audio-effects` 一次移除音频片段上的全部场景音、音色或声音成曲效果，并清理不再被引用的音频效果素材。

`text-style` 可直接修改字幕或标题的颜色、字号、透明度、粗体、斜体、下划线、画布位置、描边、背景和阴影；`--no-stroke`、`--no-background`、`--no-shadow` 可移除对应样式。描边宽度/阴影扩散使用剪映面板的 0 到 100 值，背景颜色使用 `#RRGGBB`，透明度、尺寸和圆角使用 0 到 1 的归一化值。

`set-text` 替换指定字幕或标题的文字，并同步更新样式范围，保留该片段已有的动画和视觉样式。

`text-decoration` 给字幕或标题添加文字气泡（`bubble`）或花字效果（`effect`）。`effect-id` 和 `resource-id` 来自剪映素材元数据；一个片段最多挂载一个文字气泡/花字。

`text-resources` 扫描本机可读草稿，列出已经下载并使用过的文字气泡/花字及其 ID，方便直接用于 `text-decoration`。

`remove-text-decoration` 按素材 ID 移除文字气泡或花字，素材不再被其它片段引用时会一并清理。

`edit-text-decoration` 修改已有文字气泡/花字的类型或素材 ID；共享素材会自动复制，避免影响其它片段。

`text-animation` 可给字幕或标题添加文字入场、出场和循环动画；入场/出场的 `--duration` 单位为秒，省略时使用目录默认时长。循环动画不接受 `--duration`，会填满入场结束到出场开始之间的空余时段。同一片段可按任意顺序添加这三类动画，每类最多一个；工具会自动重算衔接时间，并拒绝重叠或没有循环空间的组合。复制片段共用动画时，只修改选中的片段。`resources` 的 `text-animation-in`、`text-animation-out` 和 `text-animation-loop` 分别查询文字动画目录；`inspect` 会列出每段动画的起点与时长。

`transition` 会给指定视频片段写入转场元数据。原生草稿的修改采用临时文件和原子替换；如果根草稿和活动时间线不一致，工具会停止并提示先刷新项目，避免覆盖剪映刚保存的内容。

`edit-transition` 修改已有转场的类型或时长，并清理旧的转场素材引用；至少提供一个修改项。

`remove-transition` 移除指定视频片段的转场，并清理不再被引用的转场素材。

`clear-track-transitions` 一次移除整条视频轨道上的全部转场，同时保留片段本身和其它效果。

`edit-segment` 可以修改素材起点、截取时长、时间线位置、速度、音量、静音状态和倒放；`--mute` 静音，`--no-mute` 恢复静音前的音量（也可同时传入 `--volume` 指定新音量）。修改源时长或时间线位置时会检查同轨道重叠，并按起点重新排序；修改源时长时会按照速度同步计算目标时长，并重新计算项目总时长。`delete-segment` 和 `delete-track` 用于移除片段或整条轨道，写入前同样会创建备份。

修改固定倍速时，片段与 `speeds` 素材表会同步更新；复制片段共用同一个速度资源时会自动复制该资源，使未选中的片段保留原来的速度。

`split-segment` 按片段内秒数分割视频、音频、字幕或文本片段，自动计算前后两段的源素材时间范围；原片段上的滤镜、蒙版、音量等引用会保留。

`duplicate-segment` 复制视频、音频、字幕或文本片段，默认接在原片段后面，也可以用 `--target-start` 指定新的时间线起点；转场不会被重复复制。

`add-track` 创建空的视频、音频、字幕、贴纸、滤镜或特效轨道；轨道名必须唯一，`--index` 是整个 `tracks` 数组中的绝对插入位置。创建后可用其它命令向指定轨道追加片段或资源。

`move-track` 将整条轨道移动到 `tracks` 数组中的绝对位置，用于调整视频、贴纸、滤镜和特效的层级顺序；轨道内片段和素材引用保持不变。

`rename-track` 修改轨道名称，保留轨道内的片段、素材和效果引用；新名称必须非空且不能与其它轨道重复。

`shift-track` 将整条轨道上的片段按秒整体平移，支持正负偏移并自动重算项目时长；平移后不能产生负时间。

`track-mute` 设置或取消整条音频/视频轨道的静音标志；`inspect` 会在轨道信息中返回 `muted`。

`segment-visibility` 显示或隐藏单个时间线片段，保留其媒体和所有编辑属性；`inspect` 会在片段信息中返回 `visible`。

`move-segment` 将视频、音频或文字片段移动到另一条兼容轨道，可选新的时间线起点；片段的素材、效果和关键帧引用保持不变，目标轨道不能发生时间重叠。

`track-effect` 和 `track-filter` 把视频特效或滤镜作为独立轨道片段写入；需要先用 `add-track --type effect` 或 `--type filter` 建立对应轨道。两者都支持秒级起点和持续时长，同一轨道上的片段不能重叠；特效参数按 `resources` 返回的顺序传入，滤镜强度为 0 到 100。独立轨道素材会写入 `video_effects` 或 `effects` 素材表，剪映打开后可继续调整。

`edit-track-effect` 可修改独立轨道片段的起点、时长、滤镜强度或视频特效参数；参数使用 `INDEX=VALUE`，值为 0 到 100 的面板百分比。删除独立轨道片段或整条独立轨道时，未被其它片段引用的效果素材会一并清理。

`transform` 支持位置、缩放、旋转、不透明度和水平/垂直翻转。`keyframe` 支持位置、旋转、缩放、不透明度、音量、饱和度、对比度和亮度的线性关键帧；后三项范围为 -1 到 1，0 表示原始值。时间以片段起点为零点；可用 `--clear` 清除该属性的全部关键帧。已有关键帧的属性不会被静态变换命令覆盖。

`clear-keyframes` 一次清除片段的全部关键帧序列，保留其它画面和音频设置。

`clear-effects` 一次清除片段上的滤镜、视频特效和混合模式，保留蒙版、抠像和背景设置。

`adjust` 将亮度、对比度和饱和度写入视频片段的原生 `common_keyframes`，在片段起点和终点写入相同值，因此整段保持固定效果；它不会覆盖其他属性的关键帧。

`project-settings` 修改草稿的画布宽高、比例和帧率，未提供的选项保持原值。

`doctor` 只读检查草稿是否可解码、轨道和片段时间范围是否有效、素材与资源引用是否存在、媒体文件是否丢失，并返回 `ok`、错误和警告列表；发现错误时 CLI 返回退出码 1。

`media-resources` 列出草稿中的素材池、ID、本地路径、贴纸资源 ID 和引用次数。`relink-media` 将新的本地视频或音频复制到草稿的 `media/relinked` 目录，并更新指定素材 ID 的路径，适合修复素材丢失。

`crop` 使用 0 到 1 的归一化坐标设置素材裁剪矩形，原点在左上角；`left/top/right/bottom` 分别对应四条边。多个片段共用素材时会自动复制素材记录，只让当前片段使用新裁剪。

`resources` 查询参考库内置的滤镜、视频特效和蒙版元数据；它反映当前 `pyJianYingDraft` 版本的资源目录，不保证每个资源在剪映账号中可用。`filter`、`video-effect` 和 `remove-effect` 会维护片段引用与草稿素材表。

`mix-mode` 为视频片段设置剪映混合模式（正片叠底、滤色、叠加等）；一个片段只能有一个混合模式，可先用 `remove-effect` 移除。混合模式需要基础视频和上层视频轨道同时存在才会产生可见差异。

`animation` 支持入场、出场和组合动画；`mask` 支持线性、镜面、圆形、矩形、爱心和星形蒙版；`chroma` 支持色度抠像；`background` 支持模糊或纯色背景填充。`remove-resource` 可按素材 ID 移除这些附加资源。

`clear-animations` 一次移除片段上的全部视频或文字动画，并清理不再被引用的动画素材。

蒙版会按剪映 11.x 实际格式写入 `common_mask` 字段、`constant_material_id`、本机缓存的 AmazingFeature 路径和 `enable_video_mask` 标志；旧版草稿仍使用 `masks`。背景填充只显示在视频没有铺满画布的区域；如果视频已经填满整个画布，模糊背景会被前景视频遮住。

`edit-mask` 修改已有蒙版的位置、大小、旋转、羽化、扩展、反转和矩形宽度。剪映 11.x 保存后的紧凑 `common_mask` 只会暴露草稿实际保留的字段；未保存的控制会明确报错，不会写入看似成功但剪映忽略的字段。

`voiceover` 把一份文案脚本合成配音轨并放进草稿，可选 `--subtitles` 顺带生成对应字幕。脚本每行一条，可加 `MM:SS.s` 前缀钉住起始时间。`--engine auto` 先探测在线 `edge-tts`，失败则整条降级离线 `piper`。**离线兜底需要先启用**：装 `pip install -e .[tts-offline]`，并把 `PIPER_VOICE_DIR` 指向存放 `<模型>.onnx` 的目录（默认找与工具包同级的 `piper-voices/`）；未启用时一解析引擎就报错，不会产出一半配音再失败。

`transcribe` 用本地 `faster-whisper` 把音视频转写成 SRT，离线且不需要 API Key，可用 `--draft` 直接导入草稿。默认开启 VAD；现场收音里的短句容易被滤掉，嘈杂素材加 `--no-vad`。

## 许可证

Apache License 2.0，见 [LICENSE](LICENSE)。第三方来源与署名见 [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)。

本项目与剪映（JianyingPro）的开发商无关，也未获其授权或认可。「剪映」等名称与商标归各自所有者。它通过调用本机安装的剪映所自带的 `videoeditor.dll` 读写草稿，**不包含**剪映的任何二进制文件。
