[P0] 批量成片三连修:变体配音错位/成片截断配音/跨视频素材重复避让失效 #1749

Closed
opened 2026-09-06 21:26:04 +08:00 by xiaoxia · 6 comments
Owner

背景

2026-09-06 21:01 staging 实测批量 3 视频(batch c12550e5,独立配音模式,每视频选不同配音),全部 completed 但三个成片质量问题,均有 DB+worker 日志铁证。

问题 A:变体配音错位(视频3 用了视频1 的配音)

  • 用户选择:视频1=GQLY5918(11.6s)、视频2=EYCP5535(22.0s)、视频3=ANDT5195(14.7s)
  • worker 日志实际下载:plan a2989c05→6c8a397c(GQLY)、plan f4ede80e→19001180(EYCP)、plan 628fa60e→6c8a397c(GQLY);DB generation_tasks 三行 voice_library_id = GQLY / EYCP / GQLY(应为 ANDT=16421fee),voice_ids 全部为 []
  • 链路:generation_tasks.py:540 variant_voice_library_id = _variant_value(request.voice_library_ids, task_index, request.voice_library_id)_variant_value(:51)对索引越界/空值静默 fallback 到共用 voice_library_id,错误被吞
  • 要求:①前端 voice_library_ids 数组索引/长度链路排查(独立模式必须 N 个值与变体一一对应,空值不得静默 fallback 共用值,应 400 报错);②后端对批量独立配音做守卫:voice_library_ids 长度与 count 不一致或缺值时拒绝并明确报错;③清理冗余:voice_ids 字段在批量链路恒为空数组、与 voice_library_id 语义重叠,确认无引用后删除(代码唯一性铁律,不留技术债)

问题 B:成片时长截断配音(配音尾部丢失约 1s)

  • worker 日志铁证(视频3):[voice-align] 配音音频时长: 11.598s → 调整完成: 新总时长=11.598s,紧接 [debug] estimated video_duration=10.598——对齐目标没算转场时长(3 片段 2 转场),成片 10.62s,配音轨按视频长度截断,尾部约 1s 丢失
  • 视频2:配音 21.995s,ratio=1.3833 走慢放(speed=1/1.3833≈0.72x),成片 21.03s 同样差约 1s;慢放还会导致画面动作明显变慢失真
  • 要求:①voice-align 对齐目标时长必须把转场总时长算入(对齐后 estimated_duration 必须 ≥ 配音时长,而不是 clips 之和等于配音时长);配音层添加时以配音时长为准,视频尾部不足用定格/末段延长补齐,禁止截断配音;②片段比配音短时优先"补充更多素材片段"而非全局慢放(慢放比例超 0.9x~1.1x 区间时应补片段),保持画面自然;③补单测:3 片段含转场场景对齐后成片时长 ≥ 配音时长

问题 C:跨视频素材重复,批次避让失效(查重率高的根因)

  • 本批 3 plan 共 9 片段铁证:
    • 92939c5b(upload_video.mp4,素材总长仅 6.2s)被 3 个视频全部使用,其中 plan a2989c05 用区间 [0.9,6.2]、plan 628fa60e 用 [0.0,5.3]——两段几乎完全重叠
    • 668cf0d4 被视频1/视频3 共用(区间 [0,5.3] vs [6.4,11.7] 错开,属可接受)
  • 根因:variant_plan_selector.py 的 20% 避让(BATCH_CLIP_OVERLAP_LIMIT=0.20)只做"同素材已用区间→重选起点",素材选择层面不排除本批次已用过的素材;且短素材数学上无法避让:片段需 5.3s、素材仅 6.2s、可滑动窗口 0.9s,而 20% 上限要求区间错开 ≥4.24s,重选必然失败,失败后静默照用
  • 要求:①批次内素材级去重优先:每个变体选片时,本批次已被其他变体使用的素材直接排除(素材池不足时才允许复用且必须区间错开),素材池不够时给用户明确提示"素材数量不足 N 个视频独立使用"而非静默重复;②短素材保护:素材可用时长 < 片段需求时长的 N 倍(无法提供错开区间)时不得跨变体复用;③确认 record_used_segments 持久化区间在同批次 N 变体串行选片时立即可见(同事务/同请求内);④补单测:3 变体×3 片段、11 素材场景下,跨变体相同素材占比 ≤20% 且无完全重叠区间;⑤查重率问题用户反复反馈,本次必须彻底解决

验收

  • 独立配音 N=3:3 成片配音分别为用户所选 3 个配音,无错位
  • 成片时长 ≥ 配音时长,配音内容完整无截断;无明显慢放失真
  • 3 成片跨视频相同素材片段占比 ≤20%,无完全重叠区间;DB edit_plan_clips 可验证
  • N=1 单视频零回归
  • CI 全绿部署 staging,删净冗余代码

参考数据

  • batch_id: c12550e5559f40e5a5aab92db1a24e45
  • tasks: d01af230(视频1/GQLY)、702bc08b(视频2/EYCP)、4e00f4e2(视频3/错绑GQLY,应ANDT)
  • plans: a2989c05、f4ede80e、628fa60e(片段均 3×5.3s=15.9s)
  • 相关代码:apps/api/app/api/routes/generation_tasks.py:51-57,540;apps/worker/video_processing/unified_render_service.py:202-204,516-620(_align_clips_to_voice_duration);packages/domain/variant_plan_selector.py(BATCH_CLIP_OVERLAP_LIMIT=0.20)
  • 用户要求:不要修一个弄坏另一个;多次修改后的冗余代码一并删除,不留技术债
## 背景 2026-09-06 21:01 staging 实测批量 3 视频(batch c12550e5,独立配音模式,每视频选不同配音),全部 completed 但三个成片质量问题,均有 DB+worker 日志铁证。 ## 问题 A:变体配音错位(视频3 用了视频1 的配音) - 用户选择:视频1=GQLY5918(11.6s)、视频2=EYCP5535(22.0s)、视频3=ANDT5195(14.7s) - worker 日志实际下载:plan a2989c05→6c8a397c(GQLY)、plan f4ede80e→19001180(EYCP)、plan 628fa60e→6c8a397c(GQLY);DB `generation_tasks` 三行 voice_library_id = GQLY / EYCP / **GQLY**(应为 ANDT=16421fee),voice_ids 全部为 `[]` - 链路:`generation_tasks.py:540` `variant_voice_library_id = _variant_value(request.voice_library_ids, task_index, request.voice_library_id)`;`_variant_value`(:51)对索引越界/空值静默 fallback 到共用 voice_library_id,错误被吞 - 要求:①前端 voice_library_ids 数组索引/长度链路排查(独立模式必须 N 个值与变体一一对应,空值不得静默 fallback 共用值,应 400 报错);②后端对批量独立配音做守卫:voice_library_ids 长度与 count 不一致或缺值时拒绝并明确报错;③清理冗余:voice_ids 字段在批量链路恒为空数组、与 voice_library_id 语义重叠,确认无引用后删除(代码唯一性铁律,不留技术债) ## 问题 B:成片时长截断配音(配音尾部丢失约 1s) - worker 日志铁证(视频3):`[voice-align] 配音音频时长: 11.598s → 调整完成: 新总时长=11.598s`,紧接 `[debug] estimated video_duration=10.598`——对齐目标没算转场时长(3 片段 2 转场),成片 10.62s,配音轨按视频长度截断,尾部约 1s 丢失 - 视频2:配音 21.995s,ratio=1.3833 走慢放(speed=1/1.3833≈0.72x),成片 21.03s 同样差约 1s;慢放还会导致画面动作明显变慢失真 - 要求:①voice-align 对齐目标时长必须把转场总时长算入(对齐后 estimated_duration 必须 ≥ 配音时长,而不是 clips 之和等于配音时长);配音层添加时以配音时长为准,视频尾部不足用定格/末段延长补齐,禁止截断配音;②片段比配音短时优先"补充更多素材片段"而非全局慢放(慢放比例超 0.9x~1.1x 区间时应补片段),保持画面自然;③补单测:3 片段含转场场景对齐后成片时长 ≥ 配音时长 ## 问题 C:跨视频素材重复,批次避让失效(查重率高的根因) - 本批 3 plan 共 9 片段铁证: - 92939c5b(upload_video.mp4,**素材总长仅 6.2s**)被 3 个视频全部使用,其中 plan a2989c05 用区间 [0.9,6.2]、plan 628fa60e 用 [0.0,5.3]——两段几乎完全重叠 - 668cf0d4 被视频1/视频3 共用(区间 [0,5.3] vs [6.4,11.7] 错开,属可接受) - 根因:`variant_plan_selector.py` 的 20% 避让(BATCH_CLIP_OVERLAP_LIMIT=0.20)只做"同素材已用区间→重选起点",**素材选择层面不排除本批次已用过的素材**;且短素材数学上无法避让:片段需 5.3s、素材仅 6.2s、可滑动窗口 0.9s,而 20% 上限要求区间错开 ≥4.24s,重选必然失败,失败后静默照用 - 要求:①批次内素材级去重优先:每个变体选片时,本批次已被其他变体使用的素材直接排除(素材池不足时才允许复用且必须区间错开),素材池不够时给用户明确提示"素材数量不足 N 个视频独立使用"而非静默重复;②短素材保护:素材可用时长 < 片段需求时长的 N 倍(无法提供错开区间)时不得跨变体复用;③确认 record_used_segments 持久化区间在同批次 N 变体串行选片时立即可见(同事务/同请求内);④补单测:3 变体×3 片段、11 素材场景下,跨变体相同素材占比 ≤20% 且无完全重叠区间;⑤查重率问题用户反复反馈,本次必须彻底解决 ## 验收 - 独立配音 N=3:3 成片配音分别为用户所选 3 个配音,无错位 - 成片时长 ≥ 配音时长,配音内容完整无截断;无明显慢放失真 - 3 成片跨视频相同素材片段占比 ≤20%,无完全重叠区间;DB edit_plan_clips 可验证 - N=1 单视频零回归 - CI 全绿部署 staging,删净冗余代码 ## 参考数据 - batch_id: c12550e5559f40e5a5aab92db1a24e45 - tasks: d01af230(视频1/GQLY)、702bc08b(视频2/EYCP)、4e00f4e2(视频3/错绑GQLY,应ANDT) - plans: a2989c05、f4ede80e、628fa60e(片段均 3×5.3s=15.9s) - 相关代码:apps/api/app/api/routes/generation_tasks.py:51-57,540;apps/worker/video_processing/unified_render_service.py:202-204,516-620(_align_clips_to_voice_duration);packages/domain/variant_plan_selector.py(BATCH_CLIP_OVERLAP_LIMIT=0.20) - 用户要求:不要修一个弄坏另一个;多次修改后的冗余代码一并删除,不留技术债
Author
Owner

补充(用户明确的核心规则,问题 B 修复方向以此为准)

成片时长由配音时长决定,片段数量和单段时长在选片阶段就按配音时长规划,模板不再有时长概念。

现状错误链路(已核实):

  • 选片/建 plan 阶段(plan_generator_service)完全不读取配音时长:片段来自模板 clip_configs 固定时长或 _DEFAULT_CLIP_DURATION=5.0,本批 3 段×5.3s=15.9s 与配音 11.6/22/14.7s 全部不匹配
  • 配音时长直到 worker 渲染时才被 _align_clips_to_voice_duration 事后补救:配音短→裁剪片段(且漏算转场导致截断配音)、配音长→全局慢放画面(22s 配音慢放 0.72x,动作失真)
  • 模板时长概念已废弃但代码残留:packages/domain/template.py TemplateSegment.duration_min/duration_max、clip_configs 中的时长字段

要求:

  1. 选片阶段以配音时长为目标总时长:配音在第3步已选定、assets 表 duration 字段有值(本批 11.598/21.995/14.681s),批量变体建 plan / variant-plans 预览接口 / 正式 tasks 建 plan 时都要传入对应变体的配音 asset_id 并读取其时长,按目标总时长规划片段数量与单段时长(如 22s→45 段、11.6s→23 段,单段时长在素材合理范围内),素材不足覆盖配音时长时明确提示用户
  2. 渲染阶段 voice-align 只做微小误差修正(±5%),不再承担裁剪/慢放主力逻辑;禁止全局慢放画面
  3. 删除模板时长遗留代码:TemplateSegment.duration_min/duration_max、clip_configs 时长字段、相关读取分支,确认无引用后彻底删除(用户原话:模板里根本不再有时长这个概念,遗留代码直接删除,不要让代码混乱)
  4. 单测:给定配音时长 X,建出的 plan 片段总时长(含转场)≈X,且片段数随 X 变化
## 补充(用户明确的核心规则,问题 B 修复方向以此为准) **成片时长由配音时长决定,片段数量和单段时长在选片阶段就按配音时长规划,模板不再有时长概念。** 现状错误链路(已核实): - 选片/建 plan 阶段(plan_generator_service)完全不读取配音时长:片段来自模板 clip_configs 固定时长或 `_DEFAULT_CLIP_DURATION=5.0`,本批 3 段×5.3s=15.9s 与配音 11.6/22/14.7s 全部不匹配 - 配音时长直到 worker 渲染时才被 `_align_clips_to_voice_duration` 事后补救:配音短→裁剪片段(且漏算转场导致截断配音)、配音长→全局慢放画面(22s 配音慢放 0.72x,动作失真) - 模板时长概念已废弃但代码残留:`packages/domain/template.py` TemplateSegment.duration_min/duration_max、clip_configs 中的时长字段 要求: 1. **选片阶段以配音时长为目标总时长**:配音在第3步已选定、assets 表 duration 字段有值(本批 11.598/21.995/14.681s),批量变体建 plan / variant-plans 预览接口 / 正式 tasks 建 plan 时都要传入对应变体的配音 asset_id 并读取其时长,按目标总时长规划片段数量与单段时长(如 22s→4~5 段、11.6s→2~3 段,单段时长在素材合理范围内),素材不足覆盖配音时长时明确提示用户 2. 渲染阶段 voice-align 只做**微小误差修正(±5%)**,不再承担裁剪/慢放主力逻辑;禁止全局慢放画面 3. **删除模板时长遗留代码**:TemplateSegment.duration_min/duration_max、clip_configs 时长字段、相关读取分支,确认无引用后彻底删除(用户原话:模板里根本不再有时长这个概念,遗留代码直接删除,不要让代码混乱) 4. 单测:给定配音时长 X,建出的 plan 片段总时长(含转场)≈X,且片段数随 X 变化
Author
Owner

补充(staging 实测铁证,2026-09-06 21:35)

铁证1:批量预览接口 /generation/variant-plans 后端从未实现(预览≠成片的总根因)

  • staging 实测 POST https://staging.xiaoxiajianji.com/api/v1/generation/variant-plans 返回 HTTP 404(同路径存在的路由返回 401,证明 404=路由不存在而非鉴权)
  • 全后端代码 grep variant-plans/variant_plans 零结果——前端 #1748 对接的接口后端从未实现,前端 catch 404 后静默降级为本地模拟
  • 后果:批量预览的片段/时长/画面全是前端假造,与正式成片完全不一致。用户明确要求预览视频与后端成片 100% 一致(预览即成片)

要求:

  1. 后端实现 POST /api/v1/generation/variant-plans:入参与正式批量生成一致(模板、素材、变体数、titles、voice_library_ids、voice_mode 等),返回每个变体的 plan_id + clips(片段顺序/素材/start_time/duration 与正式生成完全同源);实现方式必须与正式任务共用同一套选片/变体生成服务函数,禁止另写一套预览专用逻辑
  2. 该接口生成的 plan 与正式生成的关系:正式生成时若前端回传 plan_id 则直接复用(#1745 已有 variant_plan_ids 回传机制,接通即可),保证预览所见即成片
  3. 接口必须做与问题A相同的 voice_library_ids 严格守卫(缺值/长度不符 400,禁静默 fallback)

铁证2:片段时长与配音完全无关 + 渲染期等比平均缩放(用户原话:不应该平均分配)

staging DB 实测批次 c12550e5(模板 f752fd6d「9/6」):

  • template_clip_configs 3 段全部 min_duration=max_duration=5(写死)
  • 3 个 plan 的 9 个 edit_plan_clips 时长全部 5.3s(选片阶段完全不读配音时长)
  • worker 渲染时 _align_clips_to_voice_duration(unified_render_service.py:516-620)对所有片段乘同一 ratio:11.6s 配音→每段统一×0.729 裁剪;22s 配音→每段统一×0.72 慢放。即用户指出的「音频平均分配到每个片段」

要求(与补充规则一致并细化):

  1. 选片阶段以配音时长为目标总时长规划片段:片段数 = 配音时长 ÷ 单段合理时长(3.56s 区间),如 12s→3 段、22s→45 段;单段时长按素材实际可用时长在合理区间内分配(长素材可多分、短素材少分,短素材不得跨视频复用见问题C),总片长(含转场)≈配音时长,而非每段死等长
  2. 素材总时长不足以覆盖配音时长时,接口明确返回错误提示,禁止靠慢放/截断硬凑
  3. 渲染期 voice-align 只保留 ±5% 微误差修正,删除全局等比裁剪/慢放为主的逻辑
  4. 删除模板时长遗留:template_clip_configs.min_duration/max_duration、TemplateSegment.duration_min/duration_max 及全部读取分支(用户原话:模板里不再有时长概念,遗留代码直接删除)
  5. 单测:12s 配音→plan 片段总时长≈12s 且片段数≈3;22s 配音→片段数≈4~5;素材不足→明确报错
## 补充(staging 实测铁证,2026-09-06 21:35) ### 铁证1:批量预览接口 /generation/variant-plans 后端从未实现(预览≠成片的总根因) - staging 实测 `POST https://staging.xiaoxiajianji.com/api/v1/generation/variant-plans` 返回 **HTTP 404**(同路径存在的路由返回 401,证明 404=路由不存在而非鉴权) - 全后端代码 grep `variant-plans`/`variant_plans` **零结果**——前端 #1748 对接的接口后端从未实现,前端 catch 404 后静默降级为本地模拟 - 后果:批量预览的片段/时长/画面全是前端假造,与正式成片完全不一致。用户明确要求**预览视频与后端成片 100% 一致(预览即成片)** 要求: 1. **后端实现 POST /api/v1/generation/variant-plans**:入参与正式批量生成一致(模板、素材、变体数、titles、voice_library_ids、voice_mode 等),返回每个变体的 plan_id + clips(片段顺序/素材/start_time/duration 与正式生成完全同源);实现方式必须与正式任务共用同一套选片/变体生成服务函数,**禁止另写一套预览专用逻辑** 2. 该接口生成的 plan 与正式生成的关系:正式生成时若前端回传 plan_id 则直接复用(#1745 已有 variant_plan_ids 回传机制,接通即可),保证预览所见即成片 3. 接口必须做与问题A相同的 voice_library_ids 严格守卫(缺值/长度不符 400,禁静默 fallback) ### 铁证2:片段时长与配音完全无关 + 渲染期等比平均缩放(用户原话:不应该平均分配) staging DB 实测批次 c12550e5(模板 f752fd6d「9/6」): - template_clip_configs 3 段全部 min_duration=max_duration=5(写死) - 3 个 plan 的 9 个 edit_plan_clips 时长全部 5.3s(选片阶段完全不读配音时长) - worker 渲染时 `_align_clips_to_voice_duration`(unified_render_service.py:516-620)对**所有片段乘同一 ratio**:11.6s 配音→每段统一×0.729 裁剪;22s 配音→每段统一×0.72 慢放。即用户指出的「音频平均分配到每个片段」 要求(与补充规则一致并细化): 1. 选片阶段以配音时长为目标总时长规划片段:片段数 = 配音时长 ÷ 单段合理时长(3.5~6s 区间),如 12s→3 段、22s→4~5 段;单段时长按素材实际可用时长在合理区间内分配(长素材可多分、短素材少分,短素材不得跨视频复用见问题C),总片长(含转场)≈配音时长,而非每段死等长 2. 素材总时长不足以覆盖配音时长时,接口明确返回错误提示,禁止靠慢放/截断硬凑 3. 渲染期 voice-align 只保留 ±5% 微误差修正,删除全局等比裁剪/慢放为主的逻辑 4. 删除模板时长遗留:template_clip_configs.min_duration/max_duration、TemplateSegment.duration_min/duration_max 及全部读取分支(用户原话:模板里不再有时长概念,遗留代码直接删除) 5. 单测:12s 配音→plan 片段总时长≈12s 且片段数≈3;22s 配音→片段数≈4~5;素材不足→明确报错
Author
Owner

⚠️ 规则更正(覆盖此前「片段数随配音时长变化」的表述,以此为准)

经与产品方核对,片段数规则以 2026-09-04 定稿方案为准,此前评论中「12s→3段、22s→4~5段,片段数随配音时长增减」的表述作废

  1. 片段数量由模板定死,不增不减:模板配置几个片段,plan 就是几个片段,配音长短不改变片段数(模板时长字段删除后,模板只剩片段数量/顺序/转场等结构)
  2. 配音时长 = 成片总时长:配音总时长按模板片段分配到每段(总片长含转场≈配音时长,误差<0.5s)
  3. 每段时长的具体分配方式(等比分配 vs 按配音断句节奏分配)产品方正在确认,确认前不要自行实现选片时长逻辑,可先做接口骨架、配音错位守卫、素材去重、模板时长字段删除等不涉及时长分配的部分
  4. 禁止全局慢放画面(22s 配音慢放 0.72x 动作失真,不可接受);配音略长于素材总量时的兜底用末帧冻结/末段循环(9月4日方案已定,未落地,本次补上)
  5. 9月4日方案的另一道保险「选配音时只显示时长匹配的配音(90%~110%)」未落地,属前端 #1750 范围,后端需提供片段预估总时长口径供前端过滤

其他要求(variant-plans 接口、配音 400 守卫、素材级去重、冗余删除、单测、N=1 零回归)不变。

## ⚠️ 规则更正(覆盖此前「片段数随配音时长变化」的表述,以此为准) 经与产品方核对,片段数规则以 2026-09-04 定稿方案为准,**此前评论中「12s→3段、22s→4~5段,片段数随配音时长增减」的表述作废**: 1. **片段数量由模板定死,不增不减**:模板配置几个片段,plan 就是几个片段,配音长短不改变片段数(模板时长字段删除后,模板只剩片段数量/顺序/转场等结构) 2. **配音时长 = 成片总时长**:配音总时长按模板片段分配到每段(总片长含转场≈配音时长,误差<0.5s) 3. **每段时长的具体分配方式(等比分配 vs 按配音断句节奏分配)产品方正在确认,确认前不要自行实现选片时长逻辑**,可先做接口骨架、配音错位守卫、素材去重、模板时长字段删除等不涉及时长分配的部分 4. **禁止全局慢放画面**(22s 配音慢放 0.72x 动作失真,不可接受);配音略长于素材总量时的兜底用末帧冻结/末段循环(9月4日方案已定,未落地,本次补上) 5. 9月4日方案的另一道保险「选配音时只显示时长匹配的配音(90%~110%)」未落地,属前端 #1750 范围,后端需提供片段预估总时长口径供前端过滤 其他要求(variant-plans 接口、配音 400 守卫、素材级去重、冗余删除、单测、N=1 零回归)不变。
Author
Owner

时长分配方案已定稿(方案A,产品方确认,解除上条「暂停实现选片时长逻辑」的冻结,以此为最终规则)

片段数模板定死 + 配音总时长按片段等比分配,具体算法要求:

  1. 片段数 N = 模板片段数,不增不减;批量变体共用同一模板则 N 相同,但每个变体按各自配音时长独立分配(独立配音模式下 3 个配音时长不同 → 3 个 plan 的每段时长不同,这是正确行为)
  2. 每段目标时长 = 配音时长按 N 等比分配,并计入转场:成片总时长 = Σ片段时长 − Σ转场重叠 ≈ 配音时长(误差 <0.5s);cut 无重叠时 Σ片段时长 = 配音时长。以渲染管线实际转场参数为准计算,禁止再出现「对齐目标漏算转场导致配音被截」
  3. 选片时就按分配后的段长选素材:每段截取时长 = 分配段长,选 start_time 必须满足 start_time + 段长 ≤ 素材总时长;素材时长 < 段长的该素材不得用于该段(自动换更长素材)。例:22s 配音/3段 → 每段约 7.3s,6.2s 的短素材自动出局,这同时解决短素材被迫跨视频复用的问题
  4. 兜底顺序:素材能覆盖 → 正常分配;单素材略短 → 末帧冻结(tpad freeze)或末段循环补齐,禁止慢放;素材总时长明显覆盖不了配音(如配音 58s 素材总量不足)→ 接口明确返回错误提示用户加素材/换配音,禁止硬凑
  5. 渲染期 _align_clips_to_voice_duration 的全局等比裁剪/慢放逻辑删除,仅保留 ±5% 以内微误差修正(选片已精确分配,正常不应触发)
  6. variant-plans 预览接口返回的 clips.duration 必须是上述分配后的真实段长,预览总时长 = Σclips − 转场 ≈ 配音时长,与正式成片同源
  7. 单测:模板4段+配音12s → 每段≈3s、成片≈12s;模板3段+配音22s → 每段≈7.3s 且短素材不入选;素材总量不足 → 明确报错;N=1 单视频零回归
## ✅ 时长分配方案已定稿(方案A,产品方确认,解除上条「暂停实现选片时长逻辑」的冻结,以此为最终规则) **片段数模板定死 + 配音总时长按片段等比分配**,具体算法要求: 1. **片段数 N = 模板片段数**,不增不减;批量变体共用同一模板则 N 相同,但每个变体按各自配音时长独立分配(独立配音模式下 3 个配音时长不同 → 3 个 plan 的每段时长不同,这是正确行为) 2. **每段目标时长 = 配音时长按 N 等比分配**,并计入转场:成片总时长 = Σ片段时长 − Σ转场重叠 ≈ 配音时长(误差 <0.5s);cut 无重叠时 Σ片段时长 = 配音时长。以渲染管线实际转场参数为准计算,禁止再出现「对齐目标漏算转场导致配音被截」 3. **选片时就按分配后的段长选素材**:每段截取时长 = 分配段长,选 start_time 必须满足 start_time + 段长 ≤ 素材总时长;素材时长 < 段长的该素材不得用于该段(自动换更长素材)。例:22s 配音/3段 → 每段约 7.3s,6.2s 的短素材自动出局,这同时解决短素材被迫跨视频复用的问题 4. **兜底顺序**:素材能覆盖 → 正常分配;单素材略短 → 末帧冻结(tpad freeze)或末段循环补齐,禁止慢放;素材总时长明显覆盖不了配音(如配音 58s 素材总量不足)→ 接口明确返回错误提示用户加素材/换配音,禁止硬凑 5. 渲染期 `_align_clips_to_voice_duration` 的全局等比裁剪/慢放逻辑删除,仅保留 ±5% 以内微误差修正(选片已精确分配,正常不应触发) 6. variant-plans 预览接口返回的 clips.duration 必须是上述分配后的真实段长,预览总时长 = Σclips − 转场 ≈ 配音时长,与正式成片同源 7. 单测:模板4段+配音12s → 每段≈3s、成片≈12s;模板3段+配音22s → 每段≈7.3s 且短素材不入选;素材总量不足 → 明确报错;N=1 单视频零回归
Author
Owner

⚠️ 规则更正(产品方 22:24 确认,覆盖此前所有「素材不足报错」表述)

不存在「素材铺不满配音」的概念,任何情况下都不得因素材时长问题报错打断用户。 「素材不足请加素材/换配音」是旧模板时长时代的残留思维,现模板已无时长设置,配音多长成片就多长,系统永远产出与配音等长的成片。

最终规则(替换此前评论中相关条目):

  1. 片段数模板定死;配音总时长等比分到每段(含转场计算)
  2. 选片按分配段长截取:素材长于段长 → 正常截取;素材短于段长 → 该段循环播放/末帧冻结铺满段长,禁止慢放、禁止截断
  3. 批次内素材去重照旧(同批次已用素材后续变体排除)
  4. variant-plans 接口除参数缺失/配音错位(voice_library_ids 缺值/长度不符 400)外,不得以「素材时长不足」为由返回错误

完整需求基线见产品方确认的规则文档,与本工单冲突处以该文档为准。

## ⚠️ 规则更正(产品方 22:24 确认,覆盖此前所有「素材不足报错」表述) **不存在「素材铺不满配音」的概念,任何情况下都不得因素材时长问题报错打断用户。** 「素材不足请加素材/换配音」是旧模板时长时代的残留思维,现模板已无时长设置,配音多长成片就多长,系统永远产出与配音等长的成片。 最终规则(替换此前评论中相关条目): 1. 片段数模板定死;配音总时长等比分到每段(含转场计算) 2. 选片按分配段长截取:素材长于段长 → 正常截取;素材短于段长 → **该段循环播放/末帧冻结铺满段长**,禁止慢放、禁止截断 3. 批次内素材去重照旧(同批次已用素材后续变体排除) 4. variant-plans 接口除参数缺失/配音错位(voice_library_ids 缺值/长度不符 400)外,不得以「素材时长不足」为由返回错误 完整需求基线见产品方确认的规则文档,与本工单冲突处以该文档为准。
Author
Owner

补充(产品方 22:35 明确):预览不渲染

variant-plans 是轻量计算接口:只跑选片/变体计划生成并返回 plan_id + clips,不得创建渲染任务、不得入 worker 队列、不得渲染视频文件。预览由浏览器拿素材原片按 clips 即时播放,要求快速返回。

注意与现有 POST /generation/preview(服务器渲染预览任务,会创建 task 入队)区分,不要复用该套渲染链路;正式批量生成才走渲染任务。

## 补充(产品方 22:35 明确):预览不渲染 variant-plans 是**轻量计算接口**:只跑选片/变体计划生成并返回 plan_id + clips,**不得创建渲染任务、不得入 worker 队列、不得渲染视频文件**。预览由浏览器拿素材原片按 clips 即时播放,要求快速返回。 注意与现有 POST /generation/preview(服务器渲染预览任务,会创建 task 入队)区分,不要复用该套渲染链路;正式批量生成才走渲染任务。
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: xiaoxia/xiaoxia-saas#1749