基于 cli-anything-shotcut 的无 GUI 视频编辑:以 MLT XML 为核心的状态化命令行工作流
cli-anything-shotcut 是 CLI-Anything 系列中面向 Shotcut 视频剪辑工具的命令行接口,它直接读写 Shotcut 项目底层的 MLT XML 文件,把时间线、滤镜、转场、合成与导出能力完整暴露给终端与 AI Agent。读完本文你将掌握该 CLI 的安装方式、REPL 与一次性命令两种使用形态、媒体导入到时间线排布的完整工作流,以及结合 --json 输出与 preview 机制实现可审计、可复现的自动化视频编辑方案。
设计核心:直接操作 MLT XML
Shotcut 是构建在 MLT 多媒体框架之上的 Qt/QML 编辑器,而它的工程文件本质上是 .mlt 格式的 MLT XML。这正是本 CLI 的关键切入点:整个编辑过程不依赖 GUI,而是直接对 MLT XML 进行读取与改写。
从仓库的架构分析文档 SHOTCUT.md 可以看到,Shotcut GUI 通过 MLT::Controller 与 MLT Framework 交互,最终落到 FFmpeg / LADSPA / frei0r / movit 等底层引擎;而本 CLI 绕过了 GUI 层,直接构造一个最小的 MLT XML 文档骨架——包含 profile(分辨率、帧率、宽高比、色彩空间)、媒体 producer、main_bin(媒体库)与 main_tractor(主时间线轨道)等元素。
对应的会话实现在 session.py 中,Session 负责维护 MLT 文档根节点(root)、媒体库与轨道引用(main_bin、main_tractor、_track_playlists),并在每次操作前对整棵 XML 树做快照,为撤销/重做提供基础。正因为一切都围绕 XML 树展开,project xml 命令可以直接输出当前工程的原始 MLT XML,供调试与 Agent 校验使用。
安装与前置条件
该 CLI 随 cli-anything-shotcut 包一起安装:
pip install cli-anything-shotcut
前置依赖(见 SKILL.md 与包内 README.md):
- Python 3.10+
melt(MLT CLI)——渲染与播放的必需组件ffmpeg/ffprobe——媒体探测与导出必需shotcut——系统需安装 Shotcut(工程格式的兼容基础)- 可选:
prompt_toolkit(交互式 REPL 增强)、click(CLI 框架,随包安装)
系统级工具可按发行版安装,例如 Ubuntu/Debian 下 apt install melt ffmpeg,macOS 下 brew install mlt ffmpeg。若从源码目录运行,可在 shotcut/agent-harness/ 下使用 python3 -m cli_anything.shotcut.shotcut_cli 调用入口模块(shotcut_cli.py)。
快速上手:一次性命令与双输出模式
安装完成后,最常用的基础命令如下:
# 查看帮助
cli-anything-shotcut --help
# 进入交互式 REPL 模式
cli-anything-shotcut
# 创建新工程
cli-anything-shotcut project new -o project.json
# 以 JSON 输出工程信息(供 Agent 消费)
cli-anything-shotcut --json project info -p project.json
入口命令定义在 shotcut_cli.py:全局提供 --json(机器可读输出)、--session(指定/恢复会话)、--project(打开工程文件)与 --dry-run(不落盘地试运行)四个选项。不携带子命令时自动进入 REPL;而每次一次性命令结束后,若工程已打开且有修改,会自动保存回磁盘(_auto_save_callback,见同文件 L233-L245),避免 Agent 逐条命令执行时丢失中间状态。
输出格式
所有命令默认输出人类可读的表格/彩色文本,加 --json 后则输出结构化 JSON:
# 人类可读
cli-anything-shotcut project info -p project.json
# Agent 可解析的 JSON
cli-anything-shotcut --json project info -p project.json
出错时,JSON 模式下错误也会以 {"error": ..., "type": ...} 形式输出到 stderr,并返回非零退出码(handle_error 装饰器,见 shotcut_cli.py),这为脚本与 Agent 提供了统一的错误契约。
命令组全景
SKILL.md 将命令按职责划分为九个命令组,这里逐一继承并补充参数细节。
Project:工程管理
| 命令 | 说明 |
|---|---|
new |
创建空白工程(默认 profile:hd1080p30) |
open |
打开已有 .mlt 工程文件 |
save |
保存当前工程 |
info |
展示工程详细信息 |
profiles |
列出可用视频 profile |
xml |
打印当前工程的原始 MLT XML |
可用 profile:hd1080p30、hd1080p60、hd1080p24、hd720p30、4k30、4k60、sd480p。新建工程的默认 profile 参数(1920×1080、30000/1001 帧率、16:9、colorspace 709)硬编码在 session.py 中,也可通过 --profile 显式指定。
Timeline:时间线操作
| 命令 | 说明 |
|---|---|
show |
以 ASCII 图形展示时间线概览 |
tracks |
列出所有轨道 |
add-track |
新增轨道(--type video|audio,--name) |
remove-track |
按索引移除轨道 |
add-clip |
按 clip_id 将已导入素材放到轨道上,支持 --at 绝对定位 |
remove-clip |
从轨道移除素材(--no-ripple 可保留空隙) |
move-clip |
在轨道间/轨道内移动素材 |
trim |
调整素材的入/出点 |
split |
在指定时间码处把素材一分为二 |
clips |
列出某轨道上的所有素材 |
add-blank |
在轨道上插入空白空隙 |
set-name |
设置轨道显示名 |
mute |
静音/取消静音轨道(--unmute) |
hide |
隐藏/取消隐藏视频轨道(--unhide) |
其中 timeline show 的人性化实现值得关注:它把轨道与素材绘制成可读的 ASCII 时间线(_print_timeline_visual,shotcut_cli.py),素材显示 clip 索引、文件名与 in → out 时间码,空白以 ··· gap (length) ··· 标记,方便 Agent 与用户快速核对剪辑结构。
Filter:滤镜与效果
| 命令 | 说明 |
|---|---|
list-available |
列出全部可用滤镜(--category video|audio) |
info |
展示某滤镜及其参数的详细信息 |
add |
给 clip、track 或全局添加滤镜 |
remove |
按索引移除滤镜 |
set |
设置滤镜上的某个参数 |
list |
列出目标上的活动滤镜 |
volume-envelope |
在轨道或素材上创建/替换关键帧音量包络 |
duck |
在一个或多个时间窗口上构建实用的闪避(ducking)包络 |
CLI 内置了一张常用滤镜注册表(FILTER_REGISTRY,见 filters.py),其中包含视频类 brightness(level,范围 0.0-2.0)、blur(frei0r.IIRblur,amount 0.0-1.0)、crop、mirror、sepia、charcoal、关键帧化的 fadein-video/fadeout-video,以及音频类 volume(level 0.0-5.0、gain dB)、fadein-audio/fadeout-audio 等。filter add 接受可重复的 --param name=value 键值对,非法格式会立即报错。
Media:媒体管理
| 命令 | 说明 |
|---|---|
import |
将媒体文件导入工程媒体库 |
probe |
分析媒体文件属性 |
list |
列出当前工程中的所有媒体 |
check |
校验所有媒体文件是否存在 |
thumbnail |
从视频文件生成缩略图(--time、--width、--height) |
Export:导出渲染
| 命令 | 说明 |
|---|---|
presets |
列出导出预设 |
preset-info |
展示某预设详情 |
render |
将工程渲染为视频文件(--preset、--width、--height、--overwrite) |
可用预设:default、h264-high、h264-fast、h265、webm-vp9、prores、gif、audio-mp3、audio-wav、png-sequence。渲染实际由 melt 驱动,因此该依赖是硬性要求。
Transition:转场
| 命令 | 说明 |
|---|---|
list-available |
列出可用转场类型 |
info |
展示某转场类型详情 |
add |
在两条相邻素材之间添加转场(--duration 默认 14 帧) |
remove |
按索引移除转场 |
set |
设置转场参数 |
list |
列出时间线上的全部转场 |
可用转场:dissolve、wipe-left、wipe-right、wipe-down、wipe-up、bar-horizontal、bar-vertical、diagonal、clock、iris-circle、crossfade。
Composite:合成
| 命令 | 说明 |
|---|---|
blend-modes |
列出全部混合模式 |
set-blend |
设置轨道的混合模式 |
get-blend |
获取轨道当前混合模式 |
set-opacity |
设置轨道不透明度(0.0-1.0) |
pip |
设置素材的画中画位置(--x/--y/--width/--height,支持像素或百分比,默认 100% 铺满) |
可用混合模式包括 normal、add、multiply、screen、overlay、darken、lighten、colordodge、colorburn、hardlight、softlight、difference、exclusion 以及 hsl 系列与 saturate 等 18 种。
Session:会话状态
| 命令 | 说明 |
|---|---|
status |
展示当前会话状态 |
undo |
撤销上一步操作 |
redo |
重做已撤销的操作 |
save |
将会话状态持久化到磁盘(~/.shotcut-cli/sessions/ 下的 JSON) |
list |
列出已保存的会话 |
REPL 交互模式
不携带子命令启动即进入带撤销/重做支持的 REPL:
cli-anything-shotcut
# 或直接打开工程:
cli-anything-shotcut --project my_project.mlt
REPL 中键入 help 可查看全部命令,常用指令包括:
- 工程与会话:
new [profile](默认hd1080p30)、open <path>、save [path]、info、xml、status、undo/redo - 媒体(两段式模型):
media import <file> [--caption name](返回clip_id,如clip0)、media(列出已导入媒体)、probe <file> - 时间线:
add-track <video|audio> [name]、tracks、show、add-clip <clip_id> <track> [in] [out] [--at time]、clips <track>、remove-clip <track> <clip>、trim、split - 滤镜:
list-filters [video|audio]、filter-info <name>、add-filter <name> [--track n] [--clip n] [key=val ...]、filters [--track n] [--clip n]、remove-filter <idx>、set-filter <idx> <param> <value>、volume-envelope、duck - 导出:
presets、render <output> [--preset name]
一段完整的 REPL 会话示例:
> new hd1080p30
> add-track video Main
> media import intro.mp4
Imported intro.mp4 as clip0
> media import main.mp4
Imported main.mp4 as clip1
> add-clip clip0 1 00:00:00.000 00:00:05.000
> add-clip clip1 1 00:00:00.000 00:00:10.000 --at 00:00:05.000
> add-filter brightness --track 1 --clip 0 level=1.3
> show
> save
> render output.mp4 --preset h264-high
注意 REPL 的命令名(如 add-track、add-clip、add-filter)与一次性子命令组(timeline add-track、filter add)略有差异,两者在 REPL 命令表中均已注册(见 shotcut_cli.py)。
核心工作流:两段式媒体模型
整个编辑流程遵循一条黄金规则:总是先用 media import 拿到 clip_id,再用 add-clip 把它放到时间线上。
媒体库与时间线素材通过 clip_id(clip0、clip1……)解耦:Session._resolve_refs(session.py)在打开/新建工程时扫描 main_bin 中的 entry,为每个资源分配递增的 clip_id,并建立 clip_id → chain producer → resource 路径 的映射。后续所有时间线操作都只引用 clip_id,保证脚本可重放、可审计。
实战示例
创建新工程
cli-anything-shotcut project new -o myproject.json
# 程序化使用时加 --json:
cli-anything-shotcut --json project new -o myproject.json
导出工程
cli-anything-shotcut --project myproject.json export render output.mp4 --overwrite
确定性时间线重建
对于需要反复重建的工程,应优先使用绝对定位而非单纯的追加式插入:
cli-anything-shotcut --project myproject.mlt media import intro.mp4
cli-anything-shotcut --project myproject.mlt timeline add-clip clip0 \
--track 1 --in 00:00:00.000 --out 00:00:04.000 --at 00:00:00.000
cli-anything-shotcut --project myproject.mlt media import broll.mp4
cli-anything-shotcut --project myproject.mlt timeline add-clip clip1 \
--track 1 --in 00:00:10.000 --out 00:00:16.000 --at 00:00:08.000
三条约束决定了这个模式的可靠性:
--at落在空白区间时,工具会自动插入空白以填充间隙;- CLI 会拒绝与已有素材发生重叠的放置;
- 显式给出
--in/--out会让后续绝对定位无歧义。
音频自动化
音量包络与闪避(ducking)是自动化混音的高频场景:
cli-anything-shotcut --project myproject.mlt filter volume-envelope \
--track 2 \
--point 00:00:00.000=1.0 \
--point 00:00:03.000=0.35 \
--point 00:00:05.000=1.0
cli-anything-shotcut --project myproject.mlt filter duck \
--track 2 \
--window 00:00:06.000..00:00:09.000 \
--window 00:00:15.000..00:00:18.000 \
--normal 1.0 --duck 0.25
duck 的默认参数(shotcut_cli.py)为:--normal 1.0(正常音量)、--duck 0.25(闪避音量)、--attack 00:00:00.150(淡入闪避)、--release 00:00:00.250(从闪避恢复),窗口语法为 START..END,可重复传递多个窗口。
会话状态机制
CLI 全程维护会话状态,能力包括:
- Undo/Redo:最多 50 层历史(
MAX_UNDO_DEPTH = 50,session.py),每次变更前对整棵 XML 树做快照入栈; - 工程持久化:工程状态以
.mlt(XML)保存/加载; - 会话追踪:会话元数据(工程路径、修改标记、撤销/重做深度、时间戳)以 JSON 持久化到
~/.shotcut-cli/sessions/,写盘时还使用了fcntl文件锁保证并发安全。
时间码格式
任何需要时间值的位置都接受以下格式(见包内 README.md):
| 格式 | 示例 | 含义 |
|---|---|---|
HH:MM:SS.mmm |
00:01:30.500 |
1 分 30.5 秒 |
HH:MM:SS:FF |
00:01:30:15 |
1 分 30 秒第 15 帧 |
HH:MM:SS |
00:01:30 |
1 分 30 秒 |
SS.mmm |
90.5 |
90.5 秒 |
| 纯帧号 | 2715 |
第 2715 帧 |
测试覆盖见 test_core.py,其中 TestTimecode 系列用例验证了上述所有格式的解析与往返转换。
预览与实时预览:视觉化校验剪辑结果
preview 命令组用于在不打开完整渲染的情况下验证剪辑节奏、剪切点与滤镜效果:
| 命令 | 说明 |
|---|---|
preview recipes |
列出预览 recipe |
preview capture |
渲染一个低分辨率预览包 |
preview latest |
返回最新的已有预览包 |
preview live start |
启动实时预览会话并发布首个预览包 |
preview live push |
向实时会话发布新的预览包 |
preview live status |
查询当前会话状态(不触发渲染) |
preview live stop |
停止会话(不删除产物) |
典型的 quick recipe 预览包包含:
preview.mp4- 若干采样帧
- 中点
hero.png - 携带工程事实的
summary.json
quick 的参数(preview.py)为 640×360 低分辨率、h264-fast 预设,并在 0/25%/50%/75%/95% 五个比例点采样。支持轮询模式:
cli-anything-shotcut --json --project edit.mlt preview live start --recipe quick --mode poll --source-poll-ms 500
poll 模式下,后台监控进程(preview live monitor)会以 --source-poll-ms(默认 500ms,下限 250ms)的间隔监测工程文件变化并自动重新捕获。preview live status --json 会返回会话引用与紧凑的 trajectory_summary,让 Agent 可以低成本地了解最近几次发布的状态;完整轨迹则持久化在 trajectory.json 中。实时会话还会持久化 session.json 与不可变的 bundle 目录。
查看已发布的预览产物,可配合仓库中的 cli-hub 工具:
cli-hub previews inspect /path/to/bundle-or-session
cli-hub previews html /path/to/bundle-or-session -o page.html
cli-hub previews watch /path/to/session --open
cli-hub previews open /path/to/bundle-or-session
面向 AI Agent 的使用准则
当以程序化方式调用本 CLI 时,官方推荐遵循以下十一条准则:
- 始终使用
--json标志以获得可解析输出; - 检查返回码——0 表示成功,非零表示错误;
- 失败时解析 stderr 获取错误信息;
- 所有文件操作使用绝对路径;
- 导出操作后验证输出文件确实存在;
- 重建已知剪辑时优先使用
timeline add-clip --at; - 关键帧音量或闪避改动后,人工复核最终渲染结果;
- 使用
preview capture或preview live ...从视觉上验证节奏、剪切点与滤镜效果; - 读取返回的产物路径(如
hero.png、preview.mp4);JSON 载荷引用的是磁盘上的实际文件; - 读取完整
trajectory.json之前,先使用preview live status --json; cli-hub previews ...仅用于查看/打开已有的 bundle 或实时会话。
源码结构与验证
包的源码布局(位于 shotcut/agent-harness/cli_anything/shotcut/)按职责分为:
core/——领域逻辑:project.py、timeline.py、filters.py、media.py、transitions.py、compositing.py、export.py、preview.py、session.py;utils/——基础设施:mlt_xml.py(XML 树操作)、time.py(时间码解析)、melt_backend.py、preview_bundle.py、repl_skin.py;tests/——单元与端到端测试(test_core.py、test_full_e2e.py);- 入口:
shotcut_cli.py。
仓库还提供了可直接运行的示例:workflow_basic.sh 演示了“建工程 → 加轨道 → 看时间线 → 列滤镜 → 列预设 → 取 JSON 工程信息 → 列 profile”的完整链路;workflow_demo.py 则用 Python 编排了同样的流程。测试结果记录在 TEST.md 中,覆盖时间码解析、MLT XML 读写、会话撤销/重做、时间线增删改、滤镜应用等全部核心路径。
更多资料
- 包内完整命令参考:README.md
- 测试覆盖说明:TEST.md
- 架构分析与 MLT XML 深度解析:SHOTCUT.md
- 方法论(预览机制、会话锁定等通用实践):HARNESS.md
- 当前版本:1.0.0
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust4.2 K634
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown300
jforgamejforgame是一个一站式游戏服务器开发框架。包含游戏服务器开发所需要的各种组件,比如网关,socket服务端与客户端,自定义高效消息编解码,游戏热更新,游戏通用工具等等。包含游戏服,跨服,匹配服,后台管理系统等实现,同时提供大量业务案例以供学习。亦可用于其他socket应用,例如及时聊天等。Java101
fizz-gateway-nodeAn Aggregation API Gateway in Java . FizzGate 是一个基于 Java开发的微服务聚合网关,是拥有自主知识产权的应用网关国产化替代方案,能够实现热服务编排聚合、自动授权选择、线上服务脚本编码、在线测试、高性能路由、API审核管理、回调管理等目的,拥有强大的自定义插件系统可以自行扩展,并且提供友好的图形化配置界面,能够快速帮助企业进行API服务治理、减少中间层胶水代码以及降低编码投入、提高 API 服务的稳定性和安全性。Java60
certd开源SSL证书管理工具;全自动证书申请、更新、续期;通配符证书,泛域名证书申请;证书自动化部署到阿里云、腾讯云、主机、群晖、宝塔;https证书,pfx证书,der证书,TLS证书,nginx证书自动续签自动部署JavaScript60
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python280