Install
openclaw skills install manim-animation-cnCreate mathematical animations with synchronized voiceover narration and subtitles using Manim Community and manim-voiceover. Use when users want to create animated videos with narration, math animations with voice, educational videos with subtitles, or any request involving Manim scene generation with TTS voiceover. Trigger phrases include: manim animation, math animation, animated video with voice, 数学动画, 动画配音, 动画字幕, manim voiceover, create animation video, or any request to generate narrated mathematical/educational animation videos.
openclaw skills install manim-animation-cnAuthor: ericksun(孙自翔)
本技能使用 Manim Community 生成数学/教育动画,并通过 manim-voiceover 插件集成 TTS 语音旁白和同步字幕。所有处理均在本地运行,无需付费 API。
核心能力:
TTS 引擎(优先 gTTS):
首次使用前,运行环境检查脚本确认所有依赖已就绪:
python3 {SKILL_DIR}/scripts/check_environment.py
该脚本检查:
manim 命令)pip install manimlibx264 编码器渲染视频,字幕烧录需要 libass
brew install ffmpeg(默认包含 x264 和 libass)conda install x264 -c conda-forge(⚠️ conda 的 ffmpeg 默认不含 libx264)sudo apt install ffmpeg libx264-dev libass-dev# Core
pip install manim
# Voiceover + TTS
pip install "manim-voiceover[gtts]"
pip install "manim-voiceover[pyttsx3]")pip install manim "manim-voiceover[gtts]"
# macOS (Homebrew) — 推荐,自带 libx264 + libass
brew install ffmpeg
# macOS (Conda) — 需额外安装 x264,否则 Manim 渲染会报错 UnknownCodecError: libx264
conda install x264 -c conda-forge
# 验证 ffmpeg 支持 libx264 和 libass
ffmpeg -codecs 2>&1 | grep libx264 # 应显示 encoders: libx264
ffmpeg -filters 2>&1 | grep subtitles # 应显示 subtitles filter
用户描述需求后,使用流水线脚本一键完成:
python3 {SKILL_DIR}/scripts/run_pipeline.py \
--scene_file <场景文件.py> \
--scene_name <SceneName> \
--quality high \
--burn_subtitles
常用选项:
| 选项 | 默认值 | 说明 |
|---|---|---|
--scene_file | 必需 | Manim 场景 Python 文件 |
--scene_name | 必需 | 场景类名 |
--quality | high | 渲染质量:low/medium/high/production |
--burn_subtitles | False | 是否用 ffmpeg 烧录 SRT 字幕 |
--speed | 1.35 | 播放倍速(如 1.35 表示加速到 1.35 倍,设为 1.0 则不加速) |
--preview | False | 渲染后自动打开预览 |
--output_dir | ./output | 输出目录 |
根据用户描述,生成 Manim 场景 Python 文件。场景代码需遵循以下模式:
无配音模式(纯动画):
from manim import *
class MyScene(Scene):
def construct(self):
title = Text("标题", font_size=48, color=BLUE)
self.play(Write(title))
self.wait(1)
配音模式(动画 + 语音 + 字幕):
from manim import *
from manim_voiceover import VoiceoverScene
from manim_voiceover.services.gtts import GTTSService
class MyScene(VoiceoverScene):
def _make_subtitle(self, text_str):
"""Create subtitle with dark background at bottom of screen."""
sub = Text(text_str, font_size=22, color=WHITE, weight=BOLD)
# Prevent subtitle from overflowing left/right edges
max_width = config.frame_width - 1.0 # 0.5 margin each side
if sub.width > max_width:
sub.scale_to_fit_width(max_width)
sub.to_edge(DOWN, buff=0.4)
bg = BackgroundRectangle(sub, color=BLACK, fill_opacity=0.6, buff=0.15)
return VGroup(bg, sub)
def construct(self):
self.set_speech_service(GTTSService(lang="zh"))
sub_text = "欢迎来到演示"
with self.voiceover(text=sub_text) as tracker:
sub = self._make_subtitle(sub_text)
title = Text("演示", font_size=48)
self.play(Write(title), FadeIn(sub), run_time=tracker.duration)
self.play(FadeOut(sub))
self.wait(0.3)
关键模式 — voiceover 上下文管理器:
with self.voiceover(text="语音文本") as tracker:
# tracker.duration = TTS 语音时长(秒)
# 在此块内的动画会与语音自动同步
self.play(SomeAnimation(), run_time=tracker.duration)
with self.voiceover(text=...) as tracker 做了三件事:
tracker.duration 让动画与语音同步字幕最佳实践:
_make_subtitle() 辅助函数,在屏幕底部显示带暗背景的白色粗体文字_make_subtitle() 会自动检测字幕宽度,超出画面时等比缩放(scale_to_fit_width),使用 font_size=22 以适配长文本self.play() 中就 FadeIn(sub),确保字幕与声音同步出现,不要延后⚠️ 避免双字幕: 如果场景代码中已使用 _make_subtitle() 渲染了画面内字幕,则 不要 再用 --burn_subtitles 烧录 SRT 字幕,否则画面上会出现两层重叠的字幕。两种字幕方案只能选其一:
_make_subtitle() 渲染字幕,不烧录 SRT--burn_subtitles 烧录 SRT在场景文件同目录创建 manim.cfg:
[CLI]
quality = high_quality
preview = False
[ffmpeg]
video_codec = h264
质量对照表:
| 质量 | 标志 | 分辨率 | FPS | manim.cfg 值 |
|---|---|---|---|---|
| Low | -ql | 480p | 15 | low_quality |
| Medium | -qm | 720p | 30 | medium_quality |
| High | -qh | 1080p | 60 | high_quality |
| Production | -qp | 2160p | 60 | production_quality |
manim render <scene_file.py> <SceneName>
输出路径模式:media/videos/<file>/<resolution>/<SceneName>.mp4
manim-voiceover 会自动在视频同目录生成 .srt 字幕文件。使用 ffmpeg 烧录:
ffmpeg -y -i <video.mp4> \
-vf "subtitles=<subtitle.srt>:force_style='FontSize=22,PrimaryColour=&H00FFFFFF,OutlineColour=&H00000000,Outline=2,BackColour=&H80000000,BorderStyle=4,MarginV=30'" \
-c:a copy \
<output_subtitled.mp4>
⚠️ 双字幕陷阱:如果场景 Python 代码中已经用 _make_subtitle() 渲染了画面内字幕,就 不要 再烧录 SRT 字幕,否则会出现两层重叠字幕。
注意:ffmpeg 需要 libass 支持。macOS 用 brew install ffmpeg 通常已包含。Conda 环境需额外安装 conda install x264 -c conda-forge。
使用 ffmpeg 对视频进行倍速处理,默认加速到 1.35 倍:
SPEED=1.35
ffmpeg -y -i <input.mp4> \
-filter_complex "[0:v]setpts=PTS/${SPEED}[v];[0:a]atempo=${SPEED}[a]" \
-map "[v]" -map "[a]" \
<output_fast.mp4>
注意:加速应在最终输出步骤执行。如果场景代码已有画面内字幕(_make_subtitle),加速输入应使用原始视频(非 SRT 烧录版),避免双字幕。run_pipeline.py 的 --speed 参数已自动处理此逻辑。
Write(text) — 书写文字Create(mobject) — 绘制形状FadeIn(mobject) / FadeOut(mobject) — 淡入淡出DrawBorderThenFill(mobject) — 先画边框再填充Transform(source, target) — 变形ReplacementTransform(source, target) — 替换变形TransformMatchingShapes(source, target) — 形状匹配变形mobject.animate.to_edge(UP) — 移动到边缘mobject.animate.shift(RIGHT * 2) — 平移mobject.animate.scale(2) — 缩放Rotate(mobject, angle=PI) — 旋转Text("文字", font_size=48, color=BLUE) — 文字MathTex(r"e^{i\pi}+1=0") — LaTeX 公式Circle(radius=1, color=RED) — 圆Square(side_length=2, color=GREEN) — 正方形Arrow(start, end) — 箭头NumberPlane() — 坐标平面Axes(x_range, y_range) — 坐标轴VGroup(obj1, obj2) — 垂直分组group.arrange(RIGHT, buff=0.5) — 水平排列BackgroundRectangle(obj, color=BLACK, fill_opacity=0.6) — 背景矩形症状:UnknownCodecError: libx264
根因:Manim 在 scene_file_writer.py 中硬编码使用 libx264 编码器(无法通过 config/cfg 覆盖),但 conda 环境的 ffmpeg 编译时 --disable-gpl,不包含 GPL 许可的 libx264。
解决:
# Conda 环境(最常见场景)
conda install x264 -c conda-forge
# 安装后 conda-forge 的 ffmpeg 会自动重新链接 x264 库
# 验证
ffmpeg -codecs 2>&1 | grep libx264
# 应输出包含: encoders: libx264 libx264rgb
注意:brew install ffmpeg 安装的 ffmpeg 自带 x264,但 conda 环境优先使用自己安装的 ffmpeg,不会使用 Homebrew 版本。
manim-voiceover 依赖 pkg_resources,Python 3.12+ 可能报错:
pip install "setuptools>=69.0,<72.0"
SRT 字幕烧录需要 libass。macOS:
brew install ffmpeg
# 验证
ffmpeg -filters 2>&1 | grep subtitles
Linux:
sudo apt install libass-dev
# 可能需要重新编译 ffmpeg
gTTS 需要访问 Google TTS 服务,如网络不通可切换为 pyttsx3 离线引擎:
from manim_voiceover.services.pyttsx3 import Pyttsx3Service
self.set_speech_service(Pyttsx3Service())
Manim 使用系统字体渲染 Text 对象,确保系统有中文字体:
sudo apt install fonts-noto-cjkText("文字", font="PingFang SC")references/manim_guide.md — 详细的 Manim + voiceover + 字幕技术文档scripts/check_environment.py — 一键检查所有依赖scripts/run_pipeline.py — 一键渲染 + 字幕烧录