code2animation

通过代码生成带语音的动画视频,支持多种转场效果和自动渲染。

已扫描
适合谁
需要自动化制作短视频的技术人员、内容创作者或教育工作者
不适合谁
无编程基础的普通用户、无法安装 FFmpeg 或本地运行环境的用户
国内可用性
需网络配置。可能需要网络配置或第三方服务可访问。
安装难度
新手友好(★☆☆)。基于终端操作、依赖、API Key 和本地环境要求的初步判断。

安装与下载

openclaw skills install @etrobot/code2animation

Skill 说明

命令、参数、文件名以原文为准

AgentSaaS 视频编辑技能

一个全面的视频编辑与渲染技能,使 AI 代理能够创建基于代码的动画,包含文本转语音旁白和流畅的转场效果。

目的

此技能允许代理实现以下功能:

  • 创建并预览带有动画的交互式视频项目
  • 使用 Microsoft Edge TTS 生成文本转语音音频
  • 渲染包含音画同步视觉特效的完整视频
  • 支持竖屏和横屏视频格式
  • 在媒体元素之间应用平滑的转场效果

核心能力

1. 交互式视频预览

  • 浏览器中实时预览视频项目
  • 播放控制用于测试与调试
  • 支持转场、媒体片段和时间调整
  • 帧级定位以实现精确编辑
  • 实时转场预览,支持缓动效果

2. 转场系统

  • transitionIn:每个媒体可定义自身的入场动画
  • 支持的转场类型:fade(淡入)、zoom(缩放)、slide2Left(向左滑动)、slideUp(向上滑动)、none(无)
  • 缓动效果:滑动和缩放动画使用内置的 easeOutCubic 缓动
  • stayInClip:若为 true,媒体将持续显示至该片段结束
  • 跨片段转场:自动处理片段边界情况

3. 文本转语音音频生成

  • 使用 Microsoft Edge TTS(msedge-tts)实现自动化文本转语音
  • 支持多种语音(英文与中文)
  • 生成词级时间标记,用于口型同步与动画匹配
  • 音频文件缓存以加快预览速度

4. 视频渲染

  • 使用 Puppeteer 实现逐帧自动化渲染
  • 集成 FFmpeg 进行视频编码与音频混合
  • 输出分辨率为 1920×1080(横屏)或 1080×1920(竖屏),帧率为 30 FPS
  • 确定性渲染,确保结果一致
  • 最终输出保留所有转场效果

项目配置格式

媒体项属性

  • src:footage 目录中的 HTML 文件名
  • words:语音中触发该媒体的关键词
  • transitionIn:入场动画类型(可选)
  • transitionDuration:持续时间(秒,可选,默认值:0.6s)
  • stayInClip:若为 true,媒体将在整个片段期间保持可见(可选)

转场类型

  • fade:透明度渐变(0 → 1)
  • zoom:缩放渐变(2x → 1x),含透明度变化
  • slide2Left:从右侧水平滑入(100% → 0%)
  • slideUp:从底部垂直滑入(100% → 0%)
  • none:无转场效果

转场行为

  • transitionIn:定义媒体进入场景的方式
  • transitionDuration:持续时间(秒,默认值:0.6s)
  • stayInClip:若为 true,媒体将一直显示到片段结束
  • 缓动:slide2Left 和 slideUp 使用 easeOutCubic 实现平滑减速

参考实现

请参阅 public/projects/agentSaasPromoVideo.json 获取完整示例,演示所有转场类型及 stayInClip 行为。

技术要求

系统依赖

  • Node.js:版本 18 或更高
  • FFmpeg:用于视频编码与音频混合
  • Chromium/Chrome:Puppeteer 用于无头渲染

Node.js 依赖

  • React & Vite:前端框架与构建工具
  • Puppeteer:无头浏览器,用于帧捕获
  • msedge-tts:Microsoft Edge TTS,用于音频生成
  • Express:可选 HTTP 服务器(用于 TTS API 端点)
  • Motion(Framer Motion):动画库
  • Tailwind CSS:样式框架

Shell 命令

此技能执行以下 shell 命令:

音频生成

npx tsx scripts/generate-audio.ts <projectId>
  • 读取项目 JSON 配置文件
  • 使用 Edge TTS 生成 MP3 音频文件
  • 保存词级时间标记数据

视频渲染

node scripts/render.js <projectId> [--portrait]
  • 启动本地 Vite 开发服务器
  • 启动 Puppeteer 捕获画面帧
  • 使用 FFmpeg 编码视频并混合音频
  • 清理临时文件

FFmpeg 操作

  • 帧编码:ffmpeg -framerate 30 -i frames/frame-%05d.jpg -c:v libx264 ...
  • 音频混合:ffmpeg -i video.mp4 -i audio1.mp3 -i audio2.mp3 -filter_complex ...

浏览器检测

  • 使用 which 命令在 Linux/macOS 上查找 Chrome/Chromium
  • 尊重 PUPPETEER_EXECUTABLE_PATH 环境变量设置

API 端点(可选)

该技能可暴露一个 HTTP 端点用于 TTS 生成:

POST /api/tts
Content-Type: application/json

{
  "text": "要朗读的文本",
  "voice": "en-US-GuyNeural",
  "rate": "+0%",
  "pitch": "+0Hz"
}

此端点为可选功能,仅在未预先生成音频文件时使用。

安全注意事项

文件系统访问

  • 读取路径:public/projects/<projectId>/
  • 写入路径:public/projects/<projectId>/audio/public/video/
  • 为帧存储创建临时目录
  • 渲染完成后清理临时文件

网络访问

  • 在端口 5175+ 启动本地 HTTP 服务(可配置)
  • 连接 Microsoft Edge TTS 服务(外部接口)
  • 基础功能无需外部 API 密钥

进程执行

  • 启动子进程用于:Vite 开发服务器、FFmpeg 编码
  • 使用 execSync 执行:浏览器检测、音频生成触发
  • 所有命令均为预定义,不可由用户控制

环境变量

可选配置:

  • PUPPETEER_EXECUTABLE_PATH:自定义 Puppeteer 使用的浏览器路径
  • FASTMCP_LOG_LEVEL:日志级别(默认值:ERROR)

项目结构

public/
  projects/
    <projectId>/
      <projectId>.json       # 项目配置文件
      footage/               # HTML/CSS 媒体组件
      audio/                 # 生成的 TTS 音频文件
        0.mp3, 1.mp3, ...
        0.json, 1.json, ...  # 词级时间标记文件
  video/
    render-<projectId>-landscape.mp4
    render-<projectId>-portrait.mp4

使用示例

1. 为项目生成音频

pnpm generate-audio agentSaasPromoVideo

2. 在浏览器中预览

pnpm dev

3. 渲染最终视频

pnpm render agentSaasPromoVideo

4. 渲染竖版视频

pnpm render agentSaasPromoVideo --portrait

HTML 动画规范

在创建用于视频渲染的 HTML 动画时,请使用 CSS 变量时间线 模型。

核心模型

  • 渲染器控制时间:Puppeteer 每帧设置 --t
  • 页面仅渲染状态:DOM = f(t)
  • 不使用生命周期动画 API(如 play/start/reset)和隐藏的运行时状态。
  • 进入效果由过渡系统处理:不要在 HTML 中实现滑动/淡入等过渡效果,应使用项目的 transitionIn 属性。

✅ 必须遵循的模式

  • 定义时间线根节点:
:root { --t: 0; }
  • 所有动画属性必须基于 --t
  • 始终对归一化进度值进行限制:
--p: clamp(0, calc((var(--t) - var(--start)) / var(--duration)), 1);
  • 直接在 CSS 中定义初始/结束状态(可在任意帧安全定位)。
  • 仅使用小规模确定性 JavaScript 进行内容映射(例如根据 t 获取字幕或文本索引)。
  • 让过渡系统处理进入效果:专注于内容动画,而非进入动画。

🚫 禁止使用的模式

  • transition
  • animation / @keyframes
  • window.registerFrameAnimation(...)
  • 使用 requestAnimationFrame 循环推进时间线
  • 使用 Date.now() / performance.now() 隐式获取时间以控制视觉状态
  • 手动实现进入过渡:不要在 HTML 中实现滑动/淡入效果,应使用项目配置中的 transitionIn
  • 淡出效果:元素在动画结束后不应消失。请使用 opacity: var(--p) 而非 opacity: calc(var(--p) * (1 - var(--fade))),以确保元素在最终状态仍可见。

推荐模板

.element {
  --start: 0.5;
  --duration: 1;
  --p: clamp(0, calc((var(--t) - var(--start)) / var(--duration)), 1);

  opacity: var(--p);
  transform: translateY(calc((1 - var(--p)) * 20px));
}

缓动处理(不使用 transition)

直接在进度上使用数学计算:

--p: clamp(0, calc((var(--t) - var(--start)) / var(--duration)), 1);
--ease-out: calc(1 - (1 - var(--p)) * (1 - var(--p)));
opacity: var(--ease-out);

JS 钩子模式(仅限文本/内容)

<script>
  const labels = ['A', 'B', 'C'];
  const el = document.getElementById('label');

  window.onTimelineUpdate = (t) => {
    const idx = Math.floor(Math.max(0, t) / 1.2) % labels.length;
    el.textContent = labels[idx];
  };
</script>

时间语义(tglobalTime

  • onTimelineUpdate(t, globalTime) 支持两个时间域:

- t:片段本地时间(当片段切换时重置为 0)。这是大多数 HTML 动画的默认选择。

- globalTime:跨片段连续的时间线。仅当元素需要在跨片段切换时保持连续性时使用。

  • 不要假设 t 是媒体本地时间。如果媒体在片段中间出现,其首次可见时 t 可能已经较大。
  • 对于媒体本地行为(例如切换开始时才启动动画),应从首次可见的 globalTime 锚定,并推导:

- local = globalTime - mediaStartGlobalTime

  • 保持兼容性回退:
window.onTimelineUpdate = (t, globalTime) => {
  const g = Number.isFinite(globalTime) ? globalTime : t;
  // 一般动画使用 `t`,仅在需要连续性时使用 `g`
};

确定性检查清单

  • 任意跳转到 t 都应产生唯一且确定的帧。
  • 动画状态不得依赖“前一帧”。
  • 跨片段过渡的视觉效果应在两个片段中保持连续。
  • 最终帧(t = totalDuration)必须停留在最后一个片段上(不循环回第一个片段)。

限制说明

  • 需要在系统中安装 FFmpeg
  • TTS 生成需要联网(使用 Microsoft Edge TTS)
  • 渲染过程为 CPU 密集型,可能耗时数分钟
  • 单个片段最大 TTS 文本长度:约 1000 个字符
  • 帧捕获需要足够的磁盘空间

透明性声明

此技能会执行 shell 命令并启动子进程进行视频渲染。所有操作均限于以下范围:

  1. 启动本地开发服务器(Vite)
  2. 使用 FFmpeg 进行视频编码
  3. 使用 Puppeteer 进行帧捕获
  4. 检测系统上的浏览器可执行文件

不会执行任意代码或传递用户输入至 shell 命令。所有文件路径和命令均为预定义并经过验证。

E
@etrobot

已收录 1 个 Skill

相关推荐