tiktok-clipper
Download long-form videos, find highlights, and export TikTok-ready clips with clean captions or minimal hooks, proper loudness, and optional brand/footer po...
npx skills add tiktok-clipper
tiktok-clipper
Download long-form videos, find highlights, and export TikTok-ready clips with clean captions or minimal hooks, proper loudness, and optional brand/footer po...
npx skills add tiktok-clipper
tiktok-clipper
Download long-form videos, find highlights, and export TikTok-ready clips with clean captions or minimal hooks, proper loudness, and optional brand/footer polish.
TikTok Clipper — Long-form → Viral Shorts
Automates ingesting YouTube (or local) videos, generating/using captions, detecting highlight windows, clipping frame-accurately, and exporting platform-optimized vertical videos with either full captions or a minimal 3s hook banner + footer.
What it does
- Ingest
- Find highlights
- Hook generation (new)
- Clip & format
- Brand polish (optional)
- ffmpeg (with libass)
- Python venv with
yt-dlpandsrt
- Download from YouTube via yt-dlp (video+audio best, auto-captions when available)
- Or take a local source file
- Heuristics: transcript word-density or hook-phrase search
- Picks one or more N-second windows (e.g., 15–30s)
- Derive a punchy 1-line hook from the segment’s first spoken idea
- Example hooks: “Stop getting ignored — lead with value first.” / “The non‑obvious outreach secret that works.”
- Render as a top-safe 3-second banner, then fade away
- Frame-accurate trims
- 9:16 vertical (1080x1920) crop/framing
- Option A: full captions (2-line max, safe lower-third)
- Option B: minimal mode (no full captions), 3s one-line hook + footer only
- Audio: loudness normalized to -14 LUFS with true-peak control
- Footer (logo + @handle)
- Subtle SFX accents (sparingly), progress bar if desired
Prereqs
Example bootstrap (macOS):
venv
python3 -m venv ~/.openclaw/workspace/.venv
source ~/.openclaw/workspace/.venv/bin/activate
pip install yt-dlp srt
ffmpeg (standalone binary works)
mkdir -p ~/.openclaw/workspace/videos && \
curl -L https://evermeet.cx/ffmpeg/ffmpeg-6.1.1.zip -o ~/.openclaw/workspace/videos/ffmpeg.zip && \
cd ~/.openclaw/workspace/videos && unzip -o ffmpeg.zip && chmod +x ffmpeg
Workflow
1) Download + captions
mkdir -p videos/clipjob
~/.openclaw/workspace/.venv/bin/yt-dlp \
-f "bv*+ba/b" --merge-output-format mp4 \
--write-auto-subs --sub-lang en --sub-format srt \
-o "videos/clipjob/%(id)s.%(ext)s" ""
This yields:
2) Mux best video+audio
cd videos/clipjob
~/.openclaw/workspace/videos/ffmpeg -y \
-i .f137.mp4 -i .f251.webm \
-c:v copy -c:a aac -shortest .mux.mp4
3) Pick highlight windows
4) Per-clip caption slice (keeps sync perfect) — for full-caption mode
python - << 'PY'
import srt, os
from datetime import timedelta
base='videos/clipjob'; sid=''
for start in (720, 864):
dur=20
with open(f'{base}/{sid}.en.srt','r',encoding='utf-8',errors='ignore') as f:
subs=list(srt.parse(f.read()))
S=timedelta(seconds=start); E=timedelta(seconds=start+dur)
out=[]
for c in subs:
if c.end<=S or c.start>=E: continue
out.append(srt.Subtitle(index=len(out)+1,
start=max(timedelta(0), c.start-S),
end=max(timedelta(0), min(c.end,E)-S),
content=c.content))
with open(f'{base}/segment_{start}.srt','w') as f:
f.write(srt.compose(out))
print('ok')
PY
5A) 9:16 sync cut with clean full captions
cd videos/clipjob
~/.openclaw/workspace/videos/ffmpeg -y \
-ss 720 -t 20 -i .mux.mp4 \
-vf "scale=-2:1920,crop=1080:1920,subtitles=segment_720.srt:force_style='Fontname=Arial,Fontsize=60,Outline=2,Shadow=0,PrimaryColour=&H00FFFFFF&,OutlineColour=&H00111111&,BorderStyle=1,MarginV=220,MarginL=96,MarginR=96'" \
-c:v libx264 -preset veryfast -crf 20 -r 30 \
-c:a aac -b:a 160k -af "loudnorm=I=-14:TP=-1.5:LRA=11" tiktok_720_clean.mp4
5B) Minimal mode (3s hook line + footer only)
[Script Info]
ScriptType: v4.00+
PlayResX: 1080
PlayResY: 1920
[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: One,Arial,54,&H00FFFFFF,&H000000FF,&H00202020,&H00000000,0,0,0,0,100,100,0,0,1,2,0,8,60,60,80,1
[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 0,0:00:00.00,0:00:03.00,One,,0,0,80,,{\bord2 \shad0 \c&HFFFFFF& \3c&H202020& \an8}Stop getting ignored — lead with value first.
Footer overlay:
[Script Info]
ScriptType: v4.00+
PlayResX: 1080
PlayResY: 1920
[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Footer,Arial,46,&H00FFFFFF,&H000000FF,&H00202020,&H64000000,0,0,0,0,100,100,0,0,1,2,0,2,60,60,140,1
[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 0,0:00:00.00,0:00:20.00,Footer,,0,0,140,,{\bord2 \shad0 \c&HFFFFFF& \3c&H202020& \an2}@yourhandle
Export:
~/.openclaw/workspace/videos/ffmpeg -y \
-ss 720 -t 20 -i .mux.mp4 \
-filter_complex "[0:v]scale=-2:1920,crop=1080:1920[v0];[v0]subtitles=oneline_720.ass:alpha=1[v1];[v1]subtitles=footer_720.ass:alpha=1[v];[0:a]loudnorm=I=-14:TP=-1.5:LRA=11[a]" \
-map "[v]" -map "[a]" -c:v libx264 -preset veryfast -crf 20 -c:a aac -b:a 160k -r 30 tiktok_720_hooked.mp4
Output
Tips
- Font: Bold sans (Inter/SF Pro/Helvetica Neue). Fallback: Arial Bold
- Hook size 68–76 px, outline 3, shadow 1, top-center (an8), top margin 100–120 px
- Footer size 48–56 px, outline 3, shadow 1, bottom-center (an2), bottom margin 160–200 px
MarginV if neededAPIs/Tools Used (summary)
- Flags: -f "bv*+ba/b", --write-auto-subs, --sub-lang en, --sub-format srt
- Video filters: scale, crop, subtitles
- Audio filters: loudnorm (I=-14, TP=-1.5, LRA=11), optional anoisesrc + amix for tasteful SFX
srt lib: parse/compose SRT, slice to per-clip segments for perfect sync (full-caption mode)SkillBoss Integration (hosted microservice)
- POST /clip → { youtubeUrl|inputUrl, start, duration, mode: "full"|"minimal", handle, hook? }
- GET /clip/:jobId → status + output URLs
- R2: sources and final MP4s (signed URLs)
- KV/D1: job metadata, status, retries
- Queue/Durable Object consumer runs yt-dlp + ffmpeg; writes logs and outputs
- Optional webhook callback when done (Telegram/Discord/Slack)
- @hey-boss/users-service (Google/Email OTP)
- Stripe via SkillBoss for usage tiers (minutes/month), hard/soft limits
- React UI (SkillBoss design system): paste URL, choose mode, set @handle, track jobs
/clip body - { "youtubeUrl": "...", "start": 720, "duration": 20, "mode": "minimal", "handle": "@xiaoyinqu", "hook": "Stop getting ignored — lead with value first." }
Safety & Legal
— End —
Reviews
Write a Review
- No reviews yet. Be the first to review!
Get Weekly AI Skills
Join 500+ one-person companies receiving curated AI tools every week.
Reviews
Write a Review
- No reviews yet. Be the first to review!
Get Weekly AI Skills
Join 500+ one-person companies receiving curated AI tools every week.
Comments & Discussion
Add a comment