PyCapCut
A lightweight, flexible, and easy-to-use Python tool for generating and exporting CapCut drafts to build fully automated video editing/remix pipelines! Another similar project: https://github.com/GuanYixuan/pyJianYingDraft
Install / Use
/learn @GuanYixuan/PyCapCutREADME
pyCapCut
与PyJianYingDraft同源的轻量、灵活、易上手Python CapCut草稿生成及导出工具,构建全自动视频剪辑/混剪流水线!
🧪 本项目正在从PyJianYingDraft进行迁移,欢迎⭐️此项目保持关注!
📢 欢迎加入Discord服务器进行用法或新功能的讨论
使用思路

功能清单
模板模式
🧪 本模块刚刚完成迁移,若出现不适配的情况欢迎提出issue
- ☑️ 加载(未加密的)
draft_content.json文件作为模板 - ☑️ 替换音视频片段的素材
- ☑️ 修改文本片段的文本内容
- ☑️ 将模板草稿中的音视频/文本轨道整体导入到另一草稿中
- ☑️ 提取模板中出现的贴纸/气泡/花字等元信息
批量导出
⚠️ 本模块正在迁移中,若有兴趣可参见PyJianYingDraft中相应部分
- ☑️ 控制CapCut打开指定草稿
- ☑️ 导出草稿至指定位置
- ☑️ 调节导出分辨率和帧率
视频与图片
🧪 本模块刚刚完成迁移,若有特效/动画/转场等不生效的情况欢迎提出issue
- ☑️ 添加本地视频/图片素材,并自定义片段的时间、持续时长或播放速度
- ☑️ 视频片段的音频淡入淡出效果
- ☑️ 视频整体调节(旋转、缩放、亮度等)以及关键帧生成
- ☑️ 视频片段的入场/出场/组合动画
- ☑️ 添加蒙版、片段特效和滤镜
- ☑️ 视频背景填充(示例代码)
贴纸
音频
- ☑️ 添加本地音频素材,并自定义片段的时间、持续时长或播放速度
- ☑️ 调整淡入淡出时长(示例代码),调整音量(示例代码)及其关键帧
- ☑️ 添加音频片段的场景音效果,并设置参数
轨道
- ☑️ 添加轨道以及将片段添加到指定轨道
- ☑️ 自定义视频/滤镜/特效轨道的层级关系
特效、滤镜和转场
- ☑️ 吸附于片段上的特效、滤镜和动画
- ☑️ 位于独立轨道的特效和滤镜
- ☑️ 添加转场(示例代码),并自定义其时长
文本及字幕
- ☑️ 添加文本、设置字体及样式、修改文本片段的位置及旋转设置
- ☑️ 文本的关键帧以及动画
- ☑️ 文字描边、背景和阴影
- ☑️ 文字气泡效果和花字效果(示例代码)
- ☑️ 文本自动换行,支持设置最大行宽
- ☑️ 导入
.srt文件生成字幕并批量设置格式
安装
pyCapCut现已支持pip安装(不含demo)
pip install pycapcut
跨平台兼容性
Linux和MacOS用户也可正常安装和使用,但注意生成的草稿仍然需要在Windows版CapCut下导出。
快速上手
例程demo.py将创建包含音视频素材和一行文本的CapCut草稿文件,并且添加了音频淡入、视频入场动画、转场效果、关键帧和文本气泡/花字。
这个例程的操作方法如下:
- 找到CapCut的草稿文件夹路径(类似
.../CapCut Drafts),用其替换代码中的<你的草稿文件夹> - 运行
demo.py - 在CapCut中找到并打开新创建的
demo草稿(可能需要进入再退出某个已有草稿,或重启CapCut以刷新草稿列表),你应该看到类似如下的时间轴:

你可以仔细检查音频片段的音量设置、淡入效果时长等,看看是否符合上述代码的设置
用法文档
ℹ 文档部分推荐从功能清单一节中选取感兴趣的功能阅读,而非直接按顺序阅读
模板模式
🧪 本模块刚刚完成迁移,若出现不适配的情况欢迎提出issue
为了保留部分复杂特性(文本特效、复合片段...),可以加载一个已有的CapCut草稿作为模板,然后将其中内容导入到另一的草稿中,或直接替换其中部分片段的内容。
目前提供了三种替换功能:
除此之外,对于某些没有特定名称的特性(贴纸、花字等),提供了提取素材元数据的功能以提取其resource_id
ℹ 若出现模板内容丢失的情况,欢迎反馈
加载模板
推荐使用DraftFolder来管理CapCut的草稿文件夹(可以在CapCut的全局设置-草稿位置中查询),这样能够方便地根据已有模板生成新草稿。
import pycapcut as cc
draft_folder = cc.DraftFolder("<CapCut草稿文件夹>") # 一般形如 ".../CapCut Drafts"
script = draft_folder.duplicate_as_template("模板草稿", "新草稿") # 复制"模板草稿",并命名为"新草稿",同时打开新草稿供编辑
# 对返回的ScriptFile对象进行编辑,如替换素材、添加轨道、片段等
script.save() # 保存你的"新草稿"
为了最大限度地兼容模板中的复杂特性,导入的轨道与pycapcut创建的轨道是分离开的,具体地讲:
- 除下述替换功能外,不能在导入的轨道上添加片段、转场、淡入淡出、特效等
- 仍然可以创建新的轨道,并在其上添加片段等,就像非模板模式一样
ℹ 导入轨道的限制也许会在后续版本中逐渐取消
提取素材元数据
对导入的ScriptFile对象,可以调用inspect_material方法提取部分素材的resource_id。
DraftFolder也有相应的方法来提取指定草稿的素材元数据。
import pycapcut as cc
draft_folder = cc.DraftFolder("<CapCut草稿文件夹>")
draft_folder.inspect_material("草稿名称")
# 或者
script = draft_folder.load_template("草稿名称")
script.inspect_material()
上述代码的输出可能类似于
贴纸素材:
Resource id: 7405878923323641129 '秋日手绘-枫叶'
Resource id: 7429353555447893260 '电商购物促销/哇哦'
Resource id: 7437707455267671315 '冬日涂鸦winter雪花冬天vlog装饰文字'
Resource id: 7343931192204463401 '爱心'
文字气泡效果:
Effect id: 763870 ,Resource id: 6838834573413978631 '标题59'
花字效果:
Resource id: 7342020000812731658 '彩色手绘线条花字'
其中的元数据可用于添加相应素材(例如通过StickerSegment的resource_id参数)
根据名称替换素材
这种方法将替换素材本身,而不对片段进行直接修改。
ℹ 由于素材有名称(默认是本地文件的名称),这种替换方式的定位比较方便
ℹ 由于不涉及时间范围的修改,这种替换方式尤其适合图像素材,且几乎不会产生兼容性的问题
以快速上手中的草稿为例,假如我们希望换用新的音频素材,可以:
new_material = cc.AudioMaterial("<新的音频素材路径>")
script.replace_material_by_name("audio.mp3", new_material) # 替换名称为"audio.mp3"的素材
替换新素材后,片段所截取的部分仍是素材前5秒,且音量、淡入淡出、播放速度等仍保持不变。
根据片段替换素材
这种方法将替换某个特定片段的素材,同时可以重新选取其引用的素材范围并根据新时长在时间轴上伸缩片段。
ℹ 由于片段没有名称,故通常需要依靠片段的下标来定位
此过程分为两步:选取轨道和替换素材,以上方音频素材的替换为例:
from pycapcut import trange, ShrinkMode, ExtendMode
audio_track = script.get_imported_track(
cc.TrackType.audio, # 选取导入的音频轨道
#name="audio", # 假如轨道有名称,最好利用名称来定位
index=0 # 也可用下标定位, 0表示最底层的同类型轨道
)
script.replace_material_by_seg(
audio_track, 0, new_material, # 选取audio_track中下标为0的片段,也即第一个片段
#source_timerange=None, # 若不指定,则默认使用整个素材
source_timerange=trange("0s", "10s"), # 此处指定截取素材前10秒(注意原片段时长为5秒)
handle_shrink=ShrinkMode.cut_tail, # 片段若要缩短,则依靠前移终止点来实现
handle_extend=ExtendMode.push_tail # 片段若要延长,则依靠后移终止点来实现,必要时允许后移后续片段
)
从例子中可见,此替换方法可能会造成片段的时长变化,故可以利用handle_shrink和handle_extend参数指定片段在缩短和延长时的处理方式。
ℹ 不显式指定
handle_shrink和handle_extend时,默认的处理方式如下:
- 新素材比原素材短,则前移片段终止点,使得片段长度与新素材长度一致
- 新素材比原素材长,则裁剪素材范围,保持片段原长不变
具体的处理方式列表可参见枚举类ShrinkMode和ExtendMode的定义。
ℹ 目前已知替换带有组合出入场动画的片段不会自动刷新动画时间
替换文本片段的内容
这种方法将替换某个特定文本片段的内容,但保留其所有格式。
此过程同样分为选取轨道和替换内容两个步骤:其中“选取轨道”可参考根据片段替换素材中的示例。
以下假定我们已经选取了合适的文本轨道text_track,则只需:
script.replace_text(
text_track, 0, # 选取text_track中下标为0的片段,也即第一个片段
"新文本内容" # 新的文本内容
)
导入模板草稿中的轨道
此功能会字面意义地复制模板草稿中的指定轨道到新草稿中, 适合用于拼接多个模板草稿。
ℹ 目前仅支持导入音视频/文本轨道, 支持的范围将来会继续扩展
⚠️ 本方法会保留各片段及其素材的id, 因而不支持向同一草稿多次导入同一轨道
例如
source_script = draft_folder.load_template("<模板草稿名称>") # 加载模板草稿
target_script = draft_folder.create_draft("新草稿", 1920, 1080) # 创建新草稿
# 选取模板中的一个文本轨道
text_track = source_script.get_imported_track(
cc.TrackType.text, # 选取导入的文本轨道
#name="text", # 假如轨道有名称,最好利用名称来定位
index=0 # 也可用下标定位, 0表示最底层的同类型轨道
)
# 导入文本轨道到新草稿
target_script.import_track(
source_script, text_track,
offset=target_script.duration, # 导入的轨道将放在新草稿末尾
new_name="imported_text", # 可选的新轨道名
relative_index=1, # 相对于所有文本轨道的位置, 值越大越接近前景, 可以是负数
)
时间与轨道
时间格式
CapCut(和本项目)内部均采用微秒为单位保存时间,但这不便于输入,故我们增加了一种“字符串形式”的时间,大部分时间参数均同时支持这两种形式:
- 微秒形式:用
int表达,适于计算 - 字符串形式:用
str表达,如"1.5s"、"1h3m12s"等,易于输入
如果你希望显式地将字符串形式转换为微秒形式,可以使用tim函数;trange函数则是支持字符串形式输入的Timerange便捷构造函数。
⚠️ 注意
trange的第二个参数是持续时长,而不是结束时间
例如:
import pycapcut as cc
from pycapcut import SEC, tim, trange
# 1秒钟
assert 1000000 == SEC == tim("1s") == tim("0.01666667m")
# 0~1分钟
assert cc.Timerange(0, 60*SEC) == trange("0s", "1m") == trange("0s", "0.5m30s")
# 片段开始后2秒
seg: cc.VideoSegment
assert seg.target_timerange.start + 2*SEC == seg.target_timerange.start + tim("2s")
素材截取与整体变速
截取和变速均在Segment创建时设置完成,具体是通过target_timerange、source_timerange和speed参数来共同实现的。
ℹ 目前暂不支持设置曲线变速
以下以VideoSegment为例,AudioSegment的用法相同,此二者支持两种构造方式:
- 便捷构造:直接传入素材路径字符串,自动构造素材实例
- 传统构造:先创建素材实例,再传入片段构造函数。若需要设置素材的图像裁剪属性请使用此方式
import os
import pycapcut as cc
from pycapcut import trange, SEC
# 假定已有草稿文件script(参见“快速上手”),创建三个轨道
for i in range(3, 0, -1): # 倒序
script.add_track(cc.TrackType.video, "%d" % i)
# 以下部分讲解素材与片段的创建
# 方式一:便捷构造(推荐)
tutorial_asset_dir = os.path.join(os.path.dirname(__file__), 'readme_assets', 'tutorial')
video_path = os.path.join(tutorial_asset_dir, 'video.mp4')
# 直接传入素材路径
seg1 = cc.VideoSegment(video_path, trange("0s", "4s")) # 截取素材的前4秒
# 方式二:传统构造
mat = cc.VideoMaterial(video_path) # 先创建素材实例
seg2 = cc.VideoSegment(mat, trange("0s", "4s")) # 再传入片段构造函数
# 视频素材长度为 5s
print("Video material length: %f s" % (mat.duration / SEC))
# 以下部分讲解素材的时间截取与变速
# 不指定source_timerange,则自动从头截取素材等长片段
seg11 = cc.VideoSegment(video_path, trange("0s", "4s")) # 自动截取素材的前4秒(4s表示持续时长)
seg2 = cc.VideoSegment(video_path, trange("0s", "4s"), speed=1.25) # 自动截取素材的前4*1.25=5秒
seg4 = cc.VideoSegment(video_path, trange("0s", "3s"), speed=3.0) # 截取前3*3.0=9秒,素材不够长故报错
# 指定source_timerange,则截取素材的指定片段,自动设置速度
seg12 = cc.VideoSegment(video_path, trange("4s", "1s"),
source_timerange=trange(0, "4s")) # 将素材在1s内放完,速度自动设置为5.0
# 同时指定source_timerange和speed,则截取素材的指定片段,并根据播放速度覆盖target_timerange的duration
seg3 = cc.VideoSegment(video_path, trange("1s", "66666h"),
source_timerange=trange(0, "5s"),
speed=2.0) # 将长5s的素材按2倍速放完,target_timerange的duration自动设为2.5s
# 将片段加入轨道
script.add_segment(seg11, "1").add_segment(seg12, "1")
script.add_segment(seg2, "2")
script.add_segment(seg3, "3")
多轨道操作
目前ScriptFile.add_track方法已支持创建多个同类型轨道,并支持自定义其顺序:
script.add_track(cc.TrackType.video,
track_name="前景", # 轨道名
relative_index=2) # 在所有视频轨道中的相对位置
script.add_track(cc.TrackType.video,
track_name="背景",
relative_index=1) # 由于1<2,所以前景轨道位于更上方
ℹ 对于相同index的轨道,默认后创建的轨道位于上方
一旦创建了多个同类轨道,则在添加片段时必须指定目标轨道,例如:
script.add_segment(video_segment, "背景")
视频整体调节
每个视频片段都可以单独设置裁剪、旋转、翻转、缩放、透明度、亮度等属性,这些设置通过VideoSegment构造函数中的clip_settings参数传入
ℹ 关键帧的优先级高于整体调节,故前者会覆盖后者的相应设置
下方的例子将创建一个视频片段,并设置其不透明度为0.5、打开水平翻转:
from pycapcut import ClipSettings
video_segment = cc.VideoSegment(video_material,
cc.Timerange(0, video_material.duration), # 与素材等长
clip_settings=ClipSettings(alpha=0.5, # 不透明度为0.5
flip_horizontal=True) # 打开水平翻转
)
更具体的参数说明可参见`ClipSet
