← 返回
内容创作 中文

Skill Video Caption Overlay

Render TikTok-style animated pill captions onto short-form videos using MoviePy + PIL. Takes a base MP4, a captions JSON, and optional background audio — out...
利用 MoviePy 和 PIL 为短视频生成 TikTok 风格的动态药丸字幕。支持输入 MP4 视频、字幕 JSON 及可选背景音频。
zero2ai-hub
内容创作 clawhub v1.0.0 1 版本 100000 Key: 无需
★ 0
Stars
📥 800
下载
💾 68
安装
1
版本
#latest

概述

Video Caption Overlay

Animated pill-style caption overlays for short-form video. No Premiere, no CapCut — pure Python.

Usage

uv run --with moviepy --with pillow scripts/overlay.py \
  --video base.mp4 \
  --output final.mp4 \
  --captions scripts/example_captions.json \
  --audio music.mp3 \
  --audio-start 8 \
  --audio-vol 0.5

No --audio if you want to keep the original video audio.

Custom fonts

--font-black /path/to/Montserrat-Black.ttf \
--font-bold  /path/to/Montserrat-Bold.ttf

Falls back to Montserrat from ~/.local/share/fonts/ if not specified.

captions.json format

Array of phases — each phase is a time window with one or more pill lines stacked vertically.

[
  {
    "start": 0,
    "end": 3.2,
    "y_frac": 0.06,
    "lines": [
      {
        "text": "POV:",
        "size": 28,
        "bold": true,
        "bg": [0, 195, 255],
        "fg": [0, 0, 0],
        "bg_opacity": 0.9,
        "px": 20, "py": 9, "r": 12
      },
      {
        "text": "drink more water",
        "size": 50,
        "bg": [255, 255, 255],
        "fg": [0, 0, 0]
      }
    ]
  }
]
FieldTypeDefaultDescription
------------
startfloatrequiredPhase start time (seconds)
endfloatrequiredPhase end time (seconds)
y_fracfloat0.06Vertical position as fraction of video height
lines[].textstringrequiredCaption text
lines[].sizeint50Font size (px)
lines[].boldboolfalseUse bold font (vs black/heavy)
lines[].bg[R,G,B][255,255,255]Pill background color
lines[].fg[R,G,B][0,0,0]Text color
lines[].bg_opacityfloat0.93Pill background opacity (0–1)
lines[].pxint26Horizontal padding
lines[].pyint13Vertical padding
lines[].rint18Border radius

PIL textbbox fix

PIL's textbbox((0,0), text, font) returns (x0, y0, x1, y1) where y0 is a non-zero offset (typically 7–15px depending on font size). Drawing text at (x, y) without compensating for this offset causes text to appear below the pill's visual center.

Fix implemented in pill():

bb    = draw.textbbox((0, 0), text, font=font)
x_off, y_off = bb[0], bb[1]
vis_w = bb[2] - bb[0]   # actual visual width
vis_h = bb[3] - bb[1]   # actual visual height

# Compensate offsets when drawing text
tx = cx - vis_w // 2 - x_off
ty = y - y_off
draw.text((tx, ty), text, font=font, fill=fg)

Emoji note

NotoColorEmoji.ttf fails with PIL at arbitrary sizes (bitmap font with limited supported sizes). Use text alternatives ("Free delivery" instead of "Free delivery 🚚") for reliable rendering.

Example output

See scripts/example_captions.json for the full 3-phase TikTok ad structure:

  • Phase 1 (0–3.2s): Hook — top-screen pill stack
  • Phase 2 (2.8–5.8s): Product claim — overlapping fade
  • Phase 3 (5.3–8.0s): CTA — bottom-screen price + delivery + bio link

版本历史

共 1 个版本

  • v1.0.0 当前
    2026-03-30 00:36 安全 安全

安全检测

腾讯云安全 (Keen)

安全,无风险
查看报告

腾讯云安全 (Sanbu)

安全,无风险
查看报告

🔗 相关推荐

productivity

Trading Journal

zero2ai-hub
记录每笔交易的完整背景(逻辑、入场、出场、盈亏、情绪、教训),生成周度与月度业绩报告,并分析盈亏模式...
★ 2 📥 2,952
content-creation

Baidu Wenku AIPPT

ide-rea
使用百度文库 AI 智能生成 PPT,自动根据内容选择模板。
★ 66 📥 46,215
content-creation

AdMapix

fly0pants
广告情报与应用数据分析助手,支持搜索广告素材、分析应用排名、下载量、收入及市场洞察,用于广告素材和竞品分析。
★ 295 📥 136,509