EditMind
使用文档与调用文档
EditMind 是一个面向视频创作流程的镜头规划服务。它可以做角色提取、B-roll 规划、导演分场, 也可以根据纯文本或带时间戳字幕的 transcript 来生成可执行的分镜计划。
接口总览
GET
/health
健康检查
用于部署后的存活检测。
POST
/characters/extract
角色提取
从文稿中提取角色列表,供后续分镜流程使用。
POST
/storyboard/plan
分镜规划
支持纯文本,也支持附带 transcript 时间戳字幕做节拍化分镜规划。
POST
/broll/plan
B-roll 规划
将解说词拆成可检索素材的 B-roll 计划。
POST
/director/breakdown
导演分场
把故事或剧本拆成导演视角的场景和镜头表。
快速调用示例
如果你已经有 TranscriptCore 的结果,建议把 transcript 一起传入 /storyboard/plan,
这样 EditMind 会优先按字幕节拍做分镜规划,并把时间码保留到返回结果里。
{
"text": "这是一段待分析文稿",
"characters": [],
"transcript": {
"transcript_id": "tr_xxx",
"language": "zh",
"duration_ms": 120000,
"segments": [
{ "segment_index": 1, "text": "第一句字幕", "start_ms": 0, "end_ms": 2800 }
]
}
}
完整文档
下方是当前 API 文档全文。你也可以直接访问 /api.md 获取原始 Markdown。
# EditMind API
Base URL: `http://localhost:8080`(本地)/ 部署后替换为实际域名
---
## 通用响应格式
所有接口统一返回以下结构:
```json
{
"ok": true,
"data": { ... },
"error": null
}
```
失败时:
```json
{
"ok": false,
"data": null,
"error": {
"code": "INVALID_REQUEST",
"message": "错误详情"
}
}
```
| 字段 | 类型 | 说明 |
|---|---|---|
| `ok` | boolean | `true` 成功,`false` 失败 |
| `data` | object \| null | 成功时的业务数据,失败时为 `null` |
| `error` | object \| null | 失败时的错误信息,成功时为 `null` |
| `error.code` | string | `INVALID_REQUEST`(入参错误)/ `INTERNAL_ERROR`(服务端错误)|
| `error.message` | string | 错误描述 |
---
## GET /health
健康检查。
**响应**
```json
{ "status": "ok" }
```
---
## POST /storyboard/plan
**适用场景**:解说词 / 旁白文稿 → 素材库检索用分镜(配合素材搜索使用)
### 请求体
```json
{
"text": "文稿内容",
"max_sections": 3,
"transcript": {
"transcript_id": "tr_xxx",
"language": "zh",
"duration_ms": 120000,
"segments": [
{
"segment_index": 1,
"text": "第一句字幕",
"start_ms": 0,
"end_ms": 2800
}
]
}
}
```
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `text` | string | 是 | 文稿正文,不能为空 |
| `max_sections` | integer | 否 | 最多处理的分段数,默认处理全文 |
| `transcript` | object | 否 | 带时间戳字幕;提供后会优先按字幕节拍规划分镜 |
### 响应 `data` 结构
```json
{
"plan": {
"sections": [ Section ]
}
}
```
#### Section
| 字段 | 类型 | 说明 |
|---|---|---|
| `section_index` | integer | 段落序号,从 1 开始 |
| `title` | string | 段落标题 |
| `source_text` | string | 本段对应的原文 |
| `segments` | Segment[] | 视觉节拍列表 |
#### Segment
| 字段 | 类型 | 说明 |
|---|---|---|
| `segment_index` | integer | 节拍序号,从 1 开始 |
| `source_text` | string | 本节拍对应的原文片段 |
| `intent` | string | 本节拍的叙事意图 |
| `start_ms` | integer \| null | 本节拍起始时间戳(毫秒) |
| `end_ms` | integer \| null | 本节拍结束时间戳(毫秒) |
| `shots` | Shot[] | 分镜列表 |
#### Shot
| 字段 | 类型 | 说明 |
|---|---|---|
| `shot_index` | integer | 镜头序号,从 1 开始 |
| `purpose` | string | 镜头用途:`establishing` / `action` / `reaction` / `detail` / `transition` / `atmosphere` |
| `brief` | string | 画面描述(可见内容:主体、动作、情绪、环境、机位) |
| `people` | string[] | 画面中出现的人物名,无人物时为空数组 |
| `mood` | string[] | 情绪关键词 |
| `actions` | string[] | 可见动作描述 |
| `camera` | string \| null | 景别 / 运动 / 角度,如 `"近景,固定"` |
| `duration_hint` | number \| null | 建议时长(秒) |
### 示例
**请求**
```bash
curl -X POST http://localhost:8080/storyboard/plan \
-H "Content-Type: application/json" \
-d '{"text": "875年,唐朝蝗灾,百姓苦不堪言。"}'
```
**响应**
```json
{
"ok": true,
"data": {
"plan": {
"sections": [
{
"section_index": 1,
"title": "晚唐乱象",
"source_text": "875年,唐朝蝗灾,百姓苦不堪言。",
"segments": [
{
"segment_index": 1,
"source_text": "875年,唐朝蝗灾,百姓苦不堪言。",
"intent": "展现灾年百姓困苦",
"shots": [
{
"shot_index": 1,
"purpose": "establishing",
"brief": "远景,荒芜农田上蝗虫漫天,百姓面黄肌瘦",
"people": [],
"mood": ["绝望", "困苦"],
"actions": ["百姓望着农田叹气"],
"camera": "固定远景",
"duration_hint": 5
}
]
}
]
}
]
}
},
"error": null
}
```
---
## POST /broll/plan
**适用场景**:解说词 / 旁白文稿 → B-roll 配图方案(适合纪录片、讲解、Vlog)
### 请求体
```json
{
"text": "解说词文本",
"style": "documentary"
}
```
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `text` | string | 是 | 解说词正文,不能为空 |
| `style` | string | 否 | 内容风格:`documentary` / `explainer` / `review` / `educational` |
### 响应 `data` 结构
```json
{
"plan": {
"clips": [ Clip ]
}
}
```
#### Clip
| 字段 | 类型 | 说明 |
|---|---|---|
| `clip_index` | integer | 片段序号,从 1 开始 |
| `source_text` | string | 本片段对应的解说词原文 |
| `duration_hint` | number \| null | 建议时长(秒),与解说词朗读时长对应 |
| `shots` | BrollShot[] | B-roll 镜头列表,每个片段 1-2 个 |
#### BrollShot
| 字段 | 类型 | 说明 |
|---|---|---|
| `shot_index` | integer | 镜头序号,从 1 开始 |
| `brief` | string | 画面描述(与输入文本同语言) |
| `shot_type` | string | 镜头类型:`literal`(直接呈现)/ `detail`(细节特写)/ `metaphor`(象征性画面)/ `establishing`(环境建立)/ `abstract`(质感氛围) |
| `keywords` | string[] | 素材搜索关键词(英文),适用于 Getty / Pexels / Shutterstock |
| `flow_note` | string \| null | 与上一镜头的衔接说明,第一个镜头为 `null` |
---
## POST /director/breakdown
**适用场景**:小说 / 故事 / 剧本文本 → 导演分场 + 专业分镜表
### 请求体
```json
{
"text": "故事文本",
"genre": "历史"
}
```
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `text` | string | 是 | 故事或剧本正文,不能为空 |
| `genre` | string | 否 | 题材风格,如 `历史`、`悬疑`、`爱情`,用于调整拍摄风格 |
### 响应 `data` 结构
```json
{
"breakdown": {
"overview": Overview,
"scenes": [ Scene ]
}
}
```
#### Overview
| 字段 | 类型 | 说明 |
|---|---|---|
| `dramatic_arc` | string | 整体戏剧弧线与叙事结构分析 |
| `visual_approach` | string | 推荐的视觉语言与风格方向 |
| `tone` | string | 整体情感基调,如 `压抑`、`紧张`、`抒情` |
#### Scene
| 字段 | 类型 | 说明 |
|---|---|---|
| `scene_index` | integer | 场景序号,从 1 开始 |
| `heading` | string | 场景标题,标准格式:`INT./EXT. 地点 - 时段` |
| `source_text` | string | 本场景对应的原文 |
| `dramatic_purpose` | string | 本场景在故事中的戏剧功能 |
| `emotional_beat` | string | 本场景内的情绪走向 |
| `characters` | string[] | 本场景出现的人物 |
| `director_note` | string \| null | 导演意图:需要捕捉的感受与注意事项 |
| `shots` | DirectorShot[] | 分镜列表 |
#### DirectorShot
| 字段 | 类型 | 说明 |
|---|---|---|
| `shot_index` | integer | 镜头序号,从 1 开始 |
| `label` | string | 镜头编号,如 `1A`、`1B`、`2A` |
| `type` | string | 镜头类型:`master` / `single` / `OTS` / `insert` / `cutaway` / `POV` / `two-shot` |
| `size` | string | 景别:`EWS`(极远)/ `WS`(远)/ `MS`(中)/ `MCU`(中近)/ `CU`(近)/ `ECU`(极近) |
| `movement` | string | 机位运动:`static` / `push in` / `pull out` / `pan` / `tilt` / `track` / `dolly` / `handheld` / `crane` |
| `brief` | string | 画面内容:主体、构图、视觉核心 |
| `action` | string \| null | 人物或主体在本镜头内的动作 |
| `duration_hint` | number \| null | 建议时长(秒) |
| `transition_out` | string \| null | 出镜转场方式:`cut` / `dissolve` / `fade to black` / `smash cut` / `match cut` / `null` |