mcpField
F
ffmpeg-kinetic-captions

ffmpeg-kinetic-captions

github.com/josiahsiegel创意与媒体59154 次安装19 周前更新
代码仓库

关于 ffmpeg-kinetic-captions

面向使用 FFmpeg 制作动态字幕的创作者,汇总 ASS 字幕动画与时间设置示例。内容涵盖逐词高亮、弹跳、抖动和文字显现效果。

主要功能

  1. 01ASS 字幕动画示例
  2. 02逐词卡拉 OK 高亮
  3. 03弹跳与缩放效果
  4. 04抖动与文字显现
  5. 05动画时长与平台参考

适用场景

  1. 01为短视频制作逐词高亮字幕
  2. 02给重点词添加弹跳或抖动
  3. 03制作逐字或逐词显现字幕

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/josiahsiegel/claude-plugin-marketplace --skill ffmpeg-kinetic-captions

安装后在 Claude Code 中输入/ffmpeg-kinetic-captions确认已加载。

附带文件references/complete-generator.md

详细介绍

关键指南

Windows 文件路径要求

强制要求:在 Windows 上始终使用反斜杠表示文件路径

在 Windows 上使用 Edit 或 Write 工具时,文件路径必须使用反斜杠(\),不得使用正斜杠(/)。

文档指南

除非用户明确要求,否则绝不要创建新的文档文件。


动态字幕主指南(2025-2026)

快速参考 - 动态效果

效果ASS 代码时长使用场景
单词放大{\fscx80\fscy80\t(0,200,\fscx120\fscy120)\t(200,400,\fscx100\fscy100)}400ms卡拉 OK 高亮
弹跳弹出{\fscx50\fscy50\t(0,100,\fscx115\fscy115)\t(100,200,\fscx100\fscy100)}200ms单词出现
弹性效果{\fscx40\fscy40\t(0,100,\fscx130\fscy130)\t(100,200,\fscx90\fscy90)\t(200,350,\fscx100\fscy100)}350ms高能量
弹簧弹跳{\move(540,1100,540,960,0,300)\t(0,150,\fscx110\fscy110)\t(150,300,\fscx100\fscy100)}300ms从下方进入
震动{\t(0,50,\pos(545,960))\t(50,100,\pos(535,960))\t(100,150,\pos(540,960))}150ms强调冲击
卡拉 OK 填充{\kf100}Word1000ms渐进式高亮
卡拉 OK + 放大{\k80\t(0,200,\fscx115\fscy115)\t(200,400,\fscx100\fscy100)}800ms高亮 + 缩放

动态字幕为何重要

  • 85% 的社交视频是在静音状态下观看的
  • 逐词动画可将留存率提高 25-40%
  • 缩放/弹跳效果传达“这个词现在很重要”
  • 卡拉 OK 高亮通过音频引导观众掌握节奏
  • TikTok/Shorts/Reels 上普遍采用动态排版

第 1 节:卡拉 OK 与单词放大效果

单词放大高亮是最受欢迎的动态效果——单词高亮时会放大,然后恢复正常大小。

基础单词放大卡拉 OK

[Script Info]
ScriptType: v4.00+
PlayResX: 1080
PlayResY: 1920
WrapStyle: 0

[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: KaraokeGrow,Arial Black,80,&H00FFFFFF,&H0000FFFF,&H00000000,&H40000000,1,0,0,0,100,100,0,0,1,5,0,2,10,10,280,1

[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
; Word grows when karaoke highlight reaches it
Dialogue: 0,0:00:01.00,0:00:05.00,KaraokeGrow,,0,0,0,,{\k80\t(0,200,\fscx115\fscy115)\t(200,400,\fscx100\fscy100)}This {\k60\t(0,150,\fscx115\fscy115)\t(150,300,\fscx100\fscy100)}is {\k100\t(0,250,\fscx120\fscy120)\t(250,500,\fscx100\fscy100)}AMAZING
动画标签说明
{\k80\t(0,200,\fscx115\fscy115)\t(200,400,\fscx100\fscy100)}Word

Breaking it down:
- \k80 = Karaoke duration (80 centiseconds = 0.8 seconds)
- \t(0,200,...) = Animation from 0-200ms
- \fscx115\fscy115 = Scale to 115% (grow)
- \t(200,400,...) = Animation from 200-400ms
- \fscx100\fscy100 = Scale back to 100% (shrink)
关键:时间单位不同!
标签单位0.5 秒 =
\k百分之一秒\k50
\t()毫秒\t(0,500,...)

高级单词放大模式

模式 1:放大 + 颜色变化

高亮时,单词会放大并变色:

[V4+ Styles]
Style: GrowColor,Arial Black,80,&H00FFFFFF,&H0000FFFF,&H00000000,&H40000000,1,0,0,0,100,100,0,0,1,5,0,2,10,10,280,1
;                                 White     Yellow highlight

[Events]
; Karaoke fill (kf) + grow + color transition
Dialogue: 0,0:00:00.00,0:00:03.00,GrowColor,,0,0,0,,{\kf60\t(0,200,\fscx115\fscy115\c&H00FFFF&)\t(200,400,\fscx100\fscy100)}Check {\kf80\t(0,200,\fscx115\fscy115\c&H00FFFF&)\t(200,400,\fscx100\fscy100)}this {\kf100\t(0,250,\fscx120\fscy120\c&H00FFFF&)\t(250,500,\fscx100\fscy100)}out
模式 2:放大 + 弹跳(超调)

通过弹簧物理超调效果,带来更生动的观感:

; Grows to 120%, bounces back to 95%, settles at 100%
Dialogue: 0,0:00:00.00,0:00:03.00,Style,,0,0,0,,{\k80\t(0,120,\fscx120\fscy120)\t(120,220,\fscx95\fscy95)\t(220,350,\fscx100\fscy100)}Bouncy
模式 3:放大 + 描边脉冲

高亮期间描边会扩展:

; Border/outline grows with text
Dialogue: 0,0:00:00.00,0:00:02.00,Style,,0,0,0,,{\k100\t(0,200,\fscx115\fscy115\bord8)\t(200,400,\fscx100\fscy100\bord5)}IMPACT

各平台的单词放大时长

平台放大时长缩小时长最大缩放比例动画风格
TikTok100-150ms100-150ms115-120%快速、有力
YouTube Shorts150-200ms150-200ms110-115%流畅、易读
Instagram Reels120-180ms120-180ms115-120%时尚、潮流
TikTok 优化版(快速)
; Quick 200ms total animation
{\k60\t(0,100,\fscx115\fscy115)\t(100,200,\fscx100\fscy100)}Fast
YouTube Shorts 优化版(流畅)
; Smooth 350ms total animation
{\k80\t(0,175,\fscx112\fscy112)\t(175,350,\fscx100\fscy100)}Smooth

第 2 节:CapCut 风格的单词弹出效果

单词弹出效果让每个单词以弹跳的方式出现,由 CapCut 推广开来。

基础单词弹出

[V4+ Styles]
Style: WordPop,Arial Black,84,&H00FFFFFF,&H0000FFFF,&H00000000,&H40000000,1,0,0,0,100,100,0,0,1,6,0,2,10,10,280,1

[Events]
; Each word starts at 50% scale, pops to 115%, settles at 100%
Dialogue: 0,0:00:00.00,0:00:00.50,WordPop,,0,0,0,,{\fscx50\fscy50\t(0,100,\fscx115\fscy115)\t(100,200,\fscx100\fscy100)}This
Dialogue: 0,0:00:00.30,0:00:00.80,WordPop,,0,0,0,,{\fscx50\fscy50\t(0,100,\fscx115\fscy115)\t(100,200,\fscx100\fscy100)}is
Dialogue: 0,0:00:00.50,0:00:01.20,WordPop,,0,0,0,,{\c&H0000FFFF&\fscx50\fscy50\t(0,100,\fscx120\fscy120)\t(100,250,\fscx100\fscy100)}VIRAL
带错开延迟的单词弹出

单词按顺序出现,时间彼此重叠:

单词开始结束与上一个单词的间隔
单词 10.00s0.50s-
单词 20.25s0.75s250ms
单词 30.50s1.00s250ms
单词 40.75s1.25s250ms
弹性单词弹出(多次弹跳)
; More dramatic with multiple oscillations
; 40% → 130% → 90% → 105% → 100%
Dialogue: 0,0:00:00.00,0:00:01.00,Style,,0,0,0,,{\fscx40\fscy40\t(0,100,\fscx130\fscy130)\t(100,200,\fscx90\fscy90)\t(200,350,\fscx105\fscy105)\t(350,500,\fscx100\fscy100)}ELASTIC

带移动效果的单词弹出

从下方弹入
; Word moves up while popping
Dialogue: 0,0:00:00.00,0:00:01.00,Style,,0,0,0,,{\move(540,1100,540,960,0,200)\fscx50\fscy50\t(0,100,\fscx115\fscy115)\t(100,200,\fscx100\fscy100)}BounceUp
从侧面弹入
; Word slides in from right while popping
Dialogue: 0,0:00:00.00,0:00:01.00,Style,,0,0,0,,{\move(1200,960,540,960,0,250)\fscx50\fscy50\t(0,120,\fscx110\fscy110)\t(120,250,\fscx100\fscy100)}SlideIn
带旋转的弹出效果
; Word rotates while appearing
Dialogue: 0,0:00:00.00,0:00:01.00,Style,,0,0,0,,{\frz-15\fscx50\fscy50\t(0,150,\frz0\fscx115\fscy115)\t(150,300,\fscx100\fscy100)}Twist

第 3 节:弹簧物理动画

使用弹簧物理公式实现自然的弹跳效果。

弹簧参数指南

参数低值高值效果
阻尼2-35-8弹跳较少 → 弹跳较多
频率8-10 rad/s15-20 rad/s慢速振荡 → 快速振荡
振幅5-10%15-25%轻微 → 戏剧性
阻尼比解读
  • ζ < 0.5:弹跳感很强,多次振荡
  • ζ = 0.5-0.8:弹跳感适中,振荡 1-2 次
  • ζ = 1.0:临界阻尼(无过冲)
  • ζ > 1.0:过阻尼(反应迟缓)

ASS 中的弹簧弹跳

低阻尼(弹跳感强)
; Multiple oscillations: 120% → 90% → 105% → 98% → 100%
{\fscx80\fscy80\t(0,100,\fscx120\fscy120)\t(100,200,\fscx90\fscy90)\t(200,300,\fscx105\fscy105)\t(300,400,\fscx98\fscy98)\t(400,500,\fscx100\fscy100)}Bouncy
中阻尼(平衡)
; Single overshoot: 115% → 95% → 100%
{\fscx80\fscy80\t(0,120,\fscx115\fscy115)\t(120,250,\fscx95\fscy95)\t(250,400,\fscx100\fscy100)}Balanced
高阻尼(快速稳定)
; Minimal overshoot: 110% → 100%
{\fscx80\fscy80\t(0,150,\fscx110\fscy110)\t(150,300,\fscx100\fscy100)}Quick

位置弹簧(垂直弹跳)

; Word bounces to final position
; Starts 100px below, overshoots 20px above, settles
{\pos(540,1060)\t(0,150,\pos(540,940))\t(150,250,\pos(540,980))\t(250,350,\pos(540,960))}Position Bounce

第 4 节:抖动和震颤效果

通过可控的抖动动画强调冲击效果。

水平抖动

; Shake left-right (±5px) then settle
{\pos(540,960)\t(0,50,\pos(545,960))\t(50,100,\pos(535,960))\t(100,150,\pos(542,960))\t(150,200,\pos(538,960))\t(200,250,\pos(540,960))}SHAKE

衰减冲击抖动

; Strong shake that decays: 10px → 6px → 3px → 0px
{\pos(540,960)\t(0,50,\pos(550,960))\t(50,100,\pos(530,960))\t(100,160,\pos(546,960))\t(160,220,\pos(534,960))\t(220,280,\pos(543,960))\t(280,350,\pos(540,960))}IMPACT

抖动 + 缩放组合

; Word shakes AND scales for maximum impact
{\fscx100\fscy100\pos(540,960)\t(0,50,\fscx120\fscy120\pos(545,960))\t(50,100,\fscx115\fscy115\pos(535,960))\t(100,200,\fscx100\fscy100\pos(540,960))}BOOM

抖动幅度指南

字号最大水平幅度最大垂直幅度说明
64-72px8px6px清晰易读
76-84px12px10px明显
88-96px16px14px戏剧性
100+px20px18px仅用于冲击效果

规则:为保证可读性,抖动幅度应小于字号的 15%。


第 5 节:打字机和显现效果

逐字显现文本。

逐字显现(打字机效果)

每个字符依次出现:

; Manual character timing (50ms per character)
Dialogue: 0,0:00:00.00,0:00:00.05,Style,,0,0,0,,H
Dialogue: 0,0:00:00.05,0:00:00.10,Style,,0,0,0,,He
Dialogue: 0,0:00:00.10,0:00:00.15,Style,,0,0,0,,Hel
Dialogue: 0,0:00:00.15,0:00:00.20,Style,,0,0,0,,Hell
Dialogue: 0,0:00:00.20,0:00:01.00,Style,,0,0,0,,Hello
打字机速度参考
速度毫秒/字符字符/秒感觉
快30-40ms25-33充满活力
正常50-70ms14-20舒适
慢80-120ms8-12戏剧性

逐词显现

比逐字显现更不容易令人厌烦:

Dialogue: 0,0:00:00.00,0:00:00.30,Style,,0,0,0,,{\fad(100,0)}This
Dialogue: 0,0:00:00.30,0:00:00.60,Style,,0,0,0,,{\fad(100,0)}is
Dialogue: 0,0:00:00.60,0:00:00.90,Style,,0,0,0,,{\fad(100,0)}word
Dialogue: 0,0:00:00.90,0:00:01.20,Style,,0,0,0,,{\fad(100,0)}by
Dialogue: 0,0:00:01.20,0:00:02.00,Style,,0,0,0,,{\fad(100,0)}word

带弹出的显现效果

将打字机时序与弹出动画相结合:

; Word appears AND pops
Dialogue: 0,0:00:00.00,0:00:00.50,Style,,0,0,0,,{\fscx50\fscy50\t(0,100,\fscx110\fscy110)\t(100,200,\fscx100\fscy100)}This
Dialogue: 0,0:00:00.25,0:00:00.75,Style,,0,0,0,,{\fscx50\fscy50\t(0,100,\fscx110\fscy110)\t(100,200,\fscx100\fscy100)}is
Dialogue: 0,0:00:00.50,0:00:01.00,Style,,0,0,0,,{\fscx50\fscy50\t(0,100,\fscx110\fscy110)\t(100,200,\fscx100\fscy100)}great

第 6 节:颜色过渡和多色卡拉 OK

渐进式颜色填充(卡拉 OK)

[V4+ Styles]
; Primary = unfilled color, Secondary = filled color
Style: ColorKaraoke,Arial Black,80,&H00FFFFFF,&H0000FFFF,&H00000000,&H40000000,1,0,0,0,100,100,0,0,1,5,0,2,10,10,280,1
;                                   White      Yellow

[Events]
; \kf creates smooth left-to-right color fill
Dialogue: 0,0:00:00.00,0:00:03.00,ColorKaraoke,,0,0,0,,{\kf80}This {\kf60}fills {\kf100}smoothly

多色渐变卡拉 OK

单词在多种颜色之间过渡:

; Yellow → Orange → Red progression
[V4+ Styles]
Style: GradientK,Impact,80,&H0000FFFF,&H000000FF,&H00000000,&H00000000,1,0,0,0,100,100,0,0,1,5,0,2,10,10,280,1

[Events]
; Use \t to add intermediate color during karaoke fill
Dialogue: 0,0:00:00.00,0:00:02.00,GradientK,,0,0,0,,{\kf80\t(0,400,\2c&H0000A5FF&)}Word1 {\kf100\t(0,500,\2c&H0000A5FF&)}Word2
;                                                                  Orange midpoint

高亮时闪色

; Word flashes bright color then returns
Dialogue: 0,0:00:00.00,0:00:02.00,Style,,0,0,0,,{\k80\c&HFFFFFF&\t(0,100,\c&H00FFFF&)\t(100,400,\c&HFFFFFF&)}Flash

第 7 节:平台专属字幕样式

TikTok 爆款风格

[V4+ Styles]
Style: TikTokViral,Arial Black,88,&H00FFFFFF,&H0000FFFF,&H00000000,&H40000000,1,0,0,0,100,100,0,0,1,6,0,2,10,10,320,1

[Events]
; Fast pop, high energy
Dialogue: 0,0:00:00.00,0:00:00.40,TikTokViral,,0,0,0,,{\fscx50\fscy50\t(0,80,\fscx118\fscy118)\t(80,160,\fscx100\fscy100)}THIS
Dialogue: 0,0:00:00.20,0:00:00.60,TikTokViral,,0,0,0,,{\fscx50\fscy50\t(0,80,\fscx118\fscy118)\t(80,160,\fscx100\fscy100)}IS
Dialogue: 0,0:00:00.40,0:00:01.00,TikTokViral,,0,0,0,,{\c&H00FFFF&\fscx50\fscy50\t(0,100,\fscx125\fscy125)\t(100,200,\fscx100\fscy100)}VIRAL

TikTok 参数:

  • 字号:84-96px
  • 动画:总时长 160-200ms
  • 弹出缩放:115-125%
  • 单词延迟:150-250ms
  • 屏幕上最多显示 3-5 个单词

YouTube Shorts 专业风格

[V4+ Styles]
Style: ShortsPro,Montserrat,76,&H00FFFFFF,&H00FFFFFF,&H00333333,&H80000000,1,0,0,0,100,100,0,0,1,4,2,2,10,10,300,1

[Events]
; Smoother, more professional
Dialogue: 0,0:00:00.00,0:00:00.60,ShortsPro,,0,0,0,,{\fscx80\fscy80\t(0,150,\fscx108\fscy108)\t(150,300,\fscx100\fscy100)}This
Dialogue: 0,0:00:00.30,0:00:00.90,ShortsPro,,0,0,0,,{\fscx80\fscy80\t(0,150,\fscx108\fscy108)\t(150,300,\fscx100\fscy100)}is
Dialogue: 0,0:00:00.60,0:00:01.40,ShortsPro,,0,0,0,,{\fscx80\fscy80\t(0,180,\fscx112\fscy112)\t(180,350,\fscx100\fscy100)}professional

YouTube Shorts 参数:

  • 字号:72-84px
  • 动画:总时长 250-400ms
  • 弹出缩放:108-115%
  • 单词延迟:250-350ms
  • 屏幕上最多显示 4-6 个单词

Instagram Reels 潮流风格

[V4+ Styles]
Style: ReelsTrend,Impact,82,&H00FFFFFF,&H00FF00FF,&H00000000,&H00000000,1,0,0,0,100,100,2,0,1,5,0,2,10,10,280,1

[Events]
; Stylish with slight rotation
Dialogue: 0,0:00:00.00,0:00:00.50,ReelsTrend,,0,0,0,,{\frz-5\fscx50\fscy50\t(0,120,\frz0\fscx115\fscy115)\t(120,250,\fscx100\fscy100)}Trendy
Dialogue: 0,0:00:00.25,0:00:00.75,ReelsTrend,,0,0,0,,{\frz5\fscx50\fscy50\t(0,120,\frz0\fscx115\fscy115)\t(120,250,\fscx100\fscy100)}Caption
Dialogue: 0,0:00:00.50,0:00:01.20,ReelsTrend,,0,0,0,,{\c&H00FF00FF&\fscx50\fscy50\t(0,150,\fscx120\fscy120)\t(150,300,\fscx100\fscy100)}Style

第 8 节:用于生成动感字幕的 Python 脚本

完整的 Python 动感字幕生成器可将逐词转录文本转换为动画 ASS 字幕文件(结合上文所有逐词放大、逐词弹出、弹簧弹跳、抖动、显现和卡拉 OK 模式),位于 references/complete-generator.md。如果你需要可直接运行的脚本,而不是手动构建各效果的滤镜图,请加载该参考文件。

脉冲/呼吸效果

# Text pulses 72 ± 8 pixels at ~1.5 Hz
ffmpeg -i input.mp4 \
  -vf "drawtext=text='SUBSCRIBE':fontsize='72+8*sin(t*9.42)':fontcolor=yellow:x=(w-tw)/2:y=h-150:borderw=3:bordercolor=black" \
  output.mp4
# 9.42 rad/s = 1.5 Hz (1.5 * 2π = 9.42)

弹跳式文本入场

# Text bounces from below (spring physics)
ffmpeg -i input.mp4 \
  -vf "drawtext=text='BOUNCE':fontsize=80:fontcolor=white:x=(w-tw)/2:y='(h-th)/2-30*exp(-t*3)*sin(t*15)':borderw=3:bordercolor=black:enable='gte(t,1)'" \
  output.mp4

弹出缩放(字号动画)

# Text pops from small to normal
ffmpeg -i input.mp4 \
  -vf "drawtext=text='POP':fontsize='if(lt(t,0.3),40+40*t/0.3,80)':fontcolor=white:x=(w-tw)/2:y=(h-th)/2:enable='gte(t,0.5)'" \
  output.mp4

冲击时抖动

# Text shakes with decaying amplitude
ffmpeg -i input.mp4 \
  -vf "drawtext=text='IMPACT':fontsize=100:fontcolor=white:x='(w-tw)/2+15*exp(-t*4)*sin(t*50)':y='(h-th)/2+10*exp(-t*4)*cos(t*47)':enable='gte(t,2)'" \
  output.mp4

逐词出现

# Multiple drawtext filters for word-by-word reveal
ffmpeg -f lavfi -i "color=c=black:s=1080x1920:d=5" \
  -vf "\
    drawtext=text='THIS':fontsize=80:fontcolor=white:x=(w-tw)/2:y=h/2-80:alpha='if(lt(t,0.5),t*2,1)':enable='gte(t,0.5)',\
    drawtext=text='IS':fontsize=80:fontcolor=white:x=(w-tw)/2:y=h/2:alpha='if(lt(t-1,0.5),(t-1)*2,1)':enable='gte(t,1)',\
    drawtext=text='KINETIC':fontsize=80:fontcolor=yellow:x=(w-tw)/2:y=h/2+80:alpha='if(lt(t-1.5,0.5),(t-1.5)*2,1)':enable='gte(t,1.5)'" \
  kinetic_reveal.mp4

第 10 节:最佳实践和故障排除

动感字幕最佳实践

  1. 不要过度添加动画:并非每个单词都需要最强效果
  2. 强调关键词:对重要单词使用更大的缩放幅度/更长的持续时间
  3. 匹配节奏:语速快就用快速动画,语速慢就用平滑动画
  4. 保持平台风格一致:使用适合平台的样式
  5. 测试可读性:动画不应影响理解

强调层级

单词类型动画缩放持续时间
填充词(a、the、is)轻微弹出105-110%150-200ms
普通单词标准弹出110-115%200-250ms
关键词强化弹出115-120%250-350ms
强调词弹性/抖动120-130%300-400ms

常见问题和解决方案

时序不匹配

问题:动画与音频时序不匹配 解决方案:使用 Whisper 提供的逐词时间戳,而非句子级时间戳

动画抖动

问题:文本显示时断时续
解决方案:确保动画时长是帧时长的倍数

  • 30fps:使用 33ms、67ms、100ms、133ms 等
  • 60fps:使用 17ms、33ms、50ms、67ms 等
文本过于繁杂

问题:动画分散了对内容的注意力
解决方案:减小缩放幅度(115% → 108%),简化效果

移动设备上的可读性差

问题:手机上的文本难以阅读
解决方案:

  • 增大字号(1080x1920 分辨率下至少为 80px)
  • 增加描边/边框宽度(4-6px)
  • 保留安全边距(距边缘 50px)

来源

本技能通过以下研究得到增强:


相关技能

  • ffmpeg-karaoke-animated-text - 卡拉 OK 基础知识
  • viral-video-animated-captions - CapCut 风格字幕
  • ffmpeg-animation-timing-reference - 时间公式
  • ffmpeg-captions-subtitles - 字幕基础知识
  • viral-video-platform-specs - 平台要求

评论

支持 Markdown