Merge branch '108' of https://github.com/HBAI-Ltd/Toonflow-app into 108
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 272 KiB After Width: | Height: | Size: 272 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 272 KiB After Width: | Height: | Size: 272 KiB |
@ -114,11 +114,20 @@
|
|||||||
| 审核 | 不需要 |
|
| 审核 | 不需要 |
|
||||||
|
|
||||||
**决策层行为:**
|
**决策层行为:**
|
||||||
向执行层派发阶段5分镜面板写入任务,收到确认后进入阶段6。
|
|
||||||
|
阶段4完成后、派发阶段5之前,根据模型参数 `多参` 决定写入模式:
|
||||||
|
|
||||||
|
| 模型参数 `多参` | 决策层操作 |
|
||||||
|
|----------------|-----------|
|
||||||
|
| 是 | 向用户询问:使用 **"纯文本多参模式"** 还是 **"分镜图辅助多参模式"**,等待用户确认后,将所选模式随任务指令一起派发给执行层 |
|
||||||
|
| 否 | 无需询问用户,直接以 **"首位帧模式"** 派发给执行层 |
|
||||||
|
|
||||||
|
收到执行层完成确认后进入阶段6。
|
||||||
|
|
||||||
**阶段特有约束:**
|
**阶段特有约束:**
|
||||||
- 必须严格依据阶段4分镜表逐行写入,行数与时长保持一致
|
- 必须严格依据阶段4分镜表逐行写入,行数与时长保持一致
|
||||||
- 分组累计时长不得超过 15 秒
|
- 分组累计时长不得超过 15 秒
|
||||||
|
- 派发执行层时必须在指令中明确携带写入模式(纯文本多参模式 / 分镜图辅助多参模式 / 首位帧模式)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@ -133,7 +133,7 @@ add_deriveAsset({
|
|||||||
|
|
||||||
### 执行流程
|
### 执行流程
|
||||||
|
|
||||||
1. 加载风格技法参考,获取 `script` 和 `assets`,并并且激活 `director_planning` ,所有规划内容以该文档为风格基准,冲突时以风格技法参考为准。
|
1. 加载风格技法参考,获取 `script` 和 `assets`,并并且激活 `director_planning_narrative` 以及 `director_planning_style`,所有规划内容以该文档为风格基准,冲突时以风格技法参考为准。
|
||||||
2. 按下方规范制定导演规划(创作规划),全文遵守「导演具象化原则」
|
2. 按下方规范制定导演规划(创作规划),全文遵守「导演具象化原则」
|
||||||
|
|
||||||
### 导演具象化原则(贯穿全文)
|
### 导演具象化原则(贯穿全文)
|
||||||
@ -163,7 +163,7 @@ add_deriveAsset({
|
|||||||
约束:
|
约束:
|
||||||
- 色调具体到色温范围或色彩倾向描述
|
- 色调具体到色温范围或色彩倾向描述
|
||||||
- 光影以「段落-光影方向」表格呈现,每段落指定光影基调方向
|
- 光影以「段落-光影方向」表格呈现,每段落指定光影基调方向
|
||||||
- 色温、光源角度、冷暖色调分配等具体技法参数以风格技法参考(`director_planning`)为准
|
- 色温、光源角度、冷暖色调分配等具体技法参数以风格技法参考(`director_planning_narrative` 以及 `director_planning_style`)为准
|
||||||
- **构图须说明叙事理由**,参考以下情绪-构图映射(按需选用):
|
- **构图须说明叙事理由**,参考以下情绪-构图映射(按需选用):
|
||||||
- 对称构图 → 秩序 / 压迫 / 庄重
|
- 对称构图 → 秩序 / 压迫 / 庄重
|
||||||
- 三分法偏侧留白 → 孤独 / 期待 / 未知
|
- 三分法偏侧留白 → 孤独 / 期待 / 未知
|
||||||
@ -210,7 +210,7 @@ add_deriveAsset({
|
|||||||
|
|
||||||
约束:
|
约束:
|
||||||
- 配乐按段落统一规划(不逐场),同段落内场景切换靠环境音变化过渡
|
- 配乐按段落统一规划(不逐场),同段落内场景切换靠环境音变化过渡
|
||||||
- 乐器选择、组合策略等具体技法以风格技法参考(`director_planning`)为准
|
- 乐器选择、组合策略等具体技法以风格技法参考(`director_planning_narrative` 以及 `director_planning_style`)为准
|
||||||
- 环境音具体到可感知声源("蝉鸣 / 溪水 / 市井叫卖 / 雨滴檐角"),每场标注 1~2 个核心环境音
|
- 环境音具体到可感知声源("蝉鸣 / 溪水 / 市井叫卖 / 雨滴檐角"),每场标注 1~2 个核心环境音
|
||||||
- 标注运用沉默手法的关键瞬间(关键情感瞬间优先考虑去掉配乐,只留环境音)
|
- 标注运用沉默手法的关键瞬间(关键情感瞬间优先考虑去掉配乐,只留环境音)
|
||||||
- 全片配乐覆盖率建议不超过 70%,留白段落与配乐段落形成呼吸感
|
- 全片配乐覆盖率建议不超过 70%,留白段落与配乐段落形成呼吸感
|
||||||
@ -249,7 +249,7 @@ add_deriveAsset({
|
|||||||
|
|
||||||
### 执行流程
|
### 执行流程
|
||||||
|
|
||||||
1. 获取 `script` 和 `assets`,并且激活 `director_storyboard_table` ,作为分镜设计的风格参考。
|
1. 获取 `script` 和 `assets`,并且激活 `director_storyboard_table_narrative` 以及 `director_storyboard_table_style` ,作为分镜设计的风格参考。
|
||||||
2. 按下方规则将剧本拆分为分镜,**每写一行前**回顾上一行状态,确保符合「视觉连续性铁律」后再填写当前行所有字段
|
2. 按下方规则将剧本拆分为分镜,**每写一行前**回顾上一行状态,确保符合「视觉连续性铁律」后再填写当前行所有字段
|
||||||
|
|
||||||
### 分镜拆分原则
|
### 分镜拆分原则
|
||||||
@ -408,7 +408,7 @@ add_deriveAsset({
|
|||||||
- **定场精简**:每个新场景定场最多 1~2 镜,禁止 3 镜以上的碎片化定场;能一镜完成定场+引入的不拆两镜
|
- **定场精简**:每个新场景定场最多 1~2 镜,禁止 3 镜以上的碎片化定场;能一镜完成定场+引入的不拆两镜
|
||||||
- **镜头合并自检**:完成全部分镜后,逐段检查是否有可合并的相邻镜头(同空间局部描述、纯装饰镜头、信息重复镜头),合并后重新编号
|
- **镜头合并自检**:完成全部分镜后,逐段检查是否有可合并的相邻镜头(同空间局部描述、纯装饰镜头、信息重复镜头),合并后重新编号
|
||||||
- **黄金 6 秒**:无台词镜头不超过 6s,定场/过渡类镜头尤其注意
|
- **黄金 6 秒**:无台词镜头不超过 6s,定场/过渡类镜头尤其注意
|
||||||
- **光影风格一致**:光影描述须与风格技法参考(`director_storyboard_table`)的光影规范保持一致
|
- **光影风格一致**:光影描述须与风格技法参考(`director_storyboard_table_narrative` 以及 `director_storyboard_table_style`)的光影规范保持一致
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -421,14 +421,34 @@ add_deriveAsset({
|
|||||||
| 读取剧本 | `get_flowData("script")` |
|
| 读取剧本 | `get_flowData("script")` |
|
||||||
| 读取分镜表 | `get_flowData("stoaryTable")` |
|
| 读取分镜表 | `get_flowData("stoaryTable")` |
|
||||||
|
|
||||||
|
### 写入模式
|
||||||
|
|
||||||
|
本阶段根据决策层派发指令中携带的模式信息,选择对应的写入策略:
|
||||||
|
|
||||||
|
| 模式 | 说明 | prompt | shouldGenerateImage | track 分组规则 |
|
||||||
|
|------|------|--------|---------------------|----------------|
|
||||||
|
| **纯文本多参模式** | 仅写入视频描述与资产绑定,不生成提示词和分镜图 | `''`(空字符串) | `false` | 同「分镜图辅助多参模式」,累计时长 ≤ 15s |
|
||||||
|
| **分镜图辅助多参模式** | 完整生成提示词并生成分镜图(当前默认行为) | 正常生成 | `true`(默认) | 累计时长 ≤ 15s |
|
||||||
|
| **首位帧模式** | 完整生成提示词,每条分镜独立一组 | 正常生成 | `true`(默认) | **不分组**,每行独立一组,按顺序递增 |
|
||||||
|
|
||||||
|
> 模式信息由决策层在派发指令中明确指定,执行层不自行判断。
|
||||||
|
|
||||||
### 执行流程
|
### 执行流程
|
||||||
|
|
||||||
1. 获取 `script` 、`stoaryTable`,并加载下方「分镜提示词 · 通用基础技法」与风格专属技法(激活 `director_storyboard`)作为提示词生成的全部参考依据,冲突时以风格专属技法为准
|
1. 获取 `script` 、`stoaryTable`,识别决策层指令中的**写入模式**(纯文本多参模式 / 分镜图辅助多参模式 / 首位帧模式)
|
||||||
2. 确定分组与时长规则:同组内分镜 `duration` 累计时长不得超过 15 秒,且每条 `duration` 必须严格使用 `stoaryTable` 对应行时长
|
2. **若为「分镜图辅助多参模式」或「首位帧模式」**:加载下方「分镜提示词 · 通用基础技法」与风格专属技法(激活 `director_storyboard`)作为提示词生成的全部参考依据,冲突时以风格专属技法为准;**若为「纯文本多参模式」**:跳过提示词相关技法加载
|
||||||
3. **人物空间位置预分析**:正式写入前,先通读全部分镜表,梳理同一人物在不同分镜中出现的画面位置与朝向,建立「人物-位置」连续性基准(如:角色A全片画面偏左、面朝右;角色B画面偏右、面朝左),后续每条 prompt 中涉及该人物时须保持一致
|
3. 确定分组(track)与时长规则:
|
||||||
4. **图像资产标注与正文绑定**:为每条分镜的 prompt 生成图像资产标注前缀,按 `associateAssetsIds` 的引用顺序,依次标注 `@图N 为xx{类型}`;**提示词正文中所有涉及该角色/场景/道具的位置,必须使用对应的 `@图N` 替代其名称**,建立参考图与画面描述的直接绑定(详见下方「prompt 图像资产标注规则」)
|
- **纯文本多参模式 / 分镜图辅助多参模式**:同组内分镜 `duration` 累计时长不得超过 15 秒
|
||||||
5. 严格按 `stoaryTable` 的分镜数据行逐行写入分镜面板(排除表头与分隔行),<storyboardItem prompt=提示词内容 track=分组 duration=视频推荐时间 associateAssetsIds="[该分镜所需的资产ID列表]" shouldGenerateImage="是否需要生成分镜图片 true/false, 默认为true" /></storyboardItem>
|
- **首位帧模式**:**不分组**,每条分镜独立一组,`track` 按顺序递增(第1行 track=1,第2行 track=2,以此类推)
|
||||||
6. 写入完成后,仅返回一句确认:`已完成分镜面板写入`
|
- 所有模式下,每条 `duration` 必须严格使用 `stoaryTable` 对应行时长
|
||||||
|
4. **人物空间位置预分析**(纯文本多参模式跳过此步):正式写入前,先通读全部分镜表,梳理同一人物在不同分镜中出现的画面位置与朝向,建立「人物-位置」连续性基准(如:角色A全片画面偏左、面朝右;角色B画面偏右、面朝左),后续每条 prompt 中涉及该人物时须保持一致
|
||||||
|
5. **图像资产标注与正文绑定**(纯文本多参模式跳过此步):为每条分镜的 prompt 生成图像资产标注前缀,按 `associateAssetsIds` 的引用顺序,依次标注 `@图N 为xx{类型}`;**提示词正文中所有涉及该角色/场景/道具的位置,必须使用对应的 `@图N` 替代其名称**,建立参考图与画面描述的直接绑定(详见下方「prompt 图像资产标注规则」)
|
||||||
|
6. **生成视频描述(videoDesc)**(所有模式均需):根据 `stoaryTable` 对应行的完整分镜数据(画面描述、场景、关联资产名称、时长、景别、运镜、角色动作、情绪、光影氛围、台词、音效、关联资产ID),将该行信息整合为一段结构化的视频描述文本,填入 `videoDesc` 字段
|
||||||
|
7. 严格按 `stoaryTable` 的分镜数据行逐行写入分镜面板(排除表头与分隔行),根据模式差异化输出:
|
||||||
|
- **纯文本多参模式**:`<storyboardItem videoDesc='视频描述' prompt='' track='分组' duration='视频推荐时间' associateAssetsIds="[该分镜所需的资产ID列表]" shouldGenerateImage="false" ></storyboardItem>`
|
||||||
|
- **分镜图辅助多参模式**:`<storyboardItem videoDesc='视频描述' prompt='提示词内容' track='分组' duration='视频推荐时间' associateAssetsIds="[该分镜所需的资产ID列表]" shouldGenerateImage="true" ></storyboardItem>`
|
||||||
|
- **首位帧模式**:`<storyboardItem videoDesc='视频描述' prompt='提示词内容' track='按顺序递增的独立分组' duration='视频推荐时间' associateAssetsIds="[该分镜所需的资产ID列表]" shouldGenerateImage="true" ></storyboardItem>`
|
||||||
|
8. 写入完成后,仅返回一句确认:`已完成分镜面板写入({当前模式名称})`
|
||||||
|
|
||||||
### 分镜提示词 · 通用基础技法
|
### 分镜提示词 · 通用基础技法
|
||||||
|
|
||||||
@ -664,14 +684,23 @@ Image [2]: @图2 — [外貌关键描述]
|
|||||||
### 约束
|
### 约束
|
||||||
|
|
||||||
- 前置条件:分镜表已构建完成且用户已确认
|
- 前置条件:分镜表已构建完成且用户已确认
|
||||||
- 你必须使用XML格式写入工作区分镜面板:<storyboardItem videoDesc='视频描述' prompt='提示词内容' track='分组' duration='视频推荐时间' associateAssetsIds="[该分镜所需的资产ID列表]" shouldGenerateImage="是否需要生成分镜图片 true/false, 默认为true"></storyboardItem>
|
- 你必须使用XML格式写入工作区分镜面板(具体参数值按当前模式填写,见上方执行流程第7步)
|
||||||
- 分组总时长约束:每个 `group` 的累计时长不得超过 15 秒
|
- **videoDesc 必填**(所有模式):每条分镜的 `videoDesc` 必须根据 `stoaryTable` 对应行的分镜数据生成,包含画面描述、场景、关联资产名称、时长、景别、运镜、角色动作、情绪、光影氛围、台词、音效、关联资产ID 等完整信息
|
||||||
- 行数一致性约束:分镜面板 `items` 数量必须与 `stoaryTable` 的分镜数据行数量完全一致(不包含表头与分隔行)
|
- 行数一致性约束:分镜面板 `items` 数量必须与 `stoaryTable` 的分镜数据行数量完全一致(不包含表头与分隔行)
|
||||||
- 时长一致性约束:分镜面板 `duration` 必须与 `stoaryTable` 对应行时长完全一致
|
- 时长一致性约束:分镜面板 `duration` 必须与 `stoaryTable` 对应行时长完全一致
|
||||||
- **人物位置连贯性**:每条 prompt 须通过上述「人物位置连贯性规则」校验,同场景内同一人物的画面位置与朝向描述前后一致
|
|
||||||
- **图像资产标注必填**:每条 prompt 必须以图像资产标注前缀开头,标注数量与 `associateAssetsIds` 数量一致、顺序一致;缺少标注或顺序不匹配视为格式错误
|
|
||||||
- 阶段边界:本阶段禁止调用 `generate_storyboard_images`
|
- 阶段边界:本阶段禁止调用 `generate_storyboard_images`
|
||||||
|
|
||||||
|
**模式差异化约束:**
|
||||||
|
|
||||||
|
| 约束项 | 纯文本多参模式 | 分镜图辅助多参模式 | 首位帧模式 |
|
||||||
|
|--------|---------------|-------------------|------------|
|
||||||
|
| `prompt` | `''`(空字符串) | 正常生成提示词 | 正常生成提示词 |
|
||||||
|
| `shouldGenerateImage` | `false` | `true` | `true` |
|
||||||
|
| `track` 分组 | 累计时长 ≤ 15s | 累计时长 ≤ 15s | 每行独立一组,按顺序递增 |
|
||||||
|
| 人物位置连贯性校验 | 不适用(无 prompt) | **必须**校验 | **必须**校验 |
|
||||||
|
| 图像资产标注 | 不适用(无 prompt) | **必填** | **必填** |
|
||||||
|
| 提示词技法加载 | 跳过 | 加载通用基础技法 + 风格专属技法 | 加载通用基础技法 + 风格专属技法 |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 六、分镜图生成
|
## 六、分镜图生成
|
||||||
|
|||||||
@ -172,11 +172,11 @@ description: >-
|
|||||||
| 审核项 | 标准 | 严重程度 |
|
| 审核项 | 标准 | 严重程度 |
|
||||||
|--------|------|----------|
|
|--------|------|----------|
|
||||||
| 关联资产正确 | associateAssetsIds 中的索引均在 assets 数组范围内;画面中可见的资产已关联 | 严重 |
|
| 关联资产正确 | associateAssetsIds 中的索引均在 assets 数组范围内;画面中可见的资产已关联 | 严重 |
|
||||||
|
| 父子资产选择正确 | 同一分镜按剧情优先选择衍生资产 ID;无匹配衍生时才使用主资产 ID,且二者不得同时出现 | 严重 |
|
||||||
| 剧本覆盖度 | 剧本中的全部场景和关键事件均有对应分镜,无遗漏 | 严重 |
|
| 剧本覆盖度 | 剧本中的全部场景和关键事件均有对应分镜,无遗漏 | 严重 |
|
||||||
| 拆分粒度 | 一个独立画面对应一条分镜;无过度合并或过度拆分 | 中等 |
|
| 拆分粒度 | 一个独立画面对应一条分镜;无过度合并或过度拆分 | 中等 |
|
||||||
| 镜头语言合理 | camera 字段使用标准景别术语;景别变化服务于叙事节奏 | 中等 |
|
| 镜头语言合理 | camera 字段使用标准景别术语;景别变化服务于叙事节奏 | 中等 |
|
||||||
| 时长合理性 | duration 与画面复杂度匹配;总时长与剧本预估时长基本吻合 | 中等 |
|
| 时长合理性 | duration 与画面复杂度匹配;总时长与剧本预估时长基本吻合 | 中等 |
|
||||||
| frameMode 选择 | 帧模式与分镜内容匹配(动作结果用 endFrame、对话为主用 linesSoundEffects、其余用 firstFrame) | 轻微 |
|
|
||||||
|
|
||||||
### 详细审核标准
|
### 详细审核标准
|
||||||
|
|
||||||
@ -200,6 +200,19 @@ description: >-
|
|||||||
- assets 只有 3 个,但分镜中出现 `associateAssetsIds: [1, 5]`
|
- assets 只有 3 个,但分镜中出现 `associateAssetsIds: [1, 5]`
|
||||||
- description 描述"凌玄手持青云令",但 associateAssetsIds 只有凌玄的索引,遗漏了青云令
|
- description 描述"凌玄手持青云令",但 associateAssetsIds 只有凌玄的索引,遗漏了青云令
|
||||||
|
|
||||||
|
#### 父子资产选择正确(严重)
|
||||||
|
|
||||||
|
验证方法:
|
||||||
|
1. 基于 assets 建立 `deriveId -> assetsId(父资产ID)` 映射
|
||||||
|
2. 遍历每条分镜 `associateAssetsIds`
|
||||||
|
3. 结合分镜 `description` 判断当前镜头是否明确为衍生状态(如破损、染血、夜景版、激活态等)
|
||||||
|
4. 若为衍生状态却只填父 `assetsId`,或同时出现 `deriveId` 与父 `assetsId`,均判定不通过
|
||||||
|
5. 若该镜头无匹配衍生状态,允许且应使用主 `assetsId`
|
||||||
|
|
||||||
|
不通过示例:
|
||||||
|
- 同一分镜 `associateAssetsIds: [1001, 101]`,其中 `1001` 为 `101` 的衍生资产
|
||||||
|
- description 明确“青云令裂痕发光(激活态)”,但 `associateAssetsIds` 仅填写主资产 `101`,未选择对应衍生资产 ID
|
||||||
|
|
||||||
#### 剧本覆盖度(严重)
|
#### 剧本覆盖度(严重)
|
||||||
|
|
||||||
验证方法:
|
验证方法:
|
||||||
|
|||||||
@ -25,23 +25,23 @@
|
|||||||
|
|
||||||
### 项目参数表
|
### 项目参数表
|
||||||
|
|
||||||
| 参数 | 说明 | 示例 |
|
| 参数 | 说明 |
|
||||||
|------|------|------|
|
|------|------|
|
||||||
| 集数 | 总共拆分为几集 | 7集 |
|
| 集数 | 总共拆分为几集 |
|
||||||
| 单集时长 | 每集目标时长(分钟) | 2.5分钟 |
|
| 单集时长 | 每集目标时长(分钟) |
|
||||||
| 原著范围 | 改编覆盖的章节范围 | 第1-35章 |
|
| 原著范围 | 改编覆盖的章节范围 |
|
||||||
| 章节ID列表 | 本次任务涉及的章节ID(用于事件检索) | [1,2,3,4,5] |
|
| 平台规格 | 画面比例(竖屏/横屏) |
|
||||||
| 平台规格 | 画面比例(竖屏/横屏) | 竖屏9:16 |
|
| 风格定位 | 短剧整体风格标签 |
|
||||||
| 风格定位 | 短剧整体风格标签 | 诡异修仙+心理悬疑 |
|
| 付费策略 | 前几集免费、从第几集设付费点 |
|
||||||
| 付费策略 | 前几集免费、从第几集设付费点 | 前2集免费,第3集起付费 |
|
|
||||||
|
|
||||||
### 初始化对话流程
|
### 初始化对话流程
|
||||||
|
|
||||||
1. 用户发起改编请求时,**必须主动询问用户**项目参数(不主动调用 `deepRetrieve`,除非用户要求回想之前的配置)
|
1. 用户发起改编请求时,**必须主动询问用户**项目参数(不主动调用 `deepRetrieve`,除非用户要求回想之前的配置)
|
||||||
2. 如果没有已确认的参数,**必须主动询问用户**:
|
2. 如果没有已确认的参数,**必须主动询问用户**:
|
||||||
- "请确认以下信息:计划拆分为几集?每集大约几分钟?覆盖原著哪些章节?"
|
- "请确认以下信息:计划拆分为几集?每集大约几分钟?覆盖原著哪些章节?"
|
||||||
3. 用户确认后,将参数作为**项目配置**保存,并在所有后续派发指令头部附带
|
3. 用户确认后,**必须校验章节范围**:调用 `get_novel_events` 获取实际可用的章节列表,若用户输入的章节ID中包含不存在的章节,**立即提醒用户**:"您输入的章节范围中包含不存在的章节({不存在的章节ID列表}),请重新确认原著范围和章节ID列表。",并等待用户修正后再继续
|
||||||
4. 如果用户只给出部分参数,对未给出的参数**逐一追问**,不可使用默认值跳过
|
4. 校验通过后,将参数作为**项目配置**保存,并在所有后续派发指令头部附带
|
||||||
|
5. 如果用户只给出部分参数,对未给出的参数**逐一追问**,不可使用默认值跳过
|
||||||
|
|
||||||
### 参数传递模板
|
### 参数传递模板
|
||||||
|
|
||||||
@ -119,10 +119,11 @@
|
|||||||
|
|
||||||
**阶段3 不需要监督层审核**,由决策层直接循环调度执行层,执行流程如下:
|
**阶段3 不需要监督层审核**,由决策层直接循环调度执行层,执行流程如下:
|
||||||
|
|
||||||
1. **集数确认**:进入阶段3 时,决策层询问用户本次生成几集剧本(默认3集;若项目总集数不足3,则为项目集数)
|
1. **集数确认**:进入阶段3 时,决策层询问用户本次生成几集剧本(默认3集;单次轮询上限为**5集**,若用户要求超过5集,告知用户"循环调度次数过多可能导致上下文超载,建议每次不超过5集",并等待用户确认)
|
||||||
2. **循环派发**:用户确认集数后,决策层按集序逐集循环调用 `run_sub_agent_script`,每次只处理**一集**剧本
|
2. **循环派发**:用户确认集数后,决策层按集序逐集循环调用 `run_sub_agent_script`,每次只处理**一集**剧本
|
||||||
3. **静默执行**:循环过程中**不向用户发送任何中间通知**
|
3. **静默执行**:循环过程中**不向用户发送任何中间通知**
|
||||||
4. **完成通知**:全部集数处理完毕后,一次性通知用户
|
4. **完成通知**:全部集数处理完毕后,一次性通知用户
|
||||||
|
5. **续写询问**:若项目仍有剩余未生成的集数,完成通知时附带询问"是否继续生成后续剧本?",用户确认后再次进入集数确认流程(仍遵守单次上限5集的规则)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@ -9,17 +9,14 @@
|
|||||||
| 读取工作区 | `get_planData` |
|
| 读取工作区 | `get_planData` |
|
||||||
| 读取事件 | `get_novel_events(ids:number[])` |
|
| 读取事件 | `get_novel_events(ids:number[])` |
|
||||||
| 读取原文 | `get_novel_text` |
|
| 读取原文 | `get_novel_text` |
|
||||||
| 写入剧本 | `insert_script_to_sqlite` |
|
| 读取剧本内容 | `get_script_content(ids:string[])` |
|
||||||
|
|
||||||
## 执行流程
|
## 执行流程
|
||||||
|
|
||||||
1. 调用 `get_planData` 获取骨架与改编策略
|
1. 调用 `get_planData` 获取骨架与改编策略;若存在上一集剧本id,调用 `get_script_content(ids)` 获取上一集剧本内容,用于衔接剧情与角色状态,调用 `get_novel_text` 获取对应章节原文,调用 `get_novel_events(ids)` 获取事件表
|
||||||
2. 从骨架中提取本集信息:覆盖章节、戏剧功能、场景核心、删减决策、集末钩子
|
2. 从骨架中**仅提取当前任务集**的信息:覆盖章节、戏剧功能、场景核心、删减决策、集末钩子。**忽略其他已完成或未分配的集**
|
||||||
3. 调用 `get_novel_text` 获取对应章节原文,调用 `get_novel_events(ids)` 获取事件表
|
3. **阐述思路**(200-300字):场景组织方式、重点情绪与冲突、节奏把控思路
|
||||||
4. 按下方【输出格式规范】编写剧本:文件头 → 剧情梗概 → 出场角色表 → 场景表 → 剧本正文
|
4. 按下方【输出格式规范】**只编写当前任务集的剧本**(文件头 → 剧情梗概 → 出场角色表 → 场景表 → 剧本正文),按照XML格式写入工作区`<script><item name="剧本名称">剧本内容</item></script>`,**只写入当前任务集的剧本,不重复写入之前已完成的集**,改编策略不写入XML中
|
||||||
5. **阐述思路**(200-300字):场景组织方式、重点情绪与冲突、节奏把控思路
|
5. 返回简短确认,如:"第X集剧本已写入,请在工作台查看。"
|
||||||
6. 调用 `insert_script_to_sqlite` 写入
|
|
||||||
7. 返回简短确认,如:"第X集剧本已写入,请在工作台查看。"
|
|
||||||
|
|
||||||
## 约束
|
## 约束
|
||||||
|
|
||||||
@ -30,7 +27,7 @@
|
|||||||
|
|
||||||
## 注意事项
|
## 注意事项
|
||||||
|
|
||||||
- 执行前先调用 `get_planData` 确认工作区状态;已有内容在其基础上修改,除非指令要求重写
|
- **每次只编写当前任务集的剧本,不得将之前已完成的集重新输出或写入**
|
||||||
- 只执行剧本编写,不越权执行其他阶段
|
- 只执行剧本编写,不越权执行其他阶段
|
||||||
- 不处理剧本删除请求,收到时提醒:`请在道具本管理中手动删除剧本`
|
- 不处理剧本删除请求,收到时提醒:`请在道具本管理中手动删除剧本`
|
||||||
- 完成写入后返回一句确认即可,不复述内容;返回后本次任务终止
|
- 完成写入后返回一句确认即可,不复述内容;返回后本次任务终止
|
||||||
@ -64,41 +61,9 @@
|
|||||||
---
|
---
|
||||||
```
|
```
|
||||||
|
|
||||||
### 三、本集出场角色与定妆信息
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
## 出场角色
|
|
||||||
|
|
||||||
| 角色 | 角色说明 | 定妆描述 |
|
### 三、剧本内容结构
|
||||||
|------|----------|---------|
|
|
||||||
| {角色名} | {性格、身份、角色功能} | {服装、发型、妆容等视觉特征} |
|
|
||||||
| ... | ... | ... |
|
|
||||||
|
|
||||||
---
|
|
||||||
```
|
|
||||||
|
|
||||||
- 只列出本集出场的角色
|
|
||||||
- 角色说明应涵盖人物身份和在本集的关键作用
|
|
||||||
- 定妆信息需与美术资产包保持一致,避免后续修改时重复描述
|
|
||||||
|
|
||||||
### 四、场景说明
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
## 场景表
|
|
||||||
|
|
||||||
| 场景 | 时间 | 氛围 | 说明 |
|
|
||||||
|------|------|------|------|
|
|
||||||
| {场景名} | {时间设定} | {整体氛围/光线} | {视觉风格要点} |
|
|
||||||
| ... | ... | ... | ... |
|
|
||||||
|
|
||||||
---
|
|
||||||
```
|
|
||||||
|
|
||||||
- 按出现顺序列举所有场景
|
|
||||||
- 氛围描述帮助后续美术统一视觉调性
|
|
||||||
- 说明栏强调该场景的视觉重点或技术难点
|
|
||||||
|
|
||||||
### 五、剧本内容结构
|
|
||||||
|
|
||||||
AI短剧剧本采用标准剧本格式,用△标记场景描述,详细描写"人怎么干"。
|
AI短剧剧本采用标准剧本格式,用△标记场景描述,详细描写"人怎么干"。
|
||||||
|
|
||||||
@ -171,7 +136,7 @@ OS({人物名},{情绪}):
|
|||||||
**转场**
|
**转场**
|
||||||
- 场景之间用 `---` 分隔
|
- 场景之间用 `---` 分隔
|
||||||
|
|
||||||
### 六、画面描述规范
|
### 四、画面描述规范
|
||||||
|
|
||||||
画面描述必须足够具体,可直接用于 AI 视频生成提示词:
|
画面描述必须足够具体,可直接用于 AI 视频生成提示词:
|
||||||
|
|
||||||
@ -185,13 +150,13 @@ OS({人物名},{情绪}):
|
|||||||
- 避免横向全景(竖屏无法展示)
|
- 避免横向全景(竖屏无法展示)
|
||||||
- 上下构图利用竖屏优势(如俯视/仰视)
|
- 上下构图利用竖屏优势(如俯视/仰视)
|
||||||
|
|
||||||
### 七、台词规范
|
### 五、台词规范
|
||||||
|
|
||||||
- 对话标注格式:`{人物名}:{台词}`
|
- 对话标注格式:`{人物名}:{台词}`
|
||||||
- 表演指示关键词:平静、愤怒、崩溃、冷笑、低沉、颤抖、用力、轻声等
|
- 表演指示关键词:平静、愤怒、崩溃、冷笑、低沉、颤抖、用力、轻声等
|
||||||
- 单句台词不超过20字(竖屏短视频观众阅读速度)
|
- 单句台词不超过20字(竖屏短视频观众阅读速度)
|
||||||
|
|
||||||
### 八、转场标注
|
### 六、转场标注
|
||||||
|
|
||||||
节拍之间必须标注转场方式:
|
节拍之间必须标注转场方式:
|
||||||
|
|
||||||
@ -203,14 +168,14 @@ OS({人物名},{情绪}):
|
|||||||
| `[闪黑]` | 黑屏过渡 | 意识丧失、恐怖预兆 |
|
| `[闪黑]` | 黑屏过渡 | 意识丧失、恐怖预兆 |
|
||||||
| `[叠化]` | 画面重叠过渡 | 蒙太奇、记忆闪回 |
|
| `[叠化]` | 画面重叠过渡 | 蒙太奇、记忆闪回 |
|
||||||
|
|
||||||
### 九、时长控制
|
### 七、时长控制
|
||||||
|
|
||||||
- 目标:按项目配置的单集时长 ±10秒
|
- 目标:按项目配置的单集时长 ±10秒
|
||||||
- 台词量:按 150字/分钟 语速计算
|
- 台词量:按 150字/分钟 语速计算
|
||||||
- 每个场景段落20-60秒
|
- 每个场景段落20-60秒
|
||||||
- 纯画面段落(无台词)最长15秒
|
- 纯画面段落(无台词)最长15秒
|
||||||
|
|
||||||
### 十、自查清单(仅供内部校验,不输出到剧本中)
|
### 八、自查清单(仅供内部校验,不输出到剧本中)
|
||||||
|
|
||||||
编写完成后,按以下清单逐项自查,发现问题直接修正后再写入,无需将清单本身输出:
|
编写完成后,按以下清单逐项自查,发现问题直接修正后再写入,无需将清单本身输出:
|
||||||
|
|
||||||
@ -234,4 +199,4 @@ OS({人物名},{情绪}):
|
|||||||
- **自查清单**:不输出自查清单本身
|
- **自查清单**:不输出自查清单本身
|
||||||
- **任何元信息**:不输出字数统计、场景数量统计、创作说明等非剧本内容
|
- **任何元信息**:不输出字数统计、场景数量统计、创作说明等非剧本内容
|
||||||
|
|
||||||
剧本输出只包含:文件头 → 剧情梗概 → 出场角色表 → 场景表 → 剧本正文(△描述 + 台词 + OS/V.S.)
|
剧本输出只包含:文件头 → 剧情梗概→ 剧本正文(△描述 + 台词 + OS/V.S.)
|
||||||
@ -105,18 +105,33 @@
|
|||||||
**付费点:** {无 / 有+类型}
|
**付费点:** {无 / 有+类型}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 模式B:总览表 + 关键集展开(>20集)
|
#### 模式B:总览表 + 指定集展开(>20集)
|
||||||
|
|
||||||
**第一步**——分集总览表,每集一行:
|
> **⚠️ 核心原则:表格行数 = 项目配置总集数,一行就是一集,一集就是一行。**
|
||||||
|
|
||||||
|
**第一步**——分集总览表:
|
||||||
|
|
||||||
| 集 | 集标题 | 章节范围 | 戏剧功能 | 场景核心 | 章节处理 | 集末钩子 | 付费点 |
|
| 集 | 集标题 | 章节范围 | 戏剧功能 | 场景核心 | 章节处理 | 集末钩子 | 付费点 |
|
||||||
|----|--------|----------|----------|----------|----------|----------|--------|
|
|----|--------|----------|----------|----------|----------|----------|--------|
|
||||||
|
| 1 | {标题} | 第X-Y章 | {功能} | {一句话} | `X保留/Y压缩/Z删` | {钩子} | {无/有} |
|
||||||
|
| 2 | {标题} | 第X-Y章 | {功能} | {一句话} | `X保留/Y压缩/Z删` | {钩子} | {无/有} |
|
||||||
|
| 3 | {标题} | 第X-Y章 | {功能} | {一句话} | `X保留/Y压缩/Z删` | {钩子} | {无/有} |
|
||||||
|
| … | (每集一行,不跳号) | … | … | … | … | … | … |
|
||||||
|
| N | {标题} | 第X-Y章 | {功能} | {一句话} | `X保留/Y压缩/Z删` | {钩子} | {无/有} |
|
||||||
|
|
||||||
> 「章节处理」列:`章号:处理` 用 `/` 分隔,如 `3保留/4压缩/5删`;未提及默认保留。
|
**硬性规则(违反任何一条即为不合格输出):**
|
||||||
|
|
||||||
|
1. **行数 = 总集数**:表格行数必须恰好等于【项目配置】中的总集数 N(第1集→第N集),不多不少。
|
||||||
|
2. **禁止"单元/分组"概念**:不得出现"内容单元""叙事体""映射表"等中间抽象层;每一行直接就是最终的一集。
|
||||||
|
3. **禁止范围行**:不得出现一行代表多集的写法(如"第X-Y集");每行「集」列只能是单个整数。
|
||||||
|
4. **禁止事后补充映射**:不得在表格之外附加"精确映射表""拆分集说明"等补丁来凑集数。
|
||||||
|
5. **章节可复用**:当一章内容丰富需要拆成多集时,多行的「章节范围」可以指向同一章,在「章节处理」列注明该集使用该章的哪个片段(如 `X前半保留/X后半压缩`)。
|
||||||
|
6. **「章节处理」列**:`章号:处理` 用 `/` 分隔,如 `3保留/4压缩/5删`;未提及默认保留。
|
||||||
|
|
||||||
**第二步**——对以下关键集用模式A模板展开详情:
|
**第二步**——对以下关键集用模式A模板展开详情:
|
||||||
- 🔴 幕末转折集、付费卡点集、高潮集
|
- 🔴 幕末转折集、付费卡点集、高潮集
|
||||||
- 🟡 首集
|
- 🟡 首集
|
||||||
|
- 🟢 用户在【项目配置】或指令中额外指定的集数
|
||||||
|
|
||||||
### 全局删减决策记录
|
### 全局删减决策记录
|
||||||
|
|
||||||
@ -136,6 +151,7 @@
|
|||||||
### 自查清单(生成后内部校验,不输出)
|
### 自查清单(生成后内部校验,不输出)
|
||||||
|
|
||||||
- [ ] 总集数、每集时长符合【项目配置】
|
- [ ] 总集数、每集时长符合【项目配置】
|
||||||
|
- [ ] **模式B表格行数 = 项目配置总集数 N**(恰好 N 行,无单元/映射/补丁)
|
||||||
- [ ] 前2集无付费点
|
- [ ] 前2集无付费点
|
||||||
- [ ] 每集有集末钩子,三幕均有幕末转折
|
- [ ] 每集有集末钩子,三幕均有幕末转折
|
||||||
- [ ] 删减记录与分集中的删减一致
|
- [ ] 删减记录与分集中的删减一致
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 743 KiB After Width: | Height: | Size: 743 KiB |
@ -354,7 +354,412 @@ description: 专注于从剧本内容中提取所使用的资产(角色、场
|
|||||||
{
|
{
|
||||||
name: "视频提示词生成",
|
name: "视频提示词生成",
|
||||||
type: "videoPromptGeneration",
|
type: "videoPromptGeneration",
|
||||||
data: "根据以下提示词生成一个视频提示词",
|
data: `# 视频提示词生成 Skill
|
||||||
|
|
||||||
|
你是**视频提示词生成 Agent**,专门负责根据指定的 AI 视频模型,读取分镜信息并输出该模型对应格式的视频提示词。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 输入格式
|
||||||
|
|
||||||
|
### 1. 模型名称(必选)
|
||||||
|
|
||||||
|
支持以下模型(不区分大小写,支持别名匹配):
|
||||||
|
|
||||||
|
| 模型标识 | 别名 | 说明 |
|
||||||
|
|---------|------|------|
|
||||||
|
| \`KlingOmni\` | 可灵、kling、klingomni | 快手 · 多模态图文融合 |
|
||||||
|
| \`Seedance1.5\` | seedance1.5pro、seedance 1.5、即梦1.5 | 字节 · 纯文本五维度 |
|
||||||
|
| \`Seedance2.0\` | seedance2、seedance 2.0、即梦2.0 | 字节 · XML 结构化12维 |
|
||||||
|
|
||||||
|
### 2. 资产信息
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
资产信息[id, type, name], [id, type, name], ...
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
- \`id\`:资产唯一标识(如 \`A001\`)
|
||||||
|
- \`type\`:资产类型,取值 \`character\`(角色)/ \`scene\`(场景)/ \`prop\`(道具)
|
||||||
|
- \`name\`:资产名称(如 \`沈辞\`、\`城楼\`、\`长剑\`)
|
||||||
|
|
||||||
|
### 3. 分镜信息
|
||||||
|
|
||||||
|
分镜以 \`<storyboardItem>\` XML 标签列表的形式传入,每条分镜结构如下:
|
||||||
|
|
||||||
|
\`\`\`xml
|
||||||
|
<storyboardItem
|
||||||
|
videoDesc='(画面描述、场景、关联资产名称、时长、景别、运镜、角色动作、情绪、光影氛围、台词、音效、关联资产ID)'
|
||||||
|
prompt='待生成'
|
||||||
|
track='分组'
|
||||||
|
duration='视频推荐时间'
|
||||||
|
associateAssetsIds="[该分镜所需的资产ID列表]"
|
||||||
|
shouldGenerateImage="true"
|
||||||
|
></storyboardItem>
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
#### 输入字段说明
|
||||||
|
|
||||||
|
| 属性 | 说明 | 来源 |
|
||||||
|
|------|------|------|
|
||||||
|
| \`videoDesc\` | **核心输入**:分镜的结构化画面描述,包含画面描述、场景、关联资产名称、时长、景别、运镜、角色动作、情绪、光影氛围、台词、音效、关联资产ID | 用户/上游系统填写 |
|
||||||
|
| \`prompt\` | **已有字段**:上游生成的分镜图提示词,作为辅助参考上下文,**不修改** | 上游系统已填写 |
|
||||||
|
| \`track\` | 分镜分组标识 | 用户/上游系统填写 |
|
||||||
|
| \`duration\` | 视频推荐时长(秒) | 用户/上游系统填写 |
|
||||||
|
| \`associateAssetsIds\` | 该分镜关联的资产ID列表 | 用户/上游系统填写 |
|
||||||
|
| \`shouldGenerateImage\` | 是否需要生成分镜图片,默认 \`true\` | 用户/上游系统填写 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 任务目标
|
||||||
|
|
||||||
|
读取所有 \`<storyboardItem>\` 的属性,结合资产信息,根据指定模型的提示词格式,将全部分镜整合为一个完整的视频提示词。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 输出格式
|
||||||
|
|
||||||
|
将所有分镜整合为**一个完整的视频提示词**输出(非逐条独立):
|
||||||
|
|
||||||
|
| 模型 | 整合方式 |
|
||||||
|
|------|----------|
|
||||||
|
| **KlingOmni** | \`[References]\` 汇总所有 \`@图N \` 引用;\`[Instruction]\` 按时间顺序描述完整叙事 |
|
||||||
|
| **Seedance 1.5** | 五维度按时间轴连续编排(\`[Motion]\` 0s → 总时长),单镜头连贯 |
|
||||||
|
| **Seedance 2.0** | \`生成一个由以下 N 个分镜组成的视频\`,每条对应 \`分镜N<duration-ms>\` 段落 |
|
||||||
|
|
||||||
|
- 仅输出视频提示词文本,不输出 XML 标签,不附加解释
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## videoDesc 解析规则
|
||||||
|
|
||||||
|
从 \`videoDesc\` 括号内按顿号分隔提取以下结构化字段:
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
({画面描述}、{场景}、{关联资产名称}、{时长}、{景别}、{运镜}、{角色动作}、{情绪}、{光影氛围}、{台词}、{音效}、{关联资产ID})
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
| 序号 | 字段 | 用途 | 示例 |
|
||||||
|
|------|------|------|------|
|
||||||
|
| 1 | 画面描述 | prompt 的叙事主干 | 沈辞独立城楼远眺苍茫大地 |
|
||||||
|
| 2 | 场景 | 匹配场景资产 | 城楼 |
|
||||||
|
| 3 | 关联资产名称 | 匹配角色/道具资产 | 沈辞/城楼 |
|
||||||
|
| 4 | 时长 | 控制时长参数 | 4s |
|
||||||
|
| 5 | 景别 | 控制镜头景别 | 全景 |
|
||||||
|
| 6 | 运镜 | 控制运镜方式 | 静止 |
|
||||||
|
| 7 | 角色动作 | prompt 动作描写 | 负手而立衣袂随风飘扬 |
|
||||||
|
| 8 | 情绪 | prompt 情绪氛围 | 坚定决绝 |
|
||||||
|
| 9 | 光影氛围 | prompt 光影描写 | 黄昏冷调侧逆光 |
|
||||||
|
| 10 | 台词 | prompt 台词/音频段 | 无台词 / 具体台词内容 |
|
||||||
|
| 11 | 音效 | prompt 音效描写 | 风声衣袂声 |
|
||||||
|
| 12 | 关联资产ID | 用于资产ID↔角色标签映射 | A001/A002 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 资产引用编号规则
|
||||||
|
|
||||||
|
所有模型统一使用 \`@图N \` 格式引用资产和分镜图,编号按输入顺序连续递增:
|
||||||
|
|
||||||
|
1. **资产**:按资产信息中 \`[id, type, name]\` 的出现顺序,从 \`@图1 \` 开始编号(不区分 character / scene / prop)
|
||||||
|
2. **分镜图**:每条 \`<storyboardItem>\` 对应一张分镜图,编号接续资产之后
|
||||||
|
|
||||||
|
#### 示例
|
||||||
|
|
||||||
|
输入 3 个资产 + 2 条分镜:
|
||||||
|
\`\`\`
|
||||||
|
资产信息[A001, character, 沈辞], [A002, character, 苏锦], [A003, scene, 城楼]
|
||||||
|
\`\`\`
|
||||||
|
\`\`\`xml
|
||||||
|
<storyboardItem ...> <!-- 分镜1 -->
|
||||||
|
<storyboardItem ...> <!-- 分镜2 -->
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
编号结果:
|
||||||
|
|
||||||
|
| 输入项 | 引用标签 | 说明 |
|
||||||
|
|--------|----------|------|
|
||||||
|
| [A001, character, 沈辞] | \`@图1 \` | 角色·沈辞 参考图 |
|
||||||
|
| [A002, character, 苏锦] | \`@图2 \` | 角色·苏锦 参考图 |
|
||||||
|
| [A003, scene, 城楼] | \`@图3 \` | 场景·城楼 参考图 |
|
||||||
|
| storyboardItem 第1条 | \`@图4 \` | 分镜图1 |
|
||||||
|
| storyboardItem 第2条 | \`@图5 \` | 分镜图2 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 模型提示词生成规则
|
||||||
|
|
||||||
|
### 一、KlingOmni(可灵)
|
||||||
|
|
||||||
|
#### 核心原则
|
||||||
|
- MVL 多模态融合:自然语言 + 图像引用在同一语义空间
|
||||||
|
- 分镜图序列负责动作/时间轴/构图,场景参考图负责环境一致性
|
||||||
|
- 所有资产和分镜图统一用 \`@图N \` 引用
|
||||||
|
|
||||||
|
#### prompt 生成模板
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
[References]
|
||||||
|
@图1 : [{角色A名}参考图]
|
||||||
|
@图2 : [{角色B名}参考图]
|
||||||
|
@图3 : [{场景名}参考图]
|
||||||
|
@图4 : [分镜图1]
|
||||||
|
|
||||||
|
[Instruction]
|
||||||
|
Based on the storyboard @图4 :
|
||||||
|
@图1 {动作/状态描述(英文)},
|
||||||
|
@图2 {动作/状态描述(英文)},
|
||||||
|
set in the {场景描述(英文)} of @图3 ,
|
||||||
|
{镜头/运镜描述(英文)},
|
||||||
|
{情感基调(英文)}.
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
#### 生成约束
|
||||||
|
1. **Instruction 必须用英文**
|
||||||
|
2. **角色动作**从 videoDesc 的「角色动作」字段提取,翻译为简洁英文动作描述
|
||||||
|
3. **镜头风格**使用标准标签:\`cinematic\` / \`wide-angle\` / \`close-up\` / \`slow motion\` / \`surround shooting\` / \`handheld\`
|
||||||
|
4. **空间关系**使用标准动词:\`wearing\` / \`holding\` / \`standing on\` / \`following behind\` / \`sitting in\`
|
||||||
|
5. 单条分镜对应单个 \`@图N \`,不做多帧跨镜描述
|
||||||
|
6. 无需描述角色外观(由参考图负责)
|
||||||
|
7. 无时长标注(由模型推断)
|
||||||
|
|
||||||
|
#### KlingOmni 完整示例
|
||||||
|
|
||||||
|
输入:
|
||||||
|
\`\`\`
|
||||||
|
模型:KlingOmni
|
||||||
|
资产信息[A001, character, 沈辞], [A002, character, 苏锦], [A003, scene, 城楼]
|
||||||
|
\`\`\`
|
||||||
|
\`\`\`xml
|
||||||
|
<storyboardItem videoDesc='(沈辞独立城楼远眺苍茫大地、城楼、沈辞/城楼、4s、全景、静止、负手而立衣袂随风飘扬、坚定决绝、黄昏冷调侧逆光、无台词、风声衣袂声、A001/A003)' prompt='全景,平视略仰,城楼之上,沈辞负手而立,衣袂飘扬,黄昏冷调侧逆光...' track='main' duration='4' associateAssetsIds="["A001","A003"]" shouldGenerateImage="true" ></storyboardItem>
|
||||||
|
<storyboardItem videoDesc='(苏锦登上城楼走向沈辞、城楼、苏锦/沈辞/城楼、4s、中景、跟踪、苏锦拾级而上走向沈辞、担忧、黄昏余晖渐暗、无台词、脚步声风声、A001/A002/A003)' prompt='中景,跟踪,苏锦拾级而上走向城楼上的沈辞...' track='main' duration='4' associateAssetsIds="["A001","A002","A003"]" shouldGenerateImage="true" ></storyboardItem>
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
输出:
|
||||||
|
\`\`\`
|
||||||
|
[References]
|
||||||
|
@图1 : [沈辞参考图]
|
||||||
|
@图2 : [苏锦参考图]
|
||||||
|
@图3 : [城楼参考图]
|
||||||
|
@图4 : [分镜图1]
|
||||||
|
@图5 : [分镜图2]
|
||||||
|
|
||||||
|
[Instruction]
|
||||||
|
Based on the storyboard from @图4 to @图5 :
|
||||||
|
@图1 standing alone atop the city wall, hands clasped behind back, robes billowing in the wind, gazing across the vast land,
|
||||||
|
@图2 ascending the steps toward @图1 , expression worried,
|
||||||
|
set in the ancient city wall environment of @图3 ,
|
||||||
|
wide shot transitioning to medium tracking shot, cinematic,
|
||||||
|
resolute determination shifting to concerned anticipation, dusk cold-toned side-backlit atmosphere fading.
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 二、Seedance 1.5 Pro
|
||||||
|
|
||||||
|
#### 核心原则
|
||||||
|
- **参考图负责主体外观,提示词只负责动作和镜头** — 不在提示词里写外观
|
||||||
|
- **五维度结构**:Visual / Motion / Camera / Audio / Narrative
|
||||||
|
- **不说话的主体标注 \`silent\`** — 防止误生口型
|
||||||
|
- **单镜头连贯描述,避免切镜**
|
||||||
|
- **时间轴分段**:每段 2-4 秒,用 \`0s-Xs\` 标注
|
||||||
|
|
||||||
|
#### prompt 生成模板
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
[Visual]
|
||||||
|
@图1 ({角色A名}): {站位/姿态}, {说话状态 speaking/silent}.
|
||||||
|
@图2 ({角色B名}): {站位/姿态}, {说话状态}.
|
||||||
|
{场景描述}, {道具描述}.
|
||||||
|
{视觉风格标签}.
|
||||||
|
|
||||||
|
[Motion]
|
||||||
|
0s-{X}s: @图1 {动作描述段1}.
|
||||||
|
{X}s-{Y}s: @图2 {动作描述段2}.
|
||||||
|
|
||||||
|
[Camera]
|
||||||
|
{镜头类型}, {运镜方式}, {全程描述(单镜头无切换)}.
|
||||||
|
|
||||||
|
[Audio]
|
||||||
|
{台词(含音画同步标注)/ 音效描述}. {说话者标注 lip-sync active / silent}.
|
||||||
|
|
||||||
|
[Narrative]
|
||||||
|
{情节点概述}, {叙事位置}.
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
#### 生成约束
|
||||||
|
1. **全部用英文**
|
||||||
|
2. **不描述角色外观**(外观由参考图控制)
|
||||||
|
3. **每个角色必须标注说话状态**:\`speaking\` / \`silent\` / \`speaking simultaneously\`
|
||||||
|
4. **Motion 时间轴**每段 2-4 秒,不超过单条分镜总时长
|
||||||
|
5. **Camera 段落**全程单镜头连贯描述,不含切镜
|
||||||
|
6. **视觉风格**从以下选取:\`Film noir / Cinematic / Photorealistic / 4K / High contrast / Low saturation / Desaturated tones / Shallow depth of field / Bokeh background / Cinematic color grading\`
|
||||||
|
7. **镜头类型**从以下选取:\`Wide establishing shot / Over-the-shoulder / Medium shot / Close-up / Wide shot / POV / Dutch angle / Crane up / Dolly right / Whip pan / Handheld / Slow motion\`
|
||||||
|
|
||||||
|
#### Seedance 1.5 Pro 完整示例
|
||||||
|
|
||||||
|
输入:
|
||||||
|
\`\`\`
|
||||||
|
模型:Seedance1.5
|
||||||
|
资产信息[A001, character, 沈辞], [A002, character, 苏锦], [A003, scene, 城楼]
|
||||||
|
\`\`\`
|
||||||
|
\`\`\`xml
|
||||||
|
<storyboardItem videoDesc='(沈辞独立城楼远眺苍茫大地、城楼、沈辞/城楼、4s、全景、静止、负手而立衣袂随风飘扬、坚定决绝、黄昏冷调侧逆光、无台词、风声衣袂声、A001/A003)' prompt='全景,平视略仰,城楼之上,沈辞负手而立,衣袂飘扬,黄昏冷调侧逆光...' track='main' duration='4' associateAssetsIds="["A001","A003"]" shouldGenerateImage="true" ></storyboardItem>
|
||||||
|
<storyboardItem videoDesc='(苏锦登上城楼走向沈辞、城楼、苏锦/沈辞/城楼、4s、中景、跟踪、苏锦拾级而上走向沈辞、担忧、黄昏余晖渐暗、无台词、脚步声风声、A001/A002/A003)' prompt='中景,跟踪,苏锦拾级而上走向城楼上的沈辞...' track='main' duration='4' associateAssetsIds="["A001","A002","A003"]" shouldGenerateImage="true" ></storyboardItem>
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
输出:
|
||||||
|
\`\`\`
|
||||||
|
[Visual]
|
||||||
|
@图1 (沈辞): standing alone atop city wall, hands clasped behind back, robes billowing, silent.
|
||||||
|
@图2 (苏锦): ascending steps toward @图1 , expression worried, silent.
|
||||||
|
Ancient city wall, vast open land beyond, dusk sky fading.
|
||||||
|
Cinematic, photorealistic, 4K, high contrast, desaturated tones, shallow depth of field.
|
||||||
|
|
||||||
|
[Motion]
|
||||||
|
0s-4s: @图1 stands still on city wall edge, robes flutter in wind, hair sways gently. Gaze fixed on distant horizon.
|
||||||
|
4s-8s: @图2 climbs the last few steps onto the wall, walks toward @图1 . @图1 remains still, unaware. @图2 slows as she approaches.
|
||||||
|
|
||||||
|
[Camera]
|
||||||
|
Wide establishing shot, static for first 4 seconds capturing @图1 alone. Then medium tracking shot follows @图2 ascending steps toward @图1 , smooth continuous movement, no cuts.
|
||||||
|
|
||||||
|
[Audio]
|
||||||
|
Wind howling across wall, fabric flapping rhythmically. 4s-8s: Footsteps on stone, B's robes rustling. No dialogue. No music.
|
||||||
|
|
||||||
|
[Narrative]
|
||||||
|
Lone figure on city wall, then arrival of a companion. Tension between determination and concern. Continuous single take.
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 三、Seedance 2.0
|
||||||
|
|
||||||
|
#### 核心原则
|
||||||
|
- **结构化12维编码**:统一用 \`@图N \` 引用资产和分镜图,时长 \`<duration-ms>\`
|
||||||
|
- **音色参数9维度精细描述**(有台词时必填)
|
||||||
|
- **毫秒级时长控制**
|
||||||
|
- **中文提示词**
|
||||||
|
|
||||||
|
#### prompt 生成模板
|
||||||
|
|
||||||
|
**单分镜模板:**
|
||||||
|
\`\`\`
|
||||||
|
画面风格和类型: {风格}, {色调}, {类型}
|
||||||
|
|
||||||
|
生成一个由以下 1 个分镜组成的视频:
|
||||||
|
|
||||||
|
场景:
|
||||||
|
分镜过渡: 无
|
||||||
|
|
||||||
|
分镜1<duration-ms>{毫秒数}</duration-ms>: 时间:{日/夜/晨/黄昏},场景图片:@图{场景编号} ,镜头:{景别},{角度},{运镜},@图{角色编号} {动作/表情/视线朝向/站位描述}。{台词与音色描述(如有)}。{背景环境补充}。{光影氛围}。{运镜补充}。
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
**多分镜模板:**
|
||||||
|
\`\`\`
|
||||||
|
画面风格和类型: {风格}, {色调}, {类型}
|
||||||
|
|
||||||
|
生成一个由以下 {N} 个分镜组成的视频:
|
||||||
|
|
||||||
|
场景:
|
||||||
|
分镜过渡: {全局过渡描述}
|
||||||
|
|
||||||
|
分镜1<duration-ms>{毫秒数}</duration-ms>: 时间:{...},场景图片:@图{场景编号} ,镜头:{...},@图{角色编号} {...}。{...}。
|
||||||
|
分镜2<duration-ms>{毫秒数}</duration-ms>: ...
|
||||||
|
...
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
#### 音色生成规则(有台词时必填)
|
||||||
|
|
||||||
|
台词格式:\`@图{角色编号} 说:「{台词内容}」音色:{9维度描述}\`
|
||||||
|
|
||||||
|
9维度按顺序填写:
|
||||||
|
\`\`\`
|
||||||
|
{性别},{年龄音色},{音调},{音色质感},{声音厚度},{发音方式},{气息},{语速},{特殊质感}
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
> 当 desc 中未明确音色信息时,根据角色类型从以下参考表推断:
|
||||||
|
|
||||||
|
| 角色类型特征 | 默认音色 |
|
||||||
|
|------------|---------|
|
||||||
|
| 男性权威/霸气角色 | 男声,中年音色,音调低沉,音色浑厚有力,声音厚重,发音标准,气息极其沉稳,语速偏慢 |
|
||||||
|
| 女性温柔/甜美角色 | 女声,青年音色,音调中等偏高,音色质感明亮清脆,声音清亮柔和,气息充沛平稳,带温婉真诚感 |
|
||||||
|
| 男性年轻/普通角色 | 男声,青年音色,音调中等,音色干净,声音厚度适中,发音清晰,气息平稳,语速适中 |
|
||||||
|
| 女性活泼/外向角色 | 女声,青年音色,音调偏高,音色清脆活泼,声音轻盈,气息充沛,语速偏快,带笑意和感染力 |
|
||||||
|
| 反派/冷酷角色 | 男声,中年音色,音调低沉,音色质感干燥偏暗,声音带沙砾感,气息平稳,语速极慢,有威胁感 |
|
||||||
|
|
||||||
|
#### 无台词分镜处理
|
||||||
|
- 不写 \`说:\` 和音色段落
|
||||||
|
- 在动作描述后标注 \`无台词\`
|
||||||
|
|
||||||
|
#### Seedance 2.0 完整示例
|
||||||
|
|
||||||
|
输入:
|
||||||
|
\`\`\`
|
||||||
|
模型:Seedance2.0
|
||||||
|
资产信息[A001, character, 沈辞], [A002, character, 苏锦], [A003, scene, 城楼]
|
||||||
|
\`\`\`
|
||||||
|
\`\`\`xml
|
||||||
|
<storyboardItem videoDesc='(沈辞独立城楼远眺苍茫大地、城楼、沈辞/城楼、4s、全景、静止、负手而立衣袂随风飘扬、坚定决绝、黄昏冷调侧逆光、无台词、风声衣袂声、A001/A003)' prompt='全景,平视略仰,城楼之上,沈辞负手而立,衣袂飘扬,黄昏冷调侧逆光...' track='main' duration='4' associateAssetsIds="["A001","A003"]" shouldGenerateImage="true" ></storyboardItem>
|
||||||
|
<storyboardItem videoDesc='(苏锦登上城楼走向沈辞、城楼、苏锦/沈辞/城楼、4s、中景、跟踪、苏锦拾级而上走向沈辞、担忧、黄昏余晖渐暗、苏锦说:你又一个人在这里、脚步声风声、A001/A002/A003)' prompt='中景,跟踪,苏锦拾级而上走向城楼上的沈辞...' track='main' duration='4' associateAssetsIds="["A001","A002","A003"]" shouldGenerateImage="true" ></storyboardItem>
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
输出:
|
||||||
|
\`\`\`
|
||||||
|
画面风格和类型: 真人写实, 电影风格, 冷调, 古风
|
||||||
|
|
||||||
|
生成一个由以下 2 个分镜组成的视频:
|
||||||
|
|
||||||
|
场景:
|
||||||
|
分镜过渡: 镜头平滑切换,从全景过渡到中景跟踪,焦点从沈辞独处转向苏锦到来。
|
||||||
|
|
||||||
|
分镜1<duration-ms>4000</duration-ms>: 时间:黄昏,场景图片:@图3 ,镜头:全景,平视略仰,静止镜头,@图1 独立城楼之上,负手而立,衣袂随风飘扬,目光远眺苍茫大地,神情肃然面容沉着,眼神坚定目光清冽,眉眼沉静气质凛然。无台词。背景是古城楼砖石纹理清晰,远方大地苍茫辽阔,天际线冷暖交替。黄昏斜射余晖侧逆光,冷调为主,长影拉伸,轮廓光微勾勒人物边缘,光感诗意。镜头静止。
|
||||||
|
|
||||||
|
分镜2<duration-ms>4000</duration-ms>: 时间:黄昏,场景图片:@图3 ,镜头:中景,平视,跟踪拍摄,@图2 拾级而上,走向城楼上的@图1 ,面部朝向@图1 方向,神情微愣面色微变,眼神中带着担忧,@图2 说:「你又一个人在这里。」音色:女声,青年音色,音调中等偏高,音色质感明亮清脆,声音清亮柔和,发音方式干净,气息充沛平稳,语速适中,带温婉真诚感。背景城楼台阶纹理清晰,余晖渐暗,天际线冷暖交替加深。镜头跟踪苏锦移动。
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 景别 → 镜头标签映射
|
||||||
|
|
||||||
|
| videoDesc 中的景别 | KlingOmni(英文标签) | Seedance 1.5(英文标签) | Seedance 2.0(中文描述) |
|
||||||
|
|------|------|------|------|
|
||||||
|
| 远景 | extreme wide shot | Extreme wide shot | 远景 |
|
||||||
|
| 全景 | wide shot | Wide establishing shot | 全景 |
|
||||||
|
| 中景 | medium shot | Medium shot | 中景 |
|
||||||
|
| 近景 | close-up | Close-up | 近景 |
|
||||||
|
| 特写 | close-up | Close-up | 特写 |
|
||||||
|
| 大特写 | extreme close-up | Extreme close-up | 大特写 |
|
||||||
|
|
||||||
|
## 运镜 → 镜头标签映射
|
||||||
|
|
||||||
|
| videoDesc 中的运镜 | KlingOmni(英文标签) | Seedance 1.5(英文标签) | Seedance 2.0(中文描述) |
|
||||||
|
|------|------|------|------|
|
||||||
|
| 静止 | static camera | Static, no camera movement | 镜头静止 |
|
||||||
|
| 推进 | dolly in / push in | Slow dolly forward | 镜头缓慢向前推进 |
|
||||||
|
| 拉远 | dolly out / pull back | Slow dolly backward pull | 镜头缓慢向后拉远 |
|
||||||
|
| 跟踪 | tracking shot | Tracking shot, handheld | 跟踪拍摄 |
|
||||||
|
| 摇镜 | pan left/right | Slow pan | 镜头缓慢摇移 |
|
||||||
|
| 甩镜 | whip pan | Whip pan | 快速甩镜 |
|
||||||
|
| 升降 | crane up/down | Crane up/down | 镜头升降 |
|
||||||
|
| 环绕 | surround shooting | Orbiting shot | 环绕拍摄 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 执行流程
|
||||||
|
|
||||||
|
1. **解析输入**:提取模型名称、资产列表
|
||||||
|
2. **构建 @图N 编号表**:资产按输入顺序从 \`@图1 \` 起编号,分镜图接续编号
|
||||||
|
3. **逐条解析 \`<storyboardItem>\`**:按 videoDesc 解析规则提取12个字段,结合 \`duration\`、\`associateAssetsIds\` 建立标签映射
|
||||||
|
4. **整合为一个完整的视频提示词**:按目标模型格式编排全部分镜
|
||||||
|
5. **输出视频提示词**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 约束
|
||||||
|
|
||||||
|
- **严格按目标模型格式**,不混用不同模型的格式
|
||||||
|
- **不修改原始输入**:不改写 \`<storyboardItem>\` 的任何字段;\`prompt\` 已有的分镜图提示词仅作画面参考
|
||||||
|
- **不编造资产或台词**:只使用输入中的资产信息;无台词则标注「无台词」/ \`No dialogue\`
|
||||||
|
- **时长单位转换**:Seedance 2.0 的 \`<duration-ms>\` 需将秒 × 1000 转为毫秒
|
||||||
|
`,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import u from "@/utils";
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { success } from "@/lib/responseFormat";
|
import { success } from "@/lib/responseFormat";
|
||||||
import { validateFields } from "@/middleware/middleware";
|
import { validateFields } from "@/middleware/middleware";
|
||||||
|
import { info } from "node:console";
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
export default router.post(
|
export default router.post(
|
||||||
@ -10,11 +11,67 @@ export default router.post(
|
|||||||
validateFields({
|
validateFields({
|
||||||
trackId: z.number(),
|
trackId: z.number(),
|
||||||
projectId: z.number(),
|
projectId: z.number(),
|
||||||
prompt: z.array(z.string()),
|
info: z.array(
|
||||||
|
z.object({
|
||||||
|
id: z.number(),
|
||||||
|
sources: z.string(),
|
||||||
|
}),
|
||||||
|
),
|
||||||
model: z.string(),
|
model: z.string(),
|
||||||
}),
|
}),
|
||||||
async (req, res) => {
|
async (req, res) => {
|
||||||
const { trackId, projectId, prompt, model } = req.body;
|
const { trackId, projectId, info, model } = req.body;
|
||||||
|
//查询参数
|
||||||
|
const images = await Promise.all(
|
||||||
|
info.map(async (item: { id: number; sources: string }) => {
|
||||||
|
if (item.sources === "storyboard") {
|
||||||
|
// 查询分镜主信息
|
||||||
|
const storyboard = await u
|
||||||
|
.db("o_storyboard")
|
||||||
|
.where("o_storyboard.id", item.id)
|
||||||
|
.select("videoDesc", "prompt", "track", "duration", "shouldGenerateImage")
|
||||||
|
.first();
|
||||||
|
// 查询分镜关联的资产ID
|
||||||
|
const assetRows = await u.db("o_assets2Storyboard").where("storyboardId", item.id).select("assetId");
|
||||||
|
const associateAssetsIds = assetRows.map((row: any) => row.assetId);
|
||||||
|
return {
|
||||||
|
...storyboard,
|
||||||
|
associateAssetsIds,
|
||||||
|
_type: "storyboard", // 标记类型,便于后续区分
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (item.sources === "assets") {
|
||||||
|
// 查询素材
|
||||||
|
const assetsData = await u.db("o_assets").where("o_assets.id", item.id).select("id", "type", "name").first();
|
||||||
|
return {
|
||||||
|
...assetsData,
|
||||||
|
_type: "assets", // 标记类型
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
// 拆分 assets 和 storyboard
|
||||||
|
const assets: any[] = [];
|
||||||
|
const storyboard: any[] = [];
|
||||||
|
for (const item of images) {
|
||||||
|
if (!item) continue; // 忽略空
|
||||||
|
if (item._type === "assets")
|
||||||
|
assets.push({
|
||||||
|
id: item.id,
|
||||||
|
type: item.type,
|
||||||
|
name: item.name,
|
||||||
|
});
|
||||||
|
if (item._type === "storyboard")
|
||||||
|
storyboard.push({
|
||||||
|
videoDesc: item.videoDesc,
|
||||||
|
prompt: item.prompt,
|
||||||
|
track: item.track,
|
||||||
|
duration: item.duration,
|
||||||
|
associateAssetsIds: item.associateAssetsIds,
|
||||||
|
shouldGenerateImage: item.shouldGenerateImage,
|
||||||
|
});
|
||||||
|
}
|
||||||
const [id, modelData] = model.split(":");
|
const [id, modelData] = model.split(":");
|
||||||
const projectData = await u.db("o_project").select("*").where({ id: projectId }).first();
|
const projectData = await u.db("o_project").select("*").where({ id: projectId }).first();
|
||||||
const videoPrompt = await u.db("o_prompt").where("type", "videoPromptGeneration").first();
|
const videoPrompt = await u.db("o_prompt").where("type", "videoPromptGeneration").first();
|
||||||
@ -27,7 +84,11 @@ export default router.post(
|
|||||||
messages: [
|
messages: [
|
||||||
{
|
{
|
||||||
role: "user",
|
role: "user",
|
||||||
content: `${prompt.join(",")}`,
|
content: `
|
||||||
|
**模型名称**:${modelData},
|
||||||
|
**资产信息**(角色、场景、道具):${JSON.stringify(assets)},
|
||||||
|
**分镜信息**:${JSON.stringify(storyboard)},
|
||||||
|
`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|||||||
@ -43,8 +43,8 @@ export default router.post(
|
|||||||
// 字段映射表(与 getVisualManual 保持一致)
|
// 字段映射表(与 getVisualManual 保持一致)
|
||||||
const DATA_MAP: { value: string; subDir?: string }[] = [
|
const DATA_MAP: { value: string; subDir?: string }[] = [
|
||||||
{ value: "README" },
|
{ value: "README" },
|
||||||
{ value: "narrative_sweet_romance", subDir: "art_prompt" },
|
{ value: "narrative_sweet_romance", subDir: "driector_skills" },
|
||||||
{ value: "storyboard_table_narrative", subDir: "art_prompt" },
|
{ value: "storyboard_table_narrative", subDir: "driector_skills" },
|
||||||
];
|
];
|
||||||
// 根据 DATA_MAP 构建 value -> subDir 的映射
|
// 根据 DATA_MAP 构建 value -> subDir 的映射
|
||||||
const SUB_DIR_MAP = new Map(DATA_MAP.map(({ value, subDir }) => [value, subDir ?? ""]));
|
const SUB_DIR_MAP = new Map(DATA_MAP.map(({ value, subDir }) => [value, subDir ?? ""]));
|
||||||
|
|||||||
@ -44,8 +44,8 @@ export default router.post(
|
|||||||
// 字段映射表(与 getVisualManual 保持一致)
|
// 字段映射表(与 getVisualManual 保持一致)
|
||||||
const DATA_MAP: { value: string; subDir?: string }[] = [
|
const DATA_MAP: { value: string; subDir?: string }[] = [
|
||||||
{ value: "README" },
|
{ value: "README" },
|
||||||
{ value: "narrative_sweet_romance", subDir: "art_prompt" },
|
{ value: "narrative_sweet_romance", subDir: "driector_skills" },
|
||||||
{ value: "storyboard_table_narrative", subDir: "art_prompt" },
|
{ value: "storyboard_table_narrative", subDir: "driector_skills" },
|
||||||
];
|
];
|
||||||
// 根据 DATA_MAP 构建 value -> subDir 的映射
|
// 根据 DATA_MAP 构建 value -> subDir 的映射
|
||||||
const SUB_DIR_MAP = new Map(DATA_MAP.map(({ value, subDir }) => [value, subDir ?? ""]));
|
const SUB_DIR_MAP = new Map(DATA_MAP.map(({ value, subDir }) => [value, subDir ?? ""]));
|
||||||
|
|||||||
@ -8,8 +8,8 @@ const router = express.Router();
|
|||||||
// 字段映射表
|
// 字段映射表
|
||||||
const DATA_MAP: { label: string; value: string; subDir?: string }[] = [
|
const DATA_MAP: { label: string; value: string; subDir?: string }[] = [
|
||||||
{ label: "README", value: "README" },
|
{ label: "README", value: "README" },
|
||||||
{ label: "导演规划", value: "narrative_sweet_romance", subDir: "art_prompt" },
|
{ label: "导演规划", value: "narrative_sweet_romance", subDir: "driector_skills" },
|
||||||
{ label: "分镜表", value: "storyboard_table_narrative", subDir: "art_prompt" },
|
{ label: "分镜表", value: "storyboard_table_narrative", subDir: "driector_skills" },
|
||||||
];
|
];
|
||||||
|
|
||||||
// 读取 md 文件内容,文件不存在时返回空字符串
|
// 读取 md 文件内容,文件不存在时返回空字符串
|
||||||
|
|||||||
@ -53,7 +53,6 @@ export default function runCode(code: string, vendor?: Record<string, any>) {
|
|||||||
|
|
||||||
return exports as Record<string, any>;
|
return exports as Record<string, any>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function logger(logstring: string) {
|
export function logger(logstring: string) {
|
||||||
console.log("【VM】" + logstring);
|
console.log("【VM】" + logstring);
|
||||||
}
|
}
|
||||||
|
|||||||