What does CapCut Caption Word Groups do?
Use this skill to repair CapCut captions whose materials.texts[].words arrays are split per Chinese character, causing templates such as 逐字显色粗体 绿 to scroll/highlight fragments instead of words.
This skill edits undocumented CapCut Desktop draft JSON. Always close CapCut, back up the draft, and verify in the CapCut preview before export. CapCut updates may change the draft schema.
Workflow
- Identify the active draft directory.
- Prefer the
.lockeddraft if CapCut has a project open. - Otherwise use the latest modified draft under
~/Movies/CapCut/User Data/Projects/com.lveditor.draft.
- Prefer the
- Close CapCut before writing draft files. CapCut can overwrite external edits while the editor is open.
- Inspect the target captions:
jq -r '.materials.texts[] | [(.content|fromjson.text), ((.words.text // [])|join("|"))] | @tsv' "$DRAFT/draft_info.json" - Run
scripts/regroup-caption-words.jsagainst the draft. - Reopen CapCut and visually check at least one early, middle, and late caption.
Script
Use the bundled script for the actual patch:
node scripts/regroup-caption-words.js \
--draft "$DRAFT" \
--fillers "呃,嗯,额" \
--backup
The script patches all active draft copies it finds:
- root
draft_info.json - root
template-2.tmp Timelines/*/draft_info.jsonTimelines/*/template-2.tmp
It updates both materials.texts[].words and extra_info.subtitle_fragment_info_list[].subtitle_cache_info.
Manual Group Map
For better editorial control, pass a JSON map from exact visible caption text to the desired groups:
{
"你会担心AI就是呃夺走你的工作吗": ["你会", "担心", "AI", "就是", "夺走", "你的", "工作", "吗"],
"以及他的呃知识库比我们都要多": ["以及", "他的", "知识库", "比", "我们", "都要", "多"]
}
Then run:
node scripts/regroup-caption-words.js \
--draft "$DRAFT" \
--groups-file groups.json \
--fillers "呃,嗯,额" \
--backup
The map may use the original text before filler removal. Each group list must concatenate to the cleaned caption text after filler removal.
Validation
After patching, verify:
jq empty "$DRAFT/draft_info.json" "$DRAFT/template-2.tmp" "$DRAFT"/Timelines/*/draft_info.json "$DRAFT"/Timelines/*/template-2.tmp
rg '呃|嗯|额' "$DRAFT/draft_info.json" "$DRAFT/template-2.tmp" "$DRAFT"/Timelines/*/draft_info.json "$DRAFT"/Timelines/*/template-2.tmp
Also validate that joined word groups equal visible text:
jq -r '.materials.texts[] | [(.content|fromjson.text), ((.words.text // [])|join("|"))] | @tsv' "$DRAFT/draft_info.json"
Notes
- Preserve template-backed structure. Do not flatten captions into per-word or per-character clips.
- Filler removal changes visible text but not video/audio timing.
- Automatic segmentation uses
Intl.Segmenter("zh", { granularity: "word" }); review results when subtitles are important. - A template renderer patch like
wordCountPerPageLimit(3)to2only changes how many metadata entries appear per page. It does not fix character-level word metadata. - CapCut may regenerate or rewrite caption metadata after manual caption edits. Re-run this skill after large subtitle edits.