大家好,我是陈工,大家还处在国庆的节假日当中,祝大家节日快乐,旅途愉快。
大家在刷短视频的时候,有没有经常刷到这种,比较搞笑的视频,一段视频,然后精彩的反转片段用素描的形式,来个特写。
并且这种视频,数据都非常的不错,如果,我们纯手工去做的话,做起来就很麻烦。
现在,我们可以借助扣子 Agent 智能体工作流,批量的去进行生成相关的视频,省时省力,1 分钟的时间,可以生成 100 多条视频,非常的容易上手。
下面,跟着陈工的步伐,一起去看看怎么搭建的吧!
视频号数据:
抖音数据:
1、视频抽帧,数据处理
视频抽帧” 节点会输出帧数据组成的数组,代码的作用是:对输入的 chunks 数组进行切片处理,去除数组的第一个元素,然后将处理后的数组作为输出返回。
详细的扣子工作流截图如下图所示:
(1)开始节点
video,就是上传我们需要进行二次创作的视频。
api_token,我们需要对创作的视频,进行剪辑,然后自动导入剪映。
注意:我们可以先不用管这个,先完整的搭建出来再说!
我们会需要使用到剪映小助手,所以就需要涉及到这个 api_token。
(2)视频抽帧
对于新手而言,如果不熟悉的话,可能就不太好找,这里,我给大家截图展示一下在哪里找。
具体的设置,如下图所示:
(3)代码数组处理
变量名 chunks,对应的就是视频抽帧。
完整代码如下:
async def main(args: Args) -> Output:
params = args.params
# 构建输出对象
ret: Output = {
"chunks": params["chunks"][1:]
}
return ret
关于输出的设置,
chunks 是一个 对象数组(Array),即数组里的每个元素都是一个 “包含多字段的对象”。
数组中每个对象包含 3 个关键字段:
index:整数类型(int),通常代表 “帧的序号 / 索引”(比如视频中第 N 帧)。
screenshot:字符串类型(str),通常代表 “该帧的截图相关内容”(比如截图的 Base64 编码、存储路径等)。
timestamp_ms:整数类型(int),代表 “该帧在视频中的时间戳(单位:毫秒)”(即该帧对应视频的哪个时间点)。
简单来说,chunks 是一组 “结构化的视频帧信息”,每个元素都清晰记录了某一帧的序号、截图、时间戳。
完整的截图:
2、循环处理
“循环处理” 节点的作用是遍历输入的 chunks 数据,对每个 chunk 依次执行循环体内的一系列操作(如字符串转换、AI 编辑、视频裁剪、变量聚合等逻辑),最终生成并输出处理后的 image_list(图像列表)和 video_list(视频列表),为后续的 “数据转换” 等步骤提供结构化的图像、视频数据。
详细的扣子工作流截图如下图所示:
(1)循环处理
循环类型,选择数组循环。
具体的设置,如下图所示:
(2)字符串处理
我们直接在插件商店,搜索“数据处理工具”。
关于变量的具体设置,大家可以看下图:
(3)插入 banana 图像生成节点
关于这个插件,我们直接在插件商店,搜索香蕉图像模型,然后选择红框里面的。
具体的设置,如下图所示:
prompt:
Convert images into black-and-white sketches, using flowing lines and intermittent, trembling brushstrokes to capture the essence of a figure's dynamic posture and expression in an instant. Unleash unfettered imagination through the collision of abstract exaggeration and humorous playfulness, with an appropriate touch of such boundless creativity
(4)选择器
据 “图片地址是否存在”,让流程走不同的后续步骤
具体设置,如下图所示:
(5)代码
简单说,就是划定 5 秒为一段视频的具体时间范围,方便把视频切成一小段一小段的。
async def main(args: Args) -> Output:
params = args.params
#获取视频结束时间
chunk = params['chunks'][-1]
end\_time = int(chunk['timestamp\_ms']/1000)
# 构建输出对象
ret: Output = {
"start":params["index"]*5,
"end":end\_time
}
return ret
具体的设置,如下图所示:
(6)视频剪辑
这里,我们需要借助扣子官方的视频剪辑工具,具体如下所示:
裁剪时间,还是以 5 秒为一个单位,具体的设置,如下图所示:
(7)代码数据处理
代码详细解释,方便大家从原理上进行了解代码的意图:
获取输入参数: params = args.params —— 从外部传入的参数中,提取所有需要的配置(比如图片 URL、视频 URL、时间戳 timestamp_ms 、序号 index 等)。
构建 “图片(image)” 的配置信息:生成一个字典,包含:
- 图片地址 image_url;
- 尺寸(宽1080、高1920);
- 显示的时间区间(start/end,通过 “时间戳 + 序号偏移” 计算,单位为纳秒);
- 入场动画(in_animation: "震波");
- 动画持续时间(in_animation_duration: 500000 纳秒)。
构建 “视频(video)” 的配置信息:生成一个字典,包含:
- 播放的时间区间(start/end,同样通过 “时间戳 + 序号偏移” 计算,单位为纳秒);
- 视频时长(duration: 5000000 纳秒);
- 视频地址 video_url;
- 尺寸(宽1080、高1920);
- 音量(volume: 0.01)。
构建最终输出对象:把 “视频配置”“图片配置”,以及 “图片的结束时间”( img_end_time ,和图片的 end 时间逻辑一致)打包成一个大字典 ret ,返回给后续流程。
# 在这里,您可以通过 'args' 获取节点中的输入变量,并通过 'ret' 输出结果
# 'args' 已经被正确地注入到环境中
# 下面是一个示例,首先获取节点的全部输入参数params,其次获取其中参数名为'input'的值:
# params = args.params;
# input = params['input'];
# 下面是一个示例,输出一个包含多种数据类型的 'ret' 对象:
# ret: Output = { "name": '小明', "hobbies": ["看书", "旅游"] };
import json
async def main(args: Args) -> Output:
params = args.params
image = {
"image\_url": params["img\_url"],
"width": 1080,
"height": 1920,
"start": params["timestamp\_ms"]*1000+params["index"]*2000000,
"end": params["timestamp\_ms"]*1000+params["index"]*2000000+2000000,
"in\_animation": "震波",
"in\_animation\_duration": 500000,
}
video = {
"start":params["timestamp\_ms"]*1000-5000000+params["index"]*2000000,
"end":params["timestamp\_ms"]*1000+params["index"]*2000000,
"duration":5000000,
"video\_url":params["video\_url"],
"width":1080,
"height":1920,
"volume":0.01
}
# 构建输出对象
ret: Output = {
"video":video,
"image":image,
"img\_end\_time":params["timestamp\_ms"]*1000+params["index"]*2000000+2000000
}
return ret
具体的设置,如下图所示:
(8)再次 banana 图像生成
此次的主要目的,是防止没有图片生成,相当于加了一道保险。
设置还是和之前的设置步骤是一样的。
(9)变量聚合
对多个分支输出的 img_url 相关值进行聚合处理,最终得到一个有效的 img_url,确保后续流程能获取到可用的图片地址。
(10)设置变量
要设置的 “中间变量” 是 循环处理 - img_end_time(属于循环流程里的一个变量);
“设置值” 来源于 代码_数据处理 - img_e...(即从 “代码_数据处理” 环节的输出中获取对应值)。
简单说:通过这个组件,把 “循环处理” 中用到的 img_end_time 变量,更新为 “代码_数据处理” 环节计算出的新值,保证后续循环能基于最新数据运行。
3、视频剪辑,导入剪映
对视频的宽度和高度等一些基础的数据做一下处理。
详细的扣子工作流截图如下图所示:
(11)数据转换
我给大家解释一下,每段代码的意思到底是什么意思。
import json :导入 JSON 模块,用于后续将数据序列化为 JSON 字符串。
async def main(args: Args) -> Output: :定义异步函数 main ,接收参数 args ,返回 Output 类型的结果。
params = args.params :从输入参数中提取所有配置参数。
bgm = params['bgm'] :获取背景音乐(BGM)的地址。
image_list = params["image_list"] :获取图片列表(包含每张图片的时间、地址等配置)。
video_list = params["video_list"] :获取视频列表(包含每个视频的时间、地址等配置)。
audios = [{...}] :构建音频配置: audio_url: bgm:音频地址为之前获取的背景音乐地址。
start: 0:音频从 0 时刻开始播放。
end: image_list[-1]['end']:音频播放到图片列表中最后一张图片的结束时刻为止。 8. 8. ret: Output = {...} :构建最终输出对象,把 image_list 、 video_list 、 audios 分别用 json.dumps 转成 JSON 字符串,作为 ret 中 images 、 videos 、 audios 字段的值。
return ret :返回整理好的多媒体配置信息,供后续流程使用。
import json
asyncdefmain(args: Args) -> Output:
params = args.params
bgm = params['bgm']
image\_list = params["image\_list"]
video\_list = params["video\_list"]
#结束时间减去2000000
audios = [{
"audio\_url": bgm,
"start": 0,
"end": image\_list[-1]['end']
}]
# 构建输出对象
ret: Output = {
"images": json.dumps(image\_list),
"videos": json.dumps(video\_list),
"audios":json.dumps(audios)
}
return ret
具体的设置,如下图所示:
题外话:
下面的每一步,都会用到这个插件,大家在插件商店,自行搜索添加即可。
(12)创建草稿
(13)批量添加音频
(14)批量添加视频
15、批量添加图片
16、接受输出视频链接
关于 api_token,我们打开剪映小助手官网,我们按照要求,一步一步的进行注册即可!
点击右上角这个圈圈
然后选择复制密钥就行了。
(1)上传视频
(2)获取视频链接
(3)剪映小助手
还是在前面的链接,直接下载,然后注册就行了。
输入 draft_url 链接,然后选择创建剪映草稿。
(4)一键导入剪映
上一步完成之后,这一步我们打开剪映,就可以看到我们的成片了。
本篇文章就给大家结束到这里了,使用起来非常的方便,生成一个视频的时间是很短的,特别是适合短视频从业者进行使用。
如果觉得文章对您有帮助的话,欢迎点赞、转发、收藏。
如果大家对扣子智能体 Agent 感兴趣,想要深入学习的话,欢迎主页添加我的微信!
