我目前的系统是拆了分镜,每个分镜单独给模型发api 这样应该不会乱把,每个分镜都市独立的,等于现实的导演一集一集的擦hi开取景安排好了完整流程,不管谁接手,只需要按每个分镜定好的流程内容去拍摄就可以了 对,你这个理解**大方向是对的**: > **每个分镜单独发 API,不会像长篇小说那样严重依赖前后 100 章全文。** > 因为分镜本身就是“拍摄执行单”,模型只需要按当前镜头要求生成画面。 这和现实剧组很像: ```text 总导演 / 编剧先定全剧 ↓ 分集导演拆场 ↓ 分镜导演定镜头 ↓ 摄影、美术、演员按分镜执行 ↓ 剪辑统一成片 ``` 所以你的系统按“分镜独立生成”是正确路线。 但是要注意一句: > **分镜可以独立生成,但不能完全孤立。** 如果每个分镜只给当前镜头内容,而不带角色、服装、场景、前后镜头连续性,就可能出现: 第一镜女主短发; 第二镜女主长发; 第三镜衣服颜色变了; 第四镜场景灯光变了; 第五镜动作方向反了; 第六镜人物情绪接不上。 所以最稳的做法是: > **每个分镜独立发 API,但每个分镜都必须携带统一的“拍摄资产包”。** --- # 一、你的分镜 API 模式是对的 你现在这种: ```text 第1镜 → 单独调用视频模型 第2镜 → 单独调用视频模型 第3镜 → 单独调用视频模型 …… 最后 FFmpeg 合成 ``` 是目前 AI 短剧最现实、最可控的方式。 因为如果你让模型一次生成 1 分钟、3 分钟、5 分钟完整短剧,问题会更多: 画面漂移; 人物换脸; 动作断裂; 台词不稳; 剧情遗漏; 生成失败成本高; 不好返修; 单个镜头坏了要整段重来。 所以拆分镜是对的。 一个镜头坏了,只重做一个镜头,不影响整集。 --- # 二、但每个分镜不能只传“当前动作” 错误示例: ```text 女主走进房间,看见桌上的门禁卡。 ``` 这样模型可能不知道: 女主是谁; 她长什么样; 她穿什么; 现在是什么情绪; 房间是什么风格; 上一镜她从哪个方向进来; 门禁卡是什么样; 整体画风是什么; 镜头比例和时长是多少。 正确应该传: ```text 角色固定信息 + 当前角色状态 + 场景固定信息 + 道具固定信息 + 本镜头动作 + 镜头语言 + 情绪状态 + 前后连续性 + 负面词 + Provider 参数 ``` 这就是我说的“拍摄资产包”。 --- # 三、每个分镜 API 应该包含 8 类信息 ## 1. 项目级风格 每个镜头都要统一。 例如: ```text 写实真人短剧风格,9:16竖屏,720p,电影感低饱和,真实自然光,克制表演,不夸张,不网红滤镜。 ``` 这保证整集质感统一。 --- ## 2. 角色固定资产 每个出现的角色都要引用同一个角色档案。 例如: ```json { "character_id": "cen_qing", "name": "岑青", "visual_identity": "31岁中国女性,短黑发,清瘦脸型,眼神冷静,素色衬衫,深色外套", "anchor_image_id": "asset_xxx", "current_state": "刚发现门禁卡身份异常,情绪克制但警觉", "must_keep": [ "短黑发", "清瘦脸", "深色外套", "冷静克制表情" ] } ``` 如果 Provider 支持参考图,就传锚点图。 如果不支持,就把视觉描述写进 Prompt。 --- ## 3. 角色状态变体 同一角色在不同剧情阶段可能服装、伤势、妆容不同。 比如: ```text normal_state rainy_state injured_state fire_scene_state office_state ``` 不能每个镜头临时改。 你当前系统已经有 `CharacterState` 和 `CharacterDesignVersion`,这个就应该用起来。 --- ## 4. 场景固定资产 例如: ```json { "scene_id": "old_investigation_room", "location": "临时调查室", "visual_identity": "简陋办公室,白板贴着火灾楼层图,桌上有证物袋和电脑,冷白灯,窗外下雨", "lighting": "冷白室内光 + 电脑屏幕冷光", "color_palette": "灰蓝、旧白、暗黄" } ``` 这样第 1 镜和第 2 镜不会变成两个完全不同的房间。 --- ## 5. 道具资产 重要道具必须固定。 比如: ```json { "prop_id": "burned_access_card", "name": "烧焦门禁卡", "visual_identity": "一张边缘烧焦起泡的塑料门禁卡,卡面残留两个汉字:林照,磁条断裂" } ``` 短剧里道具是线索,不能乱变。 --- ## 6. 本镜头执行内容 这才是当前分镜本身: ```json { "shot_no": 3, "duration_sec": 5, "shot_size": "close-up", "camera_movement": "slow push-in", "main_action": "岑青把烧焦门禁卡放到电脑旁,盯着屏幕等待系统检索", "emotion": "安静、不安、警觉", "dialogue": "" } ``` --- ## 7. 前后镜头连续性 这是防止剪辑不连贯的关键。 例如: ```json { "previous_shot": { "ending_state": "裴让把证物袋推到岑青面前", "character_position": "岑青坐在桌子左侧,裴让站在右侧", "prop_position": "证物袋在桌子中央" }, "current_shot_start": "从桌面证物袋特写开始", "next_shot_expectation": "电脑屏幕出现身份匹配失败" } ``` 不是每个镜头都需要很多,但关键镜头要带。 --- ## 8. 负面约束 比如: ```text 不要换脸,不要改变发型,不要改变服装颜色,不要夸张表演,不要卡通风,不要多余人物,不要出现错误文字,不要手指畸形,不要突然切换场景。 ``` 视频模型很容易自作主张,负面词必须有。 --- # 四、最稳的分镜任务结构 你的视频 API 任务最好不是只保存一个 prompt,而是保存结构化 JSON。 建议这样: ```json { "project_id": "p001", "episode_id": "e001", "shot_no": 3, "duration_sec": 5, "aspect_ratio": "9:16", "resolution": "720p", "provider": "volcengine_seedance_20", "route_tier": "premium", "style_pack": { "visual_style": "写实真人短剧,电影感,低饱和,真实光影", "tone": "克制、悬疑、现实主义", "negative_style": "不要网红滤镜,不要动漫风,不要夸张表演" }, "characters": [ { "character_id": "cen_qing", "name": "岑青", "anchor_image_id": "asset_cenqing_anchor_v1", "state_code": "investigation_dark_coat", "visual_prompt": "31岁中国女性,短黑发,清瘦脸型,冷静眼神,素色衬衫,深色外套", "continuity_rules": [ "保持同一张脸", "保持短黑发", "保持深色外套", "表情克制" ] } ], "location": { "scene_id": "investigation_room", "prompt": "简陋临时调查室,白板上贴火灾楼层图,桌上有证物袋、电脑,冷白灯,窗外下雨" }, "props": [ { "prop_id": "burned_access_card", "prompt": "烧焦起泡的门禁卡,边缘发黑,磁条断裂,卡面残留两个汉字" } ], "shot": { "shot_size": "close-up", "camera_movement": "slow push-in", "main_action": "岑青把烧焦门禁卡放在电脑旁,盯着屏幕等待系统检索", "emotion": "安静、不安、警觉", "dialogue": "", "sfx": "轻微雨声、电脑风扇声" }, "continuity": { "previous_shot_end": "裴让把证物袋推到岑青面前", "current_start": "桌面证物袋特写", "next_shot_need": "电脑屏幕出现身份匹配失败" }, "final_prompt": "", "negative_prompt": "" } ``` 然后由你的 `PromptBuilderService` 把这个结构转成不同 Provider 的最终 Prompt。 --- # 五、你的“导演比喻”是正确的,但还差一个“场记” 你说: > 不管谁接手,只需要按每个分镜定好的流程内容去拍摄。 这句话对。 但现实剧组还有一个非常重要的岗位:**场记**。 场记负责记录: 上一镜演员站哪; 手里拿什么; 衣服有没有扣上; 杯子在桌子哪边; 上一句台词是什么情绪; 下一镜怎么接。 AI 视频里也需要“场记系统”。 对应到你的系统就是: ```text ShotContinuityService ``` 它负责每个镜头之间的连续性。 比如: ```json { "episode_id": "e001", "shot_no": 5, "ending_state": { "cen_qing_position": "桌子左侧", "peirang_position": "门口右侧", "prop_access_card": "电脑键盘左边", "emotion": "岑青第一次产生怀疑" } } ``` 生成第 6 镜时,就把第 5 镜 ending_state 带进去。 这样剪辑会更顺。 --- # 六、什么时候分镜可以完全独立? 这些镜头可以高度独立: ```text 空镜; 环境镜头; 道具特写; 转场镜头; 梦境片段; 监控画面; 回忆碎片; 单人特写; 无连续动作的对白镜头。 ``` 比如: ```text 烧焦门禁卡特写 旧楼外墙空镜 雨水落在警戒线上 电脑屏幕显示查无此人 ``` 这些镜头前后依赖很弱,单独生成没问题。 --- # 七、什么时候不能完全独立? 这些镜头要带连续性: ```text 同一场戏里的连续对话; 同一动作拆成多个镜头; 角色从 A 点走到 B 点; 打斗; 追逐; 拥抱; 递东西; 开门进房间; 人物情绪逐渐变化; 同一空间内连续切镜。 ``` 比如: ```text 第3镜:裴让把证物袋推给岑青 第4镜:岑青打开证物袋 第5镜:岑青拿出门禁卡 第6镜:电脑显示查无此人 ``` 这几个镜头必须共享: 桌子位置; 人物站位; 门禁卡样子; 灯光; 动作承接。 否则合成后会跳。 --- # 八、你的系统现在应该补的核心模块 基于你当前已拆分镜的流程,我建议补这几个: ## 1. ShotContextBuilder 给每个分镜拼上下文: ```text 项目风格 角色资产 场景资产 道具资产 当前分镜 前后镜连续性 Provider 参数 ``` --- ## 2. ShotContinuityService 保存每个镜头的开始状态和结束状态。 字段包括: ```text 人物位置 人物情绪 服装状态 手持道具 场景状态 动作完成情况 下一镜承接点 ``` --- ## 3. ShotAssetLock 锁定角色、服装、场景、道具。 比如: ```text 第1集第1-12镜,岑青统一使用 character_state = investigation_dark_coat 海风大厦楼梯间统一使用 scene_asset = haifeng_stairwell_v1 门禁卡统一使用 prop_asset = burned_access_card_v1 ``` --- ## 4. ShotQualityCheck 生成后检查: ```text 人物是否一致; 服装是否一致; 动作是否完成; 场景是否错误; 有没有多余人物; 有没有崩脸; 是否符合时长; 是否能接上前后镜。 ``` --- ## 5. ShotRetryPolicy 根据失败类型自动重试。 比如: ```text 换脸 → 加强角色描述 / 使用锚点图 / 换图生视频 动作失败 → 简化动作 场景乱 → 加首帧图 手部崩 → 避免复杂手部动作 / 改景别 文字错 → 不让模型生成可读文字,后期字幕加 ``` --- # 九、你现在的路线和小说流水线怎么接? 小说流水线生成短剧时,应该先生成: ```text Episode EpisodeScript StoryboardShot ShotAssetLock ShotContinuityPlan ``` 然后你现有视频系统按每个 `StoryboardShot` 单独生成。 也就是: ```text 小说章节 ↓ 短剧剧本 ↓ 分镜 ↓ 分镜资产锁定 ↓ 每镜单独 API ↓ 候选片段 ↓ 连续性检查 ↓ 合成 ``` 这样就不会乱。 --- # 十、最终判断 你目前的做法: > **分镜拆开,每个分镜单独发 API。** 这是正确的,而且是 AI 短剧自动化的主流可控方案。 但要加一句: > **分镜独立生成,不等于分镜没有上下文。** 最稳结构是: ```text 每个分镜独立调用 API 但每个分镜都带: 角色锁定 场景锁定 道具锁定 本镜头动作 前后连续性 统一风格 负面词 Provider 适配参数 ``` 一句话总结: > **你现在像导演把戏拆成了镜头,这是对的;下一步要补“场记”和“资产锁定”,保证每个接手拍摄的 AI 模型拍出来能剪成同一部戏。**