Project
edumotion
输入一个知识点,即可自动生成一段带解说字幕和可选配音的教学动画视频(HTML/MP4),将抽象概念转化为直观的动态演示。slug: edumotion
owner: bike13
repo: edumotion
EduMotion · 教学动画生成器
输入一个知识点(如「勾股定理」「Dijkstra 算法」),自动生成一段自包含的 HTML5 教学动画,可选叠加 TTS 配音,并导出为 MP4。
项目简介
EduMotion 用大模型把「知识点 → 讲解字幕 → 配音 → 动画 HTML → 录制视频」这条链路自动化。后端 FastAPI + LangGraph 编排,前端 Vue3 单页,浏览器端用 Playwright 录屏、FFmpeg 转码出片。
逻辑简要
生成流程是一条 LangGraph 状态图,含两个人工确认断点(字幕、预览),前端可介入编辑:
生成字幕 → [字幕确认断点] → ┬ 勾选 TTS → 合成配音 → 生成动画(按音频时长计时) → 嵌入音频 ┐
└ 未勾选 → 生成动画(单次) ┘
→ [HTML 预览断点] → 勾选自动录制 → 录制 → 落库
关键契约与设计:
- 字幕先行:先由模型产出讲解字幕,再据字幕逐条合成 TTS,测得每条音频真实时长后,才生成与时长匹配的动画 HTML,保证音画同步。
- 生成 HTML 的 JS 钩子:模型被要求始终输出
showSubtitle(text)(字幕)、await wait(ms)(计时)、markAnimationFinished()(派发recording:finished事件,录制端据此停录)。改钩子名需同步改提示词与录制/抽取逻辑。 - 音画对齐:视觉等待轴(
embed_audio_in_html)与合成音轨轴(_build_merged_audio)共用同一间隔公式;导出时按「录屏时长 − 音轨时长」裁掉动画启动前的静止片头,令音画从第 0 帧对齐。 - 多引擎:OpenAI / Claude / 火山方舟(ark) / Gemini,经预设(preset)配置,可按阶段(字幕/HTML)绑定不同模型。
目录结构
edumotion/ 后端主包
├── api/ FastAPI 路由(health / generate / presets / config / history)
├── graph/ LangGraph 状态图:nodes(节点) / pipeline(装配) / state(状态)
├── engines/ 多 LLM 引擎适配(openai/claude/ark/gemini + factory)
├── services/ 业务服务:字幕匹配、音频嵌入、录制合成、TTS、提示词
├── db/ SQLAlchemy 模型 / 仓储 / 连接
├── config/ 设置与日志
└── schemas.py API 请求/响应模型(Pydantic v2)
frontend/ Vue3 + Vite 单页前端(设置 / 生成 / 进度 / 预览)
scripts/ record_media.py(Playwright 录制+FFmpeg)、e2e_dry/e2e_real
utils/ 火山 v3 双向 WebSocket TTS 客户端与二进制协议
app.py 入口:装配 FastAPI、路由、静态、启动建表
技术栈
- 后端:Python 3.11、FastAPI、Uvicorn、LangGraph、SQLAlchemy 2、Pydantic v2
- 前端:Vue 3、Pinia、Vite
- 模型:OpenAI SDK / Anthropic(httpx) / 火山方舟 / google-genai,任意 OpenAI 兼容端点
- 配音:火山引擎 TTS(豆包 HTTP v1 / v3 双向 WebSocket)
- 出片:Playwright(Chromium) 录屏 → FFmpeg 转码 MP4/GIF
- 存储:默认本地 SQLite(可切 MySQL)
启动方式
手动启动
python -m venv .venv && .venv\Scripts\activate # Windows(或 source .venv/bin/activate)
pip install -r requirements.txt
playwright install chromium # 录制所需
playwright install-deps chromium # 仅 Linux
cp .env.example .env # 填入 LLM/TTS 凭据
# 前端构建(可选,构建后由后端静态托管;开发时也可 cd frontend && npm run dev 单跑)
cd frontend
npm install
npm run build
npm run dev
python app.py # 服务于 http://127.0.0.1:8005
Docker
docker-compose up -d # host 端口默认 8005,可用 HOST_PORT 覆盖
镜像内含 FFmpeg、中文字体、Chromium 及依赖;前端在构建阶段一并打包。
配置
复制 .env.example 为 .env。解析优先级:环境变量 → .env。
| 变量 | 说明 |
|------|------|
| DATABASE_URL | 数据库连接串,默认 sqlite:///edumotion.db;切 MySQL 填 mysql+pymysql://... |
| DOUBAO_VOICE_APP_ID / DOUBAO_VOICE_API_KEY / DOUBAO_VOICE_TYPE | 豆包 HTTP TTS 凭据与音色 |
| TTS_APP_ID / TTS_ACCESS_TOKEN / TTS_VOICE_TYPE / TTS_ENDPOINT | 火山 v3 WebSocket TTS(可选兜底) |
| PORT | 服务端口,默认 8001 |
LLM 预设(引擎/base_url/api_key/model)在运行时经 /api/presets 接口管理并持久化,不走 .env。
核心接口
所有接口以 /api 为前缀。前端静态页挂在 /,产物目录挂 /output、/recordings。
| 方法 | 路径 | 功能 | 关键参数 |
|------|------|------|----------|
| GET | /api/health | 健康检查 | — |
| POST | /api/generate | 启动生成(SSE 流),到字幕断点中断 | topic 知识点、target_audience 受众、enable_tts 是否配音、auto_record 是否自动录制 |
| POST | /api/generate/{id}/subtitles | 提交编辑后的字幕、继续流程 | subtitles 台词列表、enable_tts |
| POST | /api/generate/{id}/revise | 依反馈重生成字幕 | feedback 修改意见 |
| POST | /api/generate/{id}/resume | 预览断点后继续 | action = record(录制) | skip(跳过) |
| GET | /api/history / /api/history/{id} | 历史列表 / 详情 | — |
| GET | /api/history/{id}/download | 下载产物 | — |
| DELETE | /api/history/{id} | 删除历史(级联清产物) | — |
| GET/PUT | /api/config | 读取 / 更新 TTS 与阶段绑定配置 | tts_*、stage_preset_subtitle、stage_preset_html |
| GET/POST/PUT/DELETE | /api/presets | 模型预设增删改查 | name、engine_type(openai/claude/ark/gemini)、base_url、api_key、model、temperature、max_tokens |
| POST | /api/presets/{id}/activate | 启用某预设 | — |
| POST | /api/presets/{id}/test | 连通性测试 | 可空字段则沿用已存预设值 |
运行时产物目录
output/(最终 MP4/音频/中间 HTML 与录屏) 均已 gitignore。
API_KEY
API_KEY=sk-PviHWHby3225LjxXY0nzYYLiFSQpuhREG0TgNHktu7eagAfz BASE_URL=https://www.dmxapi.cn
评论