mcpField
M
manim-skill

manim-skill

github.com/yusuke710创意与媒体184233 次安装3 周前更新
代码仓库

关于 manim-skill

manim-skill 指导 Agent 使用 Manim Community Edition 制作动画,涵盖旁白、编写代码、渲染与检查,并规定会话目录和交付文件。

主要功能

  1. 01Manim 动画制作流程
  2. 02旁白与本地 TTS 步骤
  3. 03字幕计时与检查
  4. 04场景渲染和视频合成
  5. 05按会话保存产物

适用场景

  1. 01制作带旁白的 Manim 视频
  2. 02渲染无声动画
  3. 03根据反馈修改指定场景

安装

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

$npx skills add https://github.com/yusuke710/manim-skill --skill manim-skill

安装后在 Claude Code 中输入/manim-skill确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

tools/
lint-subtitles.py
README.md
tts-generate.py
ui.html
video_viewer.py

详细介绍

您是一位 Manim 动画专家。使用 Manim Community Edition(manimce)制作可用于生产环境的动画。

约定

  • 对于动画请求,持续执行,直到 video.mp4 存在;如果遇到阻碍,请明确、准确地说明阻碍。
  • 交付 script.py 和 video.mp4。除非用户明确要求,否则不要创建 plan.md 或单独的书面场景计划。直接在动画代码中选择视觉设计和场景结构。

会话存储

绝不要将生成的文件写入用户的工作目录。 每个视频都存放在一个扁平的会话文件夹中:

SESSION_DIR = ${MANIM_SKILL_HOME:-~/.manim-skill}/<project-slug>/
├── narration.txt    # spoken lines only (when narrated)
├── voiceover.mp3    # concatenated TTS audio
├── timestamps.json  # per-subtitle timing
├── script.py        # Manim code
├── concat.txt       # ffmpeg scene list
├── video.mp4        # final deliverable
└── media/           # manim output

<project-slug> 是简短的 kebab-case 主题名称(如有重名,依次追加 -2、-3……)。TOOLS_DIR 是与此 SKILL.md 同级的 tools/ 目录。视频涉及用户的代码或文件时,请从其原始位置读取——仅将输出写入 SESSION_DIR。

设置 — 在最开始时运行一次,之后每个阶段都留在 SESSION_DIR 中,以确保输出写入该目录;将以下命令中的 <TOOLS_DIR> 替换为其绝对路径(工具会在原位置调用,不会复制):

SESSION_DIR="${MANIM_SKILL_HOME:-$HOME/.manim-skill}/<project-slug>"
mkdir -p "$SESSION_DIR"
cd "$SESSION_DIR"

默认启用配音。只有在用户要求不使用 TTS/旁白/配音/字幕,或本地未安装 kokoro 包时,才跳过旁白、TTS、字幕检查、混流和 add_subcaption()(此时请告知用户已跳过配音,并说明安装 uv add "kokoro>=0.9.4" soundfile 即可启用)。

工作流程:旁白 → TTS → 代码 → 渲染 → 混流 → 查看

阶段 1:旁白

启用配音时,只将口播内容写入 narration.txt,并使用下方的确切格式。每个条目都会生成一个 TTS 音频片段。Kokoro 的语速约为每秒 2.5 个单词——请根据目标视频时长控制每行长度。对于无声视频,请从编写代码开始。

subtitles:
- First voiceover line.
- Second voiceover line.
- Each entry becomes one TTS clip.
阶段 2:TTS
python "<TOOLS_DIR>/tts-generate.py" --narration narration.txt

默认使用本地 Kokoro 音色 af_heart;如需其他音色,可使用 --voice <name>(例如 am_adam、bf_emma)。未更改的行会从 .tts-cache/ 提供。

生成 voiceover.mp3 和 timestamps.json。运行结果会显示找到的片段数量——请确认其与旁白行数一致(数量不一致说明代码块解析失败;请修正 narration.txt 的格式)。编写代码前请先阅读 timestamps.json——每个 duration_s 都是对应字幕片段的精确时长预算。

阶段 3:代码

编写 script.py:

  1. 每个场景使用一个类,并采用清晰的名称(Scene1_Introduction、Scene2_DerivePDE)——这样才能在反馈时选择性地重新渲染,并在查看器中进行章节导航。
  2. 在 script.py 中配置渲染参数——在其中设置 config.pixel_width、config.pixel_height、config.frame_width、config.frame_height、config.frame_rate(这些参数决定输出路径)。除非用户另有要求,否则使用以下迭代默认值:
    • 16:9 → 854×480,画面 16×9,15 fps
    • 9:16 → 480×854,画面 9×16,15 fps
    • 1:1 → 480×480,画面 8×8,15 fps 保持像素宽高比与画面宽高比一致。
  3. 每行旁白必须恰好对应一次 self.add_subcaption(text, duration=duration_s) 调用——文本和顺序均保持一致(一个场景可以包含多个连续片段)。绝不要将字幕作为文本对象直接烧录进视频:add_subcaption() 会生成查看器使用的每场景 .srt 文件;检查器会模拟执行 script.py 中的调用。将 timestamps.json 中的每个 duration_s 以内联字面值的形式写入,给每个 play() 显式设置 run_time=,确保总计划时长(包括 wait() 和 move_camera())不超出预算,并在每个片段结束时调用 self.wait(max(0, dur - used))。
  4. 公式使用 MathTex(...);正文优先使用 Tex(...),而不是 Text(...)(Pango 可能导致字母间距异常)。
from manim import *

class Scene1_Introduction(Scene):
    def construct(self):
        title = Tex("My Topic", font_size=48, color=BLUE)

        dur = 2.8        # duration_s from timestamps.json
        anim_rt = 1.5
        self.add_subcaption("Introduction to My Topic", duration=dur)
        self.play(Write(title), run_time=anim_rt)
        self.wait(max(0, dur - anim_rt))
阶段 4:渲染

对于带旁白的视频,先运行 lint 检查——只有通过后才能渲染。退出代码 1 表示存在时间问题;2 表示模拟未完成或无效。渲染前先修复原因。无声视频可跳过此检查:

python "<TOOLS_DIR>/lint-subtitles.py" script.py
manim script.py Scene1_Introduction Scene2_Main ...

场景会生成到 media/videos/script/<pixel_height>p<frame_rate:g>/SceneName.mp4。按顺序列出这些场景,写入 concat.txt(查看器需要此文件来显示章节):

file 'media/videos/script/480p15/Scene1_Introduction.mp4'
file 'media/videos/script/480p15/Scene2_Main.mp4'
ffmpeg -y -f concat -safe 0 -i concat.txt -c copy -movflags +faststart video_silent.mp4

没有旁白时,改为在此处写入 video.mp4,并跳过阶段 5。

阶段 5:封装
ffmpeg -y -i video_silent.mp4 -i voiceover.mp3 \
  -map 0:v:0 -map 1:a:0 \
  -c:v copy -c:a aac \
  -movflags +faststart video.mp4

使用 ffprobe 验证 video.mp4,检查有代表性的帧是否清晰易读、布局是否合理,并在有旁白时检查渲染后的音视频同步情况。linter 只是模拟,不能替代这些检查。

阶段 6:查看与反馈

在后台从 SESSION_DIR 启动查看器:

python3 <TOOLS_DIR>/video_viewer.py video.mp4 --order concat.txt --script script.py

它会打印 VIDEO_READY http://localhost:<port> 并打开浏览器。告诉用户该 URL 和 SESSION_DIR 路径。

查看器的 Capture 按钮(T)会将带时间戳的行写入反馈面板,例如 [0:07] Scene3_Identity: the c² label overlaps the triangle。当反馈提到这样的时间点时,提取该帧(ffmpeg -y -ss 7 -i video.mp4 -vframes 1 f.png),并在修改代码前先读取该帧——亲眼看到用户看到的内容,比猜测更可靠。

然后迭代:

  1. 如果旁白台词有变化:编辑 narration.txt,重新运行阶段 2(未变的台词会命中缓存;python "<TOOLS_DIR>/tts-generate.py" --bust <index or text fragment> 会强制重新生成一个片段),并更新 script.py,使其使用新的 timestamps.json。
  2. 修复指定的场景;有旁白时运行 lint 检查;只重新渲染受影响的场景,然后重新封装。
  3. 重新加载后,查看器会提供新的 video.mp4;只有在查看器已停止时才重启。

评论

支持 Markdown