action、set_var、for 等)以及参数结构。{
"inputs": { ... },
"script": [
{ "type": "action", "action_type": "add_text", "params": "{...}" },
{ "type": "for", "in": "${...}", "loop": [...] }
]
}inputs (输入变量定义) 和 script (工作流步骤定义)。{
"inputs": {
// 定义输入变量及其默认值
"variable_name": "default_value",
"segments": []
},
"script": [
// 步骤列表,按顺序执行
{ ... step 1 ... },
{ ... step 2 ... },
// ...
]
}${} 包裹来显式引用所有变量和表达式。| 类别 | 格式 | 示例 | 描述 |
|---|---|---|---|
| 输入变量 | ${variable_name} | ${first_image} | 引用在 inputs 中定义的变量。 |
| 步骤输出 | ${step_id.output} | ${uuid_2.output} | 引用 ID 为 uuid_2 的步骤的执行结果。 |
| 循环变量 | ${item} 或 ${index} | ${item.audio_url} | 在 for 循环内部,item 指当前元素,index 指当前索引(从 0 开始)。 |
| 表达式 | ${expression} | ${total_duration} + ${uuid_2.output} | 包含变量和运算符的 Python 风格表达式。 |
simpleeval 安全地执行算术和布尔运算。| 类别 | 运算符/关键词 | 示例 | 结果类型 |
|---|---|---|---|
| 算术运算 | +, -, *, / | ${a} + 5 | 数字 (Int/Float) |
| 比较运算 | ==, !=, >, <, >=, <= | ${index} == 0 | 布尔 (True/False) |
| 逻辑运算 | and, or, not | not ${scale_big} | 布尔 (True/False) |
| 列表/字典 | 索引 ([]), 属性 (.) | ${segments}[0], ${item.audio_url} | 混合 |
script 数组)type、id 和 index 字段。| 字段 | 类型 | 是否必须 | 描述 |
|---|---|---|---|
type | String | 是 | 步骤的类型,决定执行什么操作。枚举见下表。 |
name | String | 否 | 用于用户界面展示的步骤名称(通常用于 set_var)。 |
id | String | 是 | 步骤的唯一标识符。用于在后续步骤中引用其输出(如 ${uuid_2.output})。 |
index | Number | 是 | 执行顺序优先级。 步骤将按此字段升序执行。相同 index 的步骤按其在数组中的自然顺序执行。 |
type)| Type | 描述 | 必需字段 | 主要用途 |
|---|---|---|---|
set_var | 设置或更新一个工作流变量。 | name, value | 状态管理,计数器,布尔标志。 |
action | 调用一个外部功能/原子操作。 | action_type, params | 调用视频编辑 API、获取时长等。 |
if | 实现条件分支逻辑。 | condition, then | 根据条件跳转执行不同的步骤。 |
for | 实现循环迭代逻辑。 | in, loop | 遍历列表(如视频片段)执行重复操作。 |
break | 立即终止当前 for 循环。 | 无 | 跳出循环。 |
type: set_var)| 字段 | 类型 | 必需 | 描述 |
|---|---|---|---|
name | String | 是 | 要设置的变量名。 |
value | String/Number | 是 | 变量的新值。通常需要使用 ${} 来计算表达式。 |
[
// 1. 累加总时长
{
"type": "set_var",
"name": "total_duration",
"value": "${total_duration} + ${uuid_2.output}",
"index": 6
},
// 2. 布尔变量取反
{
"type": "set_var",
"name": "scale_big",
"value": "not ${scale_big}", // 必须使用 'not' 关键字
"index": 5
}
]type: if)if 步骤用于根据布尔条件选择性地执行一组步骤。| 字段 | 类型 | 必需 | 描述 |
|---|---|---|---|
condition | String | 是 | 必须是一个计算结果为 True 或 False 的表达式。 |
then | Array | 是 | 当 condition 为 True 时执行的步骤列表。 |
else | Array | 否 | 当 condition 为 False 时执行的步骤列表。 |
{
"type": "if",
"condition": "${index} == 0", // 使用循环变量 index
"id": "uuid_4",
"index": 3,
"then": [
// index == 0 时执行的步骤 (例如添加片头)
{ "type": "action", ... }
],
"else": [
// index != 0 时执行的步骤
{ "type": "action", ... }
]
}type: for)for 步骤用于迭代列表、字典或数字范围,并重复执行内部的步骤序列。| 字段 | 类型 | 必需 | 描述 |
|---|---|---|---|
in | String | 是 | 必须是一个引用列表变量的表达式,例如 ${segments}。 |
loop | Array | 是 | 在每次迭代中执行的步骤列表。 |
item_name | String | 否 | 循环内代表当前元素的变量名 (默认: item)。 |
index_name | String | 否 | 循 环内代表当前索引的变量名 (默认: index)。 |
segments 列表):{
"type": "for",
"in": "${segments}", // 遍历输入的 segments 列表
"id": "uuid_1",
"index": 1,
"loop": [
// 在这里,可以使用 ${item} 和 ${index}
{
"type": "action",
"action_type": "add_audio",
"params":
{
"audio_url":"${item.audio_url}"
} // 引用当前元素的属性
},
// ... 其他步骤
]
}type: action)action 步骤用于调用预定义的外部功能(例如视频编辑 API)。| 字段 | 类型 | 必需 | 描述 |
|---|---|---|---|
action_type | String | 是 | 要执行的具体操作类型。(由系统定义,例如 add_image, get_duration 等)。 |
params | String | 是 | 包含操作所需参数的 JSON 字符串。内部的变量必须使用双反斜杠进行转义 (\\")。 |
{
"type": "action",
"action_type": "add_image",
"id": "uuid_3",
"params":
{
"image_url":"${item.image_url}",
"start":"${total_duration}",
"end":"${total_duration} + ${uuid_2.output}"
}
// 注意:${uuid_2.output} 是前一步骤 get_duration 的执行结果
}type) 设置为 action 时,系统将调用一个预定义的剪辑操作来执行具体的剪辑任务。您需要通过填写 params 字段来设置该操作的所有配置参数。action_type 枚举)| Action Type | 描述 | 文档链接 |
|---|---|---|
add_text | 在视频上添加静态或动态文本。 | add_text |
add_subtitle | 添加字幕轨道,通常用于显示音频或视频内容对应的文本。 | add_subtitle |
add_text_template | 添加基于预设样式的文本模板(如标题卡、动态文字效果)。 | add_text_template |
add_image | 将图片添加到时间线上的特定轨道和时间段。 | add_image |
add_video | 将视频素材添加到时间线上的特定轨道和时间段。 | add_video |
add_audio | 将音频素材添加到时间线上的特定轨道和时间段。 | add_audio |
add_video_keyframe | 为时间线上已有的素材(图片/视频)添加关键帧动画。 | add_video_keyframe |
add_effect | 为时间线上的素材或整个视频添加视觉效果或滤镜。 | add_effect |
add_sticker | 添加动态贴纸或装饰性元素。 | add_sticker |
get_duration | 获取指定媒体文件(音频或视频)的精确时长。 | video_url 或 audio_urlget_duration |
params 字段格式说明add_audio 的参数"params":
{
"audio_url":"${item.audio_url}",
"target_start":"${total_duration}"
}"params": {"start":1.234}{
"inputs": {
"text": "Hello!",
"start": 0,
"end": 15.0
},
"script": [
{
"type": "action",
"id": "uuid_1",
"index": 0,
"action_type": "add_text",
"params": {
"text": "${text}",
"start": "${start}",
"end": "${end}",
"track_name": "text_main",
"font_size": 8.0,
"font_color": "#FF0000"
}
},
{
"type": "action",
"id": "uuid_2",
"index": 1,
"action_type": "add_text",
"params": {
"text": "这是第二行文本",
"start": 0.0,
"end": 5.0,
"track_name": "text_1",
"transform_y": 0.3
}
},
{
"type": "action",
"id": "uuid_3",
"index": 2,
"action_type": "add_subtitle",
"params": {
"srt_path": "1\n00:00:00,000 --> 00:00:04,433\n你333好,我是孙关南开发的剪映草稿助手。\n\n2\n00:00:04,433 --> 00:00:11,360\n我擅长将音频、视频、图片素材拼接在一起剪辑输出剪映草稿。\n",
"track_name": "subtitle_1",
"font_size": 5.0
}
},
{
"type": "action",
"id": "uuid_4",
"index": 3,
"action_type": "add_text_template",
"params": {
"template_id": "7373303725881822491",
"start": 2.0,
"track_name": "text_template_main"
}
},
{
"type": "action",
"id": "uuid_5",
"index": 4,
"action_type": "add_image",
"params": {
"image_url": "https://pic1.imgdb.cn/item/68ba8fc058cb8da5c8801ab0.png",
"start": 5.0,
"end": 10.0,
"track_name": "image_main",
"scale_x": 0.8,
"scale_y": 0.8
}
},
{
"type": "action",
"id": "uuid_6",
"index": 5,
"action_type": "add_video",
"params": {
"video_url": "https://cdn.wanx.aliyuncs.com/wanx/1719234057367822001/text_to_video/092faf3c94244973ab752ee1280ba76f.mp4?spm=5176.29623064.0.0.41ed26d6cBOhV3&file=092faf3c94244973ab752ee1280ba76f.mp4",
"target_start": 10.0,
"track_name": "video_main"
}
},
{
"type": "action",
"id": "uuid_7",
"index": 6,
"action_type": "add_audio",
"params": {
"audio_url": "https://lf3-lv-music-tos.faceu.com/obj/tos-cn-ve-2774/oYACBQRCMlWBIrZipvQZhI5LAlUFYii0RwEPh",
"start": 0.0,
"track_name": "audio_main",
"volume": 0.8
}
},
{
"type": "action",
"id": "uuid_8",
"index": 7,
"action_type": "add_video_keyframe",
"params": {
"track_name": "video_main",
"time": 10.5,
"property_type": "position_y",
"value": 1.0
}
},
{
"type": "action",
"id": "uuid_9",
"index": 8,
"action_type": "add_video_keyframe",
"params": {
"track_name": "video_main",
"time": 11.5,
"property_type": "position_y",
"value": 0.2
}
},
{
"type": "action",
"id": "uuid_10",
"index": 9,
"action_type": "add_video_keyframe",
"params": {
"track_name": "video_main",
"times": [10.5, 12.5],
"property_types": ["position_x", "position_x"],
"values": [1.0, -1.0]
}
},
{
"type": "action",
"id": "uuid_11",
"index": 10,
"action_type": "add_effect",
"params": {
"effect_category": "scene",
"effect_type": "金粉闪闪",
"start": 0.0,
"end": 10.0,
"track_name": "effect_01",
"params": [100, 50, 34]
}
},
{
"type": "action",
"id": "uuid_12",
"index": 11,
"action_type": "add_sticker",
"params": {
"resource_id": "7107529669750066445",
"start": 20.0,
"end": 25.0,
"transform_y": 0.3,
"transform_x": -0.2,
"alpha": 0.8,
"rotation": 45.0,
"scale_x": 1.5,
"scale_y": 1.5,
"track_name": "sticker_main"
}
}
]
}{
"inputs": {
"audio_infos": [
{
"audio_url": "https://lf3-appstore-sign.oceancloudapi.com/ocean-cloud-tos/VolcanoUserVoice/speech_7468512265134932019_7c58074f-3191-499d-8f0f-2f34746cba9f.mp3?lk3s=da27ec82&x-expires=1761462051&x-signature=SdXpkgiuY0h6VRzjAS9ysNnXVtA%3D"
},
{
"audio_url": "https://lf3-appstore-sign.oceancloudapi.com/ocean-cloud-tos/VolcanoUserVoice/speech_7468512265134932019_ff35cbf0-7f9e-421b-a3c6-649a5d6f014e.mp3?lk3s=da27ec82&x-expires=1761462052&x-signature=I%2BsyOSosoxACPvW9brJw2Fs1A%2Fc%3D"
}
]
},
"script": [
{
"type": "set_var",
"name": "total_duration",
"id": "uuid_0",
"value": 0,
"index": 0
},
{
"type": "for",
"in": "${audio_infos}",
"id": "uuid_1",
"index": 1,
"loop": [
{
"type": "action",
"action_type": "get_duration",
"id": "uuid_2",
"index": 0,
"params": {
"video_url": "${item.audio_url}"
}
},
{
"type": "action",
"action_type": "add_audio",
"id": "uuid_3",
"index": 1,
"params": {
"audio_url": "${item.audio_url}",
"target_start": "${total_duration}"
}
},
{
"type": "set_var",
"name": "total_duration",
"id": "uuid_4",
"value": "${total_duration} + ${uuid_2.output}",
"index": 2
}
]
}
]
}{
"inputs": {
"is_premium_user": false,
"video_duration": 10.0
},
"script": [
{
"type": "if",
"condition": "${is_premium_user} == True",
"id": "check_vip_status",
"index": 0,
"then": [
{
"type": "action",
"action_type": "add_text",
"id": "add_vip_watermark",
"index": 0,
"params": {
"text": "⭐ VIP 专属内容 ⭐",
"start": 0.0,
"end": "${video_duration}",
"track_name": "watermark_track",
"transform_x": -0.4,
"transform_y": 0.45,
"font_size": 5.0,
"font_color": "#FFC107"
}
}
],
"else": [
{
"type": "action",
"action_type": "add_text",
"id": "add_free_version_text",
"index": 0,
"params": {
"text": "免费预览版本",
"start": 0.0,
"end": 2.0,
"track_name": "watermark_track",
"transform_y": -0.45,
"font_size": 4.0,
"font_color": "#FFFFFF"
}
}
]
}
]
}