给视频添加 TikTok 风格文字
此技能的文件位于 ${CLAUDE_PLUGIN_ROOT}/skills/add-text/:
scripts/add_text.py:请使用此脚本。 它通过两个命令完成整个任务。scripts/caption_match.py(检测/适配/检查)和scripts/tiktok_text.py(绘制+烧录):核心引擎。scripts/setup_check.py:首次运行设置和检查。fonts/:TikTok Sans(开源,OFL 许可证)。
这些样式是根据真实 TikTok 应用内视频测量得出的。请勿以任何其他方式渲染文字(如使用 ffmpeg drawtext、普通字体等),否则无法匹配。
第 0 步:设置(每次运行;完成后约需 2 秒)
使用 PATH 中的 python / python3 运行:
python "${CLAUDE_PLUGIN_ROOT}/skills/add-text/scripts/setup_check.py" "${CLAUDE_PLUGIN_DATA}"
-
首次运行会在插件数据目录中创建私有 Python 环境并安装软件包(大约需要 1-2 分钟)。请告知用户正在发生此操作。
-
最后一行输出
READY PY=<path>。在后续所有命令中使用该<path>作为 python 命令(记为PY)。 -
如果输出
NOT READY: ...,则表示缺少某些内容并给出精确的修复方法:- ffmpeg:询问用户,然后运行给出的安装命令(Windows 上为
winget,Mac 上为brew,Linux 上为apt)。在 Windows 上,可能需要新终端才能找到 ffmpeg。如果是这样,请告知用户重启 Claude Code。 - 没有 Python 3.9+:用户需要自行安装(python.org)并重启 Claude Code。
然后再次运行设置。
- ffmpeg:询问用户,然后运行给出的安装命令(Windows 上为
-
没有
python命令?尝试python3,或在 Windows 上尝试py。
在下面的命令中,S = ${CLAUDE_PLUGIN_ROOT}/skills/add-text/scripts。请引用所有路径。在 PowerShell 中,每条命令以 & 开头(例如 & "PY" "S/add_text.py" ...)。
规则
- 输出保持输入视频的大小和帧率(TikTok:1080x1920)。将带文字版本的视频保存在原文件旁边,命名为
<名称> (WITH TEXT).mp4,绝不覆盖原文件。 - 内容: TikTok 会处罚误导性声明。避免绝对化的结果声明(如“治愈”、“3 天内修复”、“保证”)。当参考视频的吸睛开头包含声明时,调整措辞(保持相同节奏和行数),并告知用户更改了什么以及原因。如果不确定请询问。
- 输入的文字必须与 iPhone 产生的内容一致:
…而非...- 如果参考视频使用了弯引号
’“ ”,则也使用弯引号 - 表情符号使用真正的 emoji 字符
- 开头和结尾的空格很重要:TikTok 会居中对齐每一行(包括空格)。
fit会自动为你添加这些空格。
A. 复制参考 TikTok 的文字
在用户视频旁边使用一个工作文件夹,例如 text work/。
- 开始:
"PY" "S/add_text.py" start "REF.mp4" "WORKDIR"- 输出每条标题:开始/结束时间(逐帧精确,基于参考视频时间轴)、样式、填充颜色和文本框。
- 将
WORKDIR/captions.json写入,其中"text": "??",以及每条标题的缩放裁剪图WORKDIR/caption_<n>.png。 - 它会跳过 TikTok 自家“TikTok @user”水印。
- 需要先下载参考视频?如果已安装
yt-dlp则可使用。否则询问用户提供文件。
- 填写文字。 阅读每张裁剪图,将每个
"??"替换为实际文字。- 保留其他字段。
_前缀的字段(_ref_t、_bbox_1080等)由 finish 命令使用。 - 换行使用
\n,表情符号使用字符。不必担心开头或结尾的空格。 - 如果两行之间的间距大约是正常行距的两倍,则说明中间有一个空行:使用
"A\n\nB"。 - 如果一条标题中有两个独立的文本框(大小差异很大、间距很大,或不在同一 x 轴居中):将它们拆分为两个条目,共享相同的开始/结束时间、
_ref_t和样式。为每一个设置独立的_bbox_1080:取该条目各行_lines_1080的并集(detect 会输出每一行的文本框和高度),以便 fit 定位正确的文字。示例:第 1 行:[346,1126,735,1167] 和第 2+3 行 →[346,1126,735,1167]和[204,1272,887,1389]。 - 如果
style返回了custom/custom_outline?这意味着使用了其他字体、背景框或其他颜色,此工具不支持。告知用户并选择最接近的样式。请勿无声猜测。 - 此处可重新调整时间,如果用户的剪辑与参考视频不同:编辑
start/end(秒,结束时间不包含)。Fit 和 check 仍会参考参考视频的自身时间(_ref_t)。
- 保留其他字段。
- 完成:
"PY" "S/add_text.py" finish "REF.mp4" "VIDEO.mp4" "WORKDIR"- 将 json 中的大小、位置和空格进行适配,并写入
WORKDIR/fit_<n>.png(参考视频在上方,我们的在下方)。 - 将任何超出视频长度的标题截断至视频的末尾。
- 在视频旁边烧录生成
VIDEO (WITH TEXT).mp4(或(no text)→(WITH TEXT))。第四个参数可指定其他输出名称。 - 检查结果并写入
WORKDIR/check.jpg(参考视频在左侧,我们在右侧)。 - 输出 SUMMARY: PASS 或 REVIEW 并说明原因。
- 将 json 中的大小、位置和空格进行适配,并写入
- 查看
check.jpg并在告知用户完成之前展示给用户。- 低重叠率伴随 “边缘与参考视频相差 N px 内”:表示大小和位置正确。压缩后的金色或黄色文字即使正确,得分也可能在 0.45-0.7。只需肉眼确认措辞即可。
- 低重叠率伴随 “边缘偏差 N px”:通常是拼写错误、遗漏换行符、使用了错误的样式,或者拆分后
_bbox_1080设置错误。修正 json 并重新运行 finish。 - 如需保留手动调整的大小/垂直位置/水平位置,请添加
--no-fit。
B. 新标题(无参考视频)
编写一个 captions.json 文件:
[{"text": "第一行\n第二行", "start": 0, "end": 3.5, "style": "outline", "size": 70, "y": 0.5}]
然后运行 "PY" "S/add_text.py" new "VIDEO.mp4" "WORKDIR/captions.json"。它会在视频上烧录文字并在 json 文件旁边生成 preview.jpg(每条标题对应一帧)。将其展示给用户。
- style:
classic(纯白)、outline(白色+黑色轮廓)、yellow(淡黄)、yellow_gold(金黄)、lilac(淡紫)。 - size: 大约 50(小)到 85(大)。典型的吸睛开头大小为 54-77。
- y: 0.4-0.5 = 屏幕中间,0.65 = 下方三分之一处。请避开底部 20%(TikTok 的标题/UI)和右侧边缘(按钮)。
- 可选:
x(水平居中位置,默认为 0.5)、weight、color(自定义填充颜色,格式为 "#RRGGBB")。 - 换行位置应与用户用手机打字时一致。在 size 70 时,每行大约 20-28 个字符。
无需渲染视频即可快速预览:"PY" "S/tiktok_text.py" --png "文字\n更多" out.png(经典样式)。
注意事项
- 典型耗时:启动约 25 秒,完成 1-3 分钟(取决于标题数量,轮廓样式适配最慢),
--no-fit约 40 秒。 - 表情符号:每个新表情符号首次使用时会下载一次(Apple 表情符号集,来自 jsDelivr 的 emoji-data CDN),因此首次需要联网。如果下载失败,脚本会报错。请告知用户,而不是直接丢弃该表情符号。
- 故意不添加阴影:真正的 TikTok 文字没有阴影。在压缩参考视频旁边看起来“更干净”是正常现象,一旦 TikTok 重新编码上传后就会消失。
- 只有 2 行文字时,fit 的间距修正器无法判断哪一行偏离中心。如果
fit_<n>.png显示某一行偏移约 5 像素且重叠率低于约 0.6,请尝试手动为每行添加尾部或首部空格后重新运行。 - Windows:如果表情符号在其他 Python 代码片段中显示异常,请设置
PYTHONIOENCODING=utf-8。这些脚本已处理好此问题。