# **AI视频分镜生成器 - 前端API接口文档 (最终版)** ## **基本信息** * **Base URL:** `/api/v1` * **Content-Type:** `application/json` ## **重要功能更新 - 自定义提示词模板** **新增功能:** 现在支持自定义提示词模板!前端可以: 1. 让用户从预设模板中选择 2. 允许用户微调提示词内容 3. 将完整的提示词模板传递给后端 **约定变量格式:** - 生成剧本:`${script_or_idea}` - 用户的剧本或创意内容 - 生成分镜:`${materials_description}` - 项目素材描述,`${script}` - 用户剧本 **验证机制:** 后端会自动验证提示词模板是否包含必需的变量,缺少时会返回明确的错误提示。 ## **新的工作流程说明** 本次更新引入了全新的AI驱动工作流程,推荐按以下顺序进行: ### **推荐工作流程:** 1. **创建项目** → `POST /projects` 2. **生成剧本** → `POST /projects/{project_id}/generate-script` - 输入创意或剧本草稿 - AI自动生成完整剧本和所需素材列表 3. **素材处理** (三选一): - **选项A:** 批量生成所有素材图 → `POST /projects/{project_id}/generate-asset-images` - **选项B:** 单独生成指定素材图 → `POST /assets/{asset_id}/generate-image` - **选项C:** 手动为素材提供图片 → `PUT /assets/{asset_id}/image` 4. **生成分镜** → `POST /projects/{project_id}/generate-storyboards` - 系统会检查所有素材是否都有图片 5. **生成首帧图** → `POST /storyboards/{storyboard_id}/generate-frame` 6. **(可选)首帧图指导修改** → `POST /storyboards/{storyboard_id}/guide-frame` 7. **生成分镜视频** → `POST /storyboards/{storyboard_id}/generate-video` 8. **合成项目视频** → `POST /projects/{project_id}/compose-video` ### **兼容性说明:** - 旧的"关联素材"接口 (`POST /projects/{project_id}/assets`) 仍然保留,但不推荐使用 - 项目删除现在是软删除,不会真正删除数据 ## **模块:公共服务 (Public Services)** ### **1. 获取七牛云上传Token** 获取用于客户端直传文件到七牛云存储的临时Token。 * **Endpoint:** `GET /qiniu/upload-token` * **请求参数:** 无 * **成功响应 (200 OK):** * **Type:** `Object` * **描述:** 返回上传所需的Token以及相关的存储桶信息。Token具有一定的有效期。 ```json { "token": "qiniu_generated_upload_token_string", "domain": "https://your-qiniu-domain.com", "bucket": "your_bucket_name" } ``` ----- ## **模块一:提示词管理 (Prompt Management)** ### **1. 查询所有提示词** 获取系统中存储的所有可用提示词列表。 * **Endpoint:** `GET /prompts` * **请求参数:** 无 * **成功响应 (200 OK):** * **Type:** `Array` ```json [ { "step": "create_shots", "name": "default_v1", "prompt": "这是一个用于生成分镜的提示词..." } ] ``` ### **2. 根据step查询提示词** 获取指定step阶段的所有提示词。 * **Endpoint:** `GET /prompts/step/{step}` * **路径参数 (Path):** `step` (String) - 提示词使用的阶段 * **请求参数:** 无 * **成功响应 (200 OK):** * **Type:** `Array` ```json [ { "id": 1, "step": "create_shots", "name": "default_v1", "prompt": "这是一个用于生成分镜的提示词...", "created_at": "2025-08-27T10:30:00Z", "updated_at": "2025-08-27T11:00:00Z" }, { "id": 2, "step": "create_shots", "name": "custom_v2", "prompt": "这是另一个用于生成分镜的提示词...", "created_at": "2025-08-27T10:35:00Z", "updated_at": "2025-08-27T11:05:00Z" } ] ``` * **错误响应:** * **500 Internal Server Error:** 查询失败 ```json { "detail": "根据step获取提示词失败: 具体错误信息" } ``` ### **3. 新增或修改提示词** 创建一个新的提示词,或者根据 `step` 和 `name` 更新一个已有的提示词。 * **Endpoint:** `POST /prompts` * **请求体 (Body):** | 字段名 | 类型 | 必填 | 描述 | | :--- | :--- | :--- | :--- | | `step` | String | 是 | 提示词使用的阶段 | | `name` | String | 是 | 提示词的名称 | | `prompt` | String | 是 | 提示词的具体内容 | **示例:** ```json { "step": "create_shots", "name": "default_v1", "prompt": "请根据以下剧本和素材描述,生成分镜列表..." } ``` * **成功响应 (200 OK):** * **Type:** `Object` ```json { "id": 1, "step": "create_shots", "name": "default_v1", "prompt": "请根据以下剧本和素材描述,生成分镜列表...", "created_at": "2025-08-27T10:30:00Z", "updated_at": "2025-08-27T11:00:00Z" } ``` ### **4. 删除提示词** 删除指定ID的提示词。 * **Endpoint:** `DELETE /prompts/{prompt_id}` * **路径参数 (Path):** `prompt_id` (Integer) - 要删除的提示词ID * **请求参数:** 无 * **成功响应 (200 OK):** * **Type:** `Object` ```json { "message": "提示词删除成功" } ``` * **错误响应:** * **404 Not Found:** 提示词不存在 ```json { "detail": "提示词不存在" } ``` * **500 Internal Server Error:** 删除失败 ```json { "detail": "删除提示词失败: 具体错误信息" } ``` ----- ## **模块二:项目与视频生成 (Project & Video Generation)** ### **1. 分页获取项目列表** 获取已创建项目的分页列表。 * **Endpoint:** `GET /projects` * **查询参数 (Query):** | 参数名 | 类型 | 必填 | 默认值 | 描述 | | :--- | :--- | :--- | :--- | :--- | | `page` | Integer | 否 | 1 | 页码 | | `size` | Integer | 否 | 20 | 每页数量 | * **成功响应 (200 OK):** * **Type:** `Object` ```json { "items": [ { "id": 1, "name": "我的第一个项目", "created_at": "2025-08-27T10:30:00Z", "updated_at": "2025-08-27T11:00:00Z" } ], "total": 1, "page": 1, "size": 20 } ``` ### **2. 新建项目** 创建一个新的空项目。 * **Endpoint:** `POST /projects` * **请求体 (Body):** | 字段名 | 类型 | 必填 | 描述 | | :--- | :--- | :--- | :--- | | `name` | String | 是 | 项目名称 | **示例:** ```json { "name": "我的第一个项目" } ``` * **成功响应 (201 Created):** * **Type:** `Object` ```json { "id": 1, "name": "我的第一个项目" } ``` ### **3. 删除项目** 软删除指定的项目(不会真正删除数据,只是标记为已删除)。 * **Endpoint:** `DELETE /projects/{project_id}` * **路径参数 (Path):** `project_id` (Integer) * **请求参数:** 无 * **成功响应 (200 OK):** * **Type:** `Object` ```json { "message": "项目 1 删除成功" } ``` * **错误响应:** * **404 Not Found:** 项目不存在 ```json { "detail": "项目 1 不存在" } ``` * **500 Internal Server Error:** 删除失败 ```json { "detail": "删除项目失败: 具体错误信息" } ``` ### **4. 生成剧本** 根据创意或剧本生成完整剧本和所需素材信息。这是新的工作流程的第一步。 > **重要更新:** 现在支持自定义提示词模板!前端可以让用户选择并微调提示词模板,然后传递给后端。 * **Endpoint:** `POST /projects/{project_id}/generate-script` * **路径参数 (Path):** `project_id` (Integer) * **请求体 (Body):** | 字段名 | 类型 | 必填 | 描述 | | :--- | :--- | :--- | :--- | | `script_or_idea` | String | 是 | 剧本或创意内容 | | `prompt_template` | String | 是 | 提示词模板,必须包含 `${script_or_idea}` 占位符 | **示例:** ```json { "script_or_idea": "一个关于小猫冒险的故事,小猫在森林里遇到了各种动物朋友", "prompt_template": "基于以下创意或剧本,生成一个完整的视频剧本和所需的素材列表。\n\n创意/剧本:${script_or_idea}\n\n请返回以下JSON格式的结果:\n{\n \"full_script\": \"完整的视频剧本内容,包含详细的场景描述、对话、动作等\",\n \"assets\": [\n {\n \"name\": \"素材名称\",\n \"description\": \"素材的详细描述\",\n \"tags\": [\"标签1\", \"标签2\", \"标签3\"]\n }\n ]\n}\n\n要求:\n1. 完整剧本应该包含影视风格和详细的整个完整故事(大概30~90秒)\n2. 素材列表应该包含制作这个视频所需的所有关键元素(人物、场景、道具、动物等视觉相关的元素)\n3. 每个素材都要有清晰的名称、描述和相关标签\n4. 确保所有素材的风格统一\n5. 确保返回的是有效的JSON格式,不要包含其他文字" } ``` * **模板变量说明:** - `${script_or_idea}`: 会被替换为用户输入的剧本或创意内容 * **成功响应 (200 OK):** * **Type:** `Object` ```json { "full_script": "第一场:森林入口\n小猫咪咪好奇地走进了神秘的森林...", "assets": [ { "id": 1, "name": "小猫咪咪", "description": "一只橘色的小猫,有着明亮的绿眼睛", "tags": ["动物", "主角", "小猫"], "original_url": null, "created_at": "2025-08-27T10:30:00Z", "updated_at": "2025-08-27T10:30:00Z" }, { "id": 2, "name": "神秘森林", "description": "一片茂密的森林,阳光透过树叶洒下", "tags": ["场景", "森林", "自然"], "original_url": null, "created_at": "2025-08-27T10:30:00Z", "updated_at": "2025-08-27T10:30:00Z" } ] } ``` * **错误响应:** * **400 Bad Request:** 提示词模板缺少必需变量 ```json { "detail": "提示词模板缺少必需的变量: script_or_idea。请确保模板中包含: ${script_or_idea}" } ``` ### **5. 更新素材图** 为素材更新图片URL。用户可以为生成的素材提供自定义的图片。 * **Endpoint:** `PUT /assets/{asset_id}/image` * **路径参数 (Path):** `asset_id` (Integer) * **请求体 (Body):** | 字段名 | 类型 | 必填 | 描述 | | :--- | :--- | :--- | :--- | | `image_url` | String | 是 | 素材图片URL | **示例:** ```json { "image_url": "https://example.com/my-custom-image.jpg" } ``` * **成功响应 (200 OK):** * **Type:** `Object` ```json { "message": "素材图片更新成功" } ``` ### **6. 生成单个素材图** 为指定的单个素材生成图片。前端提供素材ID,后端返回生成图片后的素材信息。 * **Endpoint:** `POST /assets/{asset_id}/generate-image` * **路径参数 (Path):** `asset_id` (Integer) - 要生成图片的素材ID * **请求参数:** 无 * **成功响应 (200 OK):** * **Type:** `Object` * **描述:** 返回生成图片后的素材信息 ```json { "asset": { "id": 1, "project_id": 1, "name": "小猫咪咪", "description": "一只橘色的小猫,有着明亮的绿眼睛", "tags": ["动物", "主角", "小猫"], "original_url": "https://your-qiniu-domain.com/generated_cat_123.png", "created_at": "2025-08-27T10:30:00Z", "updated_at": "2025-08-27T10:35:00Z" } } ``` * **错误响应:** * **404 Not Found:** 素材不存在 ```json { "detail": "素材 1 不存在" } ``` * **500 Internal Server Error:** 生成失败 ```json { "detail": "生成素材图失败: 具体错误信息" } ``` ### **7. 批量创建素材图** 为项目中所有没有图片的素材自动生成图片。如果所有素材都已有图片,则可以跳过此步骤。 * **Endpoint:** `POST /projects/{project_id}/generate-asset-images` * **路径参数 (Path):** `project_id` (Integer) * **请求参数:** 无 * **成功响应 (200 OK):** * **Type:** `Array` * **描述:** 返回项目的所有素材信息(包括新生成图片的素材) ```json [ { "id": 1, "name": "小猫咪咪", "description": "一只橘色的小猫,有着明亮的绿眼睛", "tags": ["动物", "主角", "小猫"], "original_url": "https://your-qiniu-domain.com/generated_cat_123.png", "created_at": "2025-08-27T10:30:00Z", "updated_at": "2025-08-27T10:35:00Z" }, { "id": 2, "name": "神秘森林", "description": "一片茂密的森林,阳光透过树叶洒下", "tags": ["场景", "森林", "自然"], "original_url": "https://your-qiniu-domain.com/generated_forest_456.png", "created_at": "2025-08-27T10:30:00Z", "updated_at": "2025-08-27T10:35:00Z" } ] ``` ### **8. 关联素材** [已弃用 - 保留兼容性] > **注意:** 此接口已被新的工作流程替代,但保留用于兼容性。新的推荐流程是:生成剧本 → 更新/生成素材图 → 生成分镜。 * **Endpoint:** `POST /projects/{project_id}/assets` * **路径参数 (Path):** `project_id` (Integer) * **请求体 (Body):** | 字段名 | 类型 | 必填 | 描述 | | :--- | :--- | :--- | :--- | | `asset_urls` | Array\ | 是 | **已上传到七牛云的**素材URL数组 | **示例:** ```json { "asset_urls": [ "https://your-qiniu-domain.com/image1.jpg", "https://your-qiniu-domain.com/image2.png" ] } ``` * **成功响应 (200 OK):** * **Type:** `Array` * **描述:** 返回分析和入库后的素材信息列表。 ```json [ { "id": 1, "name": "海滩上的女孩", "description": "一个穿着白色连衣裙的女孩在夕阳下的海滩上奔跑。", "tags": ["海滩", "女孩", "夕阳", "连衣裙"] } ] ``` ### **9. 删除素材** 删除指定ID的素材。 * **Endpoint:** `DELETE /assets/{asset_id}` * **路径参数 (Path):** `asset_id` (Integer) - 要删除的素材ID * **请求参数:** 无 * **成功响应 (200 OK):** * **Type:** `Object` ```json { "message": "素材 1 删除成功" } ``` * **错误响应:** * **404 Not Found:** 素材不存在 ```json { "detail": "素材 1 不存在" } ``` * **500 Internal Server Error:** 删除失败 ```json { "detail": "删除素材失败: 具体错误信息" } ``` ### **10. 生成分镜** 为指定项目提交剧本和提示词,生成一系列结构化的分镜描述。 > **重要更新:** 现在支持自定义提示词模板!前端可以让用户选择并微调提示词模板,然后传递给后端。 * **Endpoint:** `POST /projects/{project_id}/generate-storyboards` * **路径参数 (Path):** `project_id` (Integer) * **请求体 (Body):** | 字段名 | 类型 | 必填 | 描述 | | :--- | :--- | :--- | :--- | | `script` | String | 是 | 用户输入的剧本内容 | | `prompt_template` | String | 是 | 提示词模板,必须包含 `${materials_description}` 和 `${script}` 占位符 | **示例:** ```json { "script": "清晨,女孩在海边醒来...", "prompt_template": "请根据以下剧本和素材描述,生成分镜列表。\n\n可用素材描述:\n${materials_description}\n\n用户剧本:\n${script}\n\n请根据以上信息生成分镜,返回JSON数组格式,每个分镜包含:\n- frame_prompt: 首帧图片生成提示词\n- frame_asset_ids: 用于生成首帧的素材ID数组\n- shot_prompt: 分镜动态内容提示词\n\n请确保返回的是有效的JSON数组格式,不要包含其他文字。" } ``` * **模板变量说明:** - `${materials_description}`: 会被替换为项目中所有素材的描述信息 - `${script}`: 会被替换为用户输入的剧本内容 * **成功响应 (200 OK):** * **Type:** `Array` ```json [ { "id": 1, "frame_prompt": "清晨金色的阳光下...", "frame_asset_ids": [1], "shot_prompt": "镜头特写女孩的面部..." } ] ``` * **错误响应:** * **400 Bad Request:** 提示词模板缺少必需变量 ```json { "detail": "提示词模板缺少必需的变量: materials_description, script。请确保模板中包含: ${materials_description}, ${script}" } ``` ### **11. 生成分镜首帧图** 为一个已生成的分镜,生成其首帧静态图。 * **Endpoint:** `POST /storyboards/{storyboard_id}/generate-frame` * **路径参数 (Path):** `storyboard_id` (Integer) * **请求体 (Body):** | 字段名 | 类型 | 必填 | 描述 | | :--- | :--- | :--- | :--- | | `frame_prompt` | String | 是 | 用于生成首帧图的提示词(可编辑) | | `frame_asset_ids` | Array\ | 是 | 用于生成首帧图的素材ID数组(可编辑) | **示例:** ```json { "frame_prompt": "日出时分,一个女孩在沙滩上醒来...", "frame_asset_ids": [1] } ``` * **成功响应 (200 OK):** * **Type:** `Object` ```json { "frame_image_url": "https://your-qiniu-domain.com/generated_image_123.png" } ``` ### **12. 首帧图指导修改** 使用指导图修改分镜的首帧图。用户可以在白板上画草图来指导首帧图的生成。 * **Endpoint:** `POST /storyboards/{storyboard_id}/guide-frame` * **路径参数 (Path):** `storyboard_id` (Integer) * **请求体 (Body):** | 字段名 | 类型 | 必填 | 描述 | | :--- | :--- | :--- | :--- | | `guide_image_url` | String | 是 | 指导图URL(用户在白板上画的动作或位置指导草图) | **示例:** ```json { "guide_image_url": "https://example.com/my-guide-sketch.jpg" } ``` * **成功响应 (200 OK):** * **Type:** `Object` ```json { "frame_image_url": "https://your-qiniu-domain.com/guided_frame_789.png" } ``` ### **13. 生成分镜视频** 为一个已生成首帧图的分镜,生成其动态视频。 * **Endpoint:** `POST /storyboards/{storyboard_id}/generate-video` * **路径参数 (Path):** `storyboard_id` (Integer) * **请求体 (Body):** | 字段名 | 类型 | 必填 | 描述 | | :--- | :--- | :--- | :--- | | `shot_prompt` | String | 是 | 用于生成分镜视频的动态描述提示词(可编辑) | **示例:** ```json { "shot_prompt": "镜头从女孩的特写平滑地拉远..." } ``` * **成功响应 (200 OK):** * **Type:** `Object` ```json { "shot_video_url": "https://your-qiniu-domain.com/generated_video_456.mp4" } ``` ### **14. 合成项目视频** 将项目中所有分镜的视频合并成一个完整的项目视频。 * **Endpoint:** `POST /projects/{project_id}/compose-video` * **路径参数 (Path):** `project_id` (Integer) * **请求参数:** 无 * **成功响应 (200 OK):** * **Type:** `Object` ```json { "video_url": "https://your-qiniu-domain.com/project_final_video_789.mp4" } ``` * **错误响应:** * **400 Bad Request:** 项目不存在或分镜没有视频 ```json { "detail": "项目 1 的分镜都没有生成视频" } ``` * **500 Internal Server Error:** 合成失败 ```json { "detail": "合成项目视频失败: 具体错误信息" } ``` ### **15. 获取项目所有信息** 获取一个项目的完整信息,用于重新打开项目时恢复前端状态。 * **Endpoint:** `GET /projects/{project_id}` * **路径参数 (Path):** `project_id` (Integer) * **成功响应 (200 OK):** * **Type:** `Object` ```json { "project": { "id": 1, "name": "我的第一个项目", "script": "清晨,女孩在海边醒来...", "video_url": "https://your-qiniu-domain.com/project_final_video_789.mp4", "created_at": "2025-08-27T10:30:00Z", "updated_at": "2025-08-27T12:00:00Z" }, "assets": [ { "id": 1, "name": "海滩上的女孩", "description": "一个穿着白色连衣裙的女孩...", "tags": ["海滩", "女孩"], "original_url": "https://your-qiniu-domain.com/image1.jpg" } ], "storyboards": [ { "id": 1, "frame_prompt": "日出时分...", "frame_asset_ids": [1], "frame_image_url": "https://your-qiniu-domain.com/generated_image_123.png", "shot_prompt": "镜头从女孩的特写平滑地拉远...", "shot_video_url": "https://your-qiniu-domain.com/generated_video_456.mp4" } ] } ```