When to trigger
The user says:
- "Help me cut a short / short video"
- "Pull the highlights from this video and make an essence cut"
- "Make a 2-minute version"
- "Cut a short video using X timecodes"
Prerequisites
Must haveLong video outputs from having already run claude-youtube-video-workflow or codex-youtube-video-workflow :
working/<video-id>/<video-id>.cut.mp4(the version after cutting the talking-head)working/<video-id>/<video-id>.srt(the subtitles after text cleanup, with timecodes aligned to cut.mp4)
If these two files have not been generated yet, run the long-video master control workflow first.
Specs (decided by the user)
| Item | Setting |
|---|---|
| Audio/video format | Primarily 16:9 editing, and a 9:16 vertical version must also be produced(for YouTube Shorts publishing; decided by the user 2026-07) |
| Vertical method | make_vertical.py: content scaled proportionally and centered without cropping, top and bottom filled with a blurred background, 1080×1920 |
| Cover size | 16:9(shares the template with the long video) |
| Output folder | **`output/<short video title> [Claude |
| Short video duration limit | ≤ 120 seconds |
| Opening Hook | ≤ 5 seconds |
| Number of candidate versions | 3(different hook strategies) |
| Internal files | 7:<標題>.mp4(16:9 clean) / <標題>_字幕版.mp4(16:9 burned-in subtitles) / <標題>_直式9x16.mp4 / .srt / .txt / cover.png / metadata.md |
Workflow
Step 1: Read in and confirm
- Read
working/<video-id>/<video-id>.srt, understand the full video content and timecodes - Confirm
cut.mp4exists - Get the long video's total duration (ffprobe)
Step 2: Highlight detection (automatic mode)
Scan all subtitle segments according to the following "Highlight Detection Checklist" and mark candidates:
| Highlight type | Subtitle feature examples |
|---|---|
| Pain point declaration | "Every year you have to…" "The most painful…" "Nobody likes…" |
| Rhetorical question | "Are you still…?" "Why…?" |
| Number promise | "3 steps" "5 minutes" "one click…" |
| Strong assertion | "As long as… then…" "The most…" "Never again…" |
| Turning point reveal | "But actually…" "As a result…" "Didn't expect…" |
| Value reckoning | "Saved…" "Gained…" "In exchange for…" |
| Call to action | "You just need to…" "You can…" |
Give each segment a highlight score from 0–3 and record it in the working notes.
Step 3: Assemble three candidate versions
Each version follows the three-act structure:
[幕 1] Hook (≤ 5s):選一段最強的亮點當開頭,抓住注意力
[幕 2] Body (60–100s):3–6 段邏輯連貫的內容,串起 hook 的承諾
[幕 3] CTA / 收尾 (5–15s):呼應 hook,給一個記憶點或行動
The three versions followDifferent hook strategies:
| Version | Hook strategy | Suitable scenario |
|---|---|---|
| A | Pain-point type Hook (starting with "Are you still...") | The audience resonates with the pain point |
| B | Curiosity type Hook (starting with "I didn't expect..." "Actually...") | Want to go viral |
| C | Promise type Hook (starting with "Done in 3 minutes...") | Strongest for tool tutorial content |
Logic coherence check: Within each version, adjacent paragraphs must connect semantically (the end of the previous paragraph → the start of the next paragraph must not break). If the semantics don't connect, add a transition subtitle or reselect.
Step 4: Write a candidate list and wait for the user to choose
Write to working/<video-id>/shorts-candidates.md:
# 短片候選 — <video-id>
## 版本 A:痛點型
- **時長**:1:42
- **時間碼**:00:00:08.500-00:00:13.200, 00:00:45.100-00:01:30.800, 00:01:55.000-00:02:05.000
- **三幕劇本**:
- Hook:「你還在手動填課程計畫嗎?」(4.7s)
- Body:示範 3 個步驟讓 Claude 自動填表(45.7s)
- CTA:「再也不用熬夜寫課程計畫」(10.0s)
- **預估亮點命中率**:8/10
## 版本 B:好奇型
(同上格式)
## 版本 C:承諾型
(同上格式)
Report the three versions to the user,stop and wait for the user to choose number A/B/C, or:
- "I'll give you the timecodes myself" → skip to step 5 and use the timecodes provided by the user
- "Generate 3 more versions" → rerun step 3 and adjust the hook strategy
Step 5: After the user decides — slice + assemble
Call the packaging script:
python skills/short-video-workflow/scripts/clip_cut.py \
--input-mp4 "working/<video-id>/<video-id>.cut.mp4" \
--input-srt "working/<video-id>/<video-id>.srt" \
--segments "00:00:08.500-00:00:13.200,00:00:45.100-00:01:30.800,00:01:55.000-00:02:05.000" \
--out-dir "working/<video-id>/short-tmp/"
The script will produce:
short-tmp/short.mp4(ffmpeg trim+concat, re-encode to ensure clean cut points)short-tmp/short.srt(re-edit subtitles according to the new timeline)short-tmp/short.txt(plain text transcript)
After it finishes runningconfirm the duration ≤ 120 seconds(ffprobe); if it exceeds that, go back to step 4 and reassemble.
Step 6: Add an ending card and burn in subtitles
- Add an ending card: Place a 3-second "For the detailed video, please see the comments" card at the very end of the video. Call the packaging script:
python skills/short-video-workflow/scripts/add_end_card.py \
--input-mp4 "working/<video-id>/short-tmp/short.mp4" \
--output-mp4 "working/<video-id>/short-tmp/short_with_card.mp4"
This will generate short-tmp/short_with_card.mp4(total length increases by 3 seconds, displaying a deep navy blue #0A192F background, neon bright blue text with white outline card, including a silent audio track).
- Burn in subtitles:
Use
burn_subtitles.pyto burn the.srtsubtitles into the video:
python skills/short-video-workflow/scripts/burn_subtitles.py \
"working/<video-id>/short-tmp/short_with_card.mp4" \
"working/<video-id>/short-tmp/short.srt" \
"working/<video-id>/short-tmp/short_subtitled.mp4"
This will produce the video with subtitles burned in and an ending card short-tmp/short_subtitled.mp4。
- Produce a 9:16 vertical version (required, for YouTube Shorts publishing): Use the "subtitle-burned version" as input to convert to vertical; the subtitles follow the foreground and do not need to be burned again:
python skills/short-video-workflow/scripts/make_vertical.py \
"working/<video-id>/short-tmp/short_subtitled.mp4" \
--out "working/<video-id>/short-tmp/short_916.mp4"
The method is blurred background fill: scale the content proportionally to width 1080 and center itwithout cropping(screen demonstrations must not crop out the UI), fill the top and bottom with the same frame enlarged and blurred as the background, output 1080×1920. The script will automatically verify the resolution.
Step 7: Give the short video 3 titles and wait for the user to choose
The short video title is not necessarily the same as the long video title; it is usually more sensational and shorter.
Based on the above content, generate 3 candidates and write them to working/<video-id>/short-titles.md, then stop and wait for the user to choose (not 10; a short video doesn't need that many).
Step 8: After the user selects the short video title — create a folder
- Title cleanup (remove
?!:/\?!:/\\<>|"*) - Create
output/<短片標題> [Claude] (Short)/(Claude) oroutput/<短片標題> [Codex] (Short)/(Codex) - Move and rename files to the output folder:
- Rename
short_with_card.mp4to<短片標題>.mp4(16:9 clean version) - Rename
short_subtitled.mp4to<短片標題>_字幕版.mp4(16:9 subtitle-burned version) - Rename
short_916.mp4Rename to<短片標題>_直式9x16.mp4(For YouTube Shorts publishing) - Rename
short.srtto<短片標題>.srt - Rename
short.txtto<短片標題>.txt
- Rename
Step 9: Generate cover (follow the long-form cover SOP)
Pre-cover SOP (all required):
Read assets/style/reference-thumbnails.pngRead assets/style/cover-style.mdRead assets/persona/三師爸人物形象照.png- Decide the main color based on the video's main subject: Claude=orange / Codex=blue / both=orange+blue
Additional requirements for short-form covers:
- Use theshortest and most sensationalversion for the title (the cover title can be more concise than the YouTube title)
- Add a small "SHORT" or "精華" sticker for identification (optional)
- 16:9 size, same template as long-form
How to call:
- Claude Code:
python skills/cover-image/draw.py "<prompt>" --edit "assets/persona/三師爸人物形象照.png" --size 1536x1024 --quality low --name cover --outdir "output/<標題> [Claude] (Short)/" - Codex: use the built-in Image2, do not call draw.py
Step 10: Write metadata (short-form version)
metadata.md structureis different from long-form(shorts have their own way):
- YouTube short description(≤ 150 characters, the first 50 characters are the most critical)
- Hashtag strip: first 3 →
#Shorts #<頻道主題>must be included - Social posts(one version each for IG Reels and TikTok, shorter and more provocative than long-form)
- SEO keywords:
- Primary keywords (3–5)
- Long-tail (3–5)
- YouTube tags field (copy directly): separated by half-width commas,add at the end
Shorts,短影片two required tags
- Pre-publish checklist: title ≤ 40 characters, cover, subtitles,
#Shortsin the title or description, recommended publishing time slot
Step 11: Self-check checklist
After running, confirm item by item:
- The folder name ends with
[Claude] (Short)or[Codex] (Short)suffix - Video duration ≤ 120 seconds (confirm with ffprobe)
- Hook subtitle appears within the first 5 seconds
- All 7 files are present (including
_直式9x16.mp4) - Vertical version resolution 1080×1920 (make_vertical.py will automatically verify)
- cover.png main color matches the AI subject (orange / blue)
- metadata.md includes
#Shortstags - HANDOFF.md has been updated with this short's status
Step 12: Update HANDOFF.md
Record:
- Short title
- Source long-form video-id
- Timecode combination
- Hook strategy used (A/B/C or user-defined)
- Output path
Override mode: user directly provides timecodes or description
The user can specify directly before step 2, for example:
- "Use the two segments 00:00:05–00:00:15 and 00:01:20–00:02:00" → skip to step 5
- "I want to cut the two segments 'how Claude operates + result showcase'" → you, the AI, find the corresponding timecodes from the SRT, confirm with the user, then skip to step 5
Pitfalls
- Timecodes must align with
cut.mp4notraw/: the timecodes for the original file do not match the subtitles. - Re-encoding vs stream copy: short-form cut points are usually not at keyframes, so use stream copy (
-c copy) a black screen may appear; this Skill always re-encodes. - Audio fade in/out:
clip_cut.pyBy default no fade is added; if you want a 0.05s soft cut, you can add it in step 5--audio-fade 0.05。 - Don't exceed 8 segments: too many fragments make the viewing experience incoherent; 3–6 segments for 2 minutes is the most comfortable.
- Don't cut in the middle of a sentence: when choosing time codes, align to subtitle segment boundaries, otherwise it will "cut halfway through".
- YouTube Shorts rules: videos ≤ 60 seconds automatically enter the Shorts feed, while 60–180 seconds are "short videos" but do not necessarily enter the Shorts feed. This Skill defaults to ≤ 120 seconds as more universal.
- 9:16 vertical is a required output(from 2026-07): always use
make_vertical.pyblurred background fill,do not use crop—cropping the left and right sides of screen-demo videos loses UI information. Use the version with burned-in subtitles as input; the subtitles automatically scale with the foreground, so no need to re-burn them. - The vertical version shares the 16:9 end card: the end card was already added before converting to vertical, so the vertical version comes with the end card; no need to make a separate vertical end card.
File structure
skills/short-video-workflow/
├── SKILL.md
└── scripts/
├── clip_cut.py # ffmpeg 切片+組片+SRT 重編
├── add_end_card.py # 結尾添加 3 秒「詳細影片請看留言」字卡
├── burn_subtitles.py # 將 srt 字幕燒錄進 mp4 影片
└── make_vertical.py # 16:9 → 9:16 直式(模糊背景填充,Shorts 發布用)
Relationship with other Skills
- Depends on:
smart-cut+audio-to-srt(cut.mp4 + srt already produced) - Shared:
cover-imageSOP、assets/style/cover-style.md、assets/persona/ - Parallel: with
claude-youtube-video-workflow/codex-youtube-video-workflowthey are siblings