mcpField
P
psychopomp

psychopomp

github.com/kitlangton创意与媒体41389 次安装1 周前更新
代码仓库

关于 psychopomp

psychopomp 是用于制作软件变更解说短片的技能,要求先核实变更事实,再编写旁白并构建场景。它将动画视觉节拍与旁白短语对齐,并涵盖审阅和渲染流程。

主要功能

  1. 01依据差异和测试核实变更
  2. 02编写分片旁白脚本
  3. 03用可复用组件组合动画场景
  4. 04将视觉节拍对齐到转录短语
  5. 05审阅并渲染完整短片

适用场景

  1. 01用动画场景解释拉取请求
  2. 02制作带旁白的代码前后对比讲解
  3. 03用定时标注和计数器展示行为变化

安装

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

$npx skills add https://github.com/kitlangton/psychopomp --skill psychopomp

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

附带文件STORY.md

详细介绍

Psychopomp 讲解短片

讲解短片由多个独立编写的 Scene Plan 在同一时间轴上拼接而成:GPU Stage 上的行为故事(光球、卡片、光束、数据包、摄像机、泛光)、固定 Callout、滚动数字、以动画阶梯差异呈现的更改、终端风格字幕,以及可选的配音。添加配音后,每个视觉节拍都会等待转录稿中的对应短语,因此重新配音会自动调整影片的时间安排。

可参考的示例位于 scenes/pr-walkthrough:src/flagship.rs(以 Stage 影片形式呈现 #50825,并缩放至其代码)、src/stop_stage.rs(结合 Stage、Callout、滚动数字,并缩放至带注释的代码差异,呈现 #50042),以及 src/lib.rs(包含时序图的五个 PR 短片)。沿用它们的结构;不要从空白 crate 开始。组件负载、通道和命令见 SCENE_PLANS.md(“制作配音讲解短片”),术语见 CONTEXT.md;开始编写前请先阅读两者。工程规则见 AGENTS.md。

步骤

  1. 确认事实。 对于每项更改,阅读实际差异和 PR 描述 (gh pr diff、gh pr view),并分别用一句话描述出错的行为、 修复后的行为和具体更改。完成标准:你要配音的每项说法都能追溯到 代码、测试或复现结果;标出任何无法验证的内容,并将其排除在脚本之外。

  2. 编写脚本,保存为 scenes/<name>/narration/script.json,每个部分对应一个片段: 开场,然后每项更改依次为 <slug>-before、<slug>-after、<slug>-code,最后是结尾。 编写时遵循 STORY.md。完成标准:每个片段的配音时长约为 30 秒以内, 且每个计划中的视觉节拍都有独特的锚点短语。

  3. 配音(可选)。 先在不使用凭据的情况下起草(--draft 使用 macOS say),或者使用 ElevenLabs(engine: "elevenlabs",默认模型为 eleven_v4) 或 Fish Audio(engine: "fish")合成最终配音:

    {
      "engine": "elevenlabs",
      "model": "eleven_v4",
      "voice": "<elevenlabs-voice-id>",
      "settings": { "stability": 0.5, "similarity": 0.7 },
      "clips": [
        { "id": "change-before", "text": "[warm, conversational voice] ..." }
      ]
    }
    
    # Draft (no API key required)
    bun scripts/narrate.ts scenes/<name>/narration/script.json --draft
    
    # ElevenLabs (requires ELEVENLABS_API_KEY and script.voice)
    ELEVENLABS_API_KEY=... bun scripts/narrate.ts scenes/<name>/narration/script.json
    
    # Fish Audio (requires FISH_AUDIO_API_KEY)
    FISH_AUDIO_API_KEY=... bun scripts/narrate.ts scenes/<name>/narration/script.json
    

    scripts/narrate.ts 会规范化响度、使用 Whisper 转录词语时间,并写入 <id>.mp3、<id>.words.json 和 narration.json。切换声音或引擎时,请根据新的词语时间重新构建 Scene Plan。

    或者在 Scene Program 中声明配音,使用 psychopomp-media (SCENE_PLANS.md, “声明配音和声音”):media.say(id, &voice, text)、 media.dialogue、media.sfx 和 audio.derive(Effect::pitch(..)),然后 media.finish()?。每行只生成一次,并记录在 media.lock.json 中;之后除非声明发生变化,否则运行时不会调用任何内容,而 ElevenLabs 的词语时间会根据其字符对齐结果和脚本拼写生成。先用 PSYCHOPOMP_MEDIA=plan cargo run -p <crate> 检查费用(不会发起 API 调用), 用 PSYCHOPOMP_MEDIA=draft 计时,并用 PSYCHOPOMP_MEDIA=prune 清理。使用 cargo run -p psychopomp-media -- adopt scenes/<name>/narration 迁移 narrate.ts 场景 (不会重新生成)。完成标准:普通运行时每个资源都显示 =。

  4. 编写场景程序,放在 scenes/<name> 中(工作区会自动识别;在 verify.json 中添加几个关键时间点)。 使用 psychopomp::score(SCENE_PLANS.md,「使用 Score DSL 编写」),确保 PlanBuilder 是唯一的 mut 绑定,且每个角色(Stage、Camera、 Caption、Callout、RollingNumber、Checklist、Meter、Bars、 Subtitles、Confetti、Terminal、Chat、ChangedFiles、LowerThird、 Lens)都是不可变值,其方法会返回可组合的 Beat(.then、.also、.with、.on_end、.after、.early、stagger、each、 at!(scene, time => ...))。使用 Narration::reading 安排片段,使用 StageElement::card|orb|beam|packet|label|ring 和相对的 psychopomp::layout::Placement 包络,在 StagePost::RESTRAINED 上构建元素; 使用 Caption::header|chip|footer 添加画面说明,并使用 sfx::*.beat(id, gain_db) 播放音效(或在 psychopomp-media 中使用 audio.beat(gain_db))。加载 explainer-motion 技能并将其应用到每个节拍:卡片使用 settle_in,光束使用 connect, 消息使用 send,回复等待 .reply(),冲击使用 hit,主角使用 orb_in, 修复过程使用 rewind;使用 Callout 将注释固定到舞台元素或编辑器代码范围, 使用 RollingNumber 显示实时计数器和计时器;通过 stage.camera()(establish、frame、follow、release、 orbit、whip、dolly_zoom)控制镜头移动。优先使用可视化和文字叠加, 而不是用 Stage 标签和圆环手动构建:用 Checklist 展示运行并解决的检查项, 用 Meter(MeterPlan::countdown)显示超时圆环,用 Bars 展示前后数值, 用 Confetti 呈现成功节拍,用 Subtitles(SubtitlesPlan::from_spoken)烧录按词计时的字幕。 变更由 Diff 组成,包含 keep、add(step) 和 remove(step) 行,每个 step 都对应一个短语。 当 cargo run -p <crate> 写入视频片段,且 cargo run --release -- plan validate <reel> 报告有效时,即为完成。缺少短语会连同其片段一起触发 panic: 将锚点改为转录中实际包含的词语。

  5. 渲染前先检查。 使用 plan inspect <reel> 获取片段跨度,然后为每个片段的开始、切换、结束和代码节拍生成联系表:

    bun scripts/sheet.ts <reel> t1,t2,... --theme neutral --shutter --out output/sheet.jpg
    

    调整外观时,设置 PSYCHOPOMP_SHADER_DIR=crates/psychopomp-render/src/render 并编辑 stage.wgsl/stage_post.wgsl:每一帧和联系表都会应用着色器编辑,无需重新构建 Rust。 然后为一个行为片段渲染含音频的视频(plan render <reel> out.mp4 --cue <scene-id>), 或渲染 2–3 秒的时间窗口(--range a..b),并检查从运动过程中提取的帧。所有片段都检查过,且没有文字重叠、裁切或对应错误的芯片时,即为完成。

  6. 渲染并验证整个视频片段;仅在联系表和短时间窗口检查通过后执行一次。使用较长的超时时间在前台运行,且在任务仍在运行时绝不要结束这一轮:

    cargo run --release -- plan render <reel> output/<name>.mp4 --theme neutral
    

    当 ffprobe 显示分辨率为 1920x1080、帧率为 60 fps、音频为 AAC,时长与 plan inspect 相符,响度接近 -16 LUFS 且峰值低于 -1 dBFS 时,即为完成。

  7. 交付 MP4 路径。使用符合规范的提交消息,将场景、旁白素材以及 Psychopomp 中的任何引擎变更一并提交。

改进 Psychopomp

当某个 reel 需要引擎无法实现的功能时,应将其添加到 Psychopomp,而不是在某个场景中另辟蹊径:在 crates/psychopomp 中规划类型并进行验证,在 plan_runtime 中进行严格通道预检,在 render 中处理像素,添加不依赖 GPU 的测试和一个 #[ignore] GPU 测试,并及时更新文档 AGENTS.md。更改前运行 cargo run --release -- verify baseline,更改后运行 verify compare --expect <scenes you changed>,以证明其他所有展示项目和影片均未受影响。

从小型、可复用的组件着手构建。插值、缓动、曲线、形状接口和连接器应放在 psychopomp::math 中(按 pmndrs math 的结构组织:核心包括 lerp/ remap/smoothstep,以及 easing、curve、shapes、random;向量使用 glam)。应扩展这些组件,而不是在渲染器或场景中内联数学运算,并将渲染器拆分为每个元素对应一个小型辅助函数,如 render/stage.rs 所示。确保 cargo fmt --check、cargo clippy --workspace --all-targets --all-features -- -D warnings 和 cargo test --workspace 均通过。

评论

支持 Markdown