Skip to content

feat(dubbing): 按角色批量分配音色并支持单句覆盖 - #423

Merged
buxuku merged 2 commits into
buxuku:mainfrom
nightt5879:nightt5879/feat-421-dubbing-speaker-voices
Aug 6, 2026
Merged

feat(dubbing): 按角色批量分配音色并支持单句覆盖#423
buxuku merged 2 commits into
buxuku:mainfrom
nightt5879:nightt5879/feat-421-dubbing-speaker-voices

Conversation

@nightt5879

@nightt5879 nightt5879 commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

变更内容

  • 配音会话读取同源校对 sidecar v1/v2,按时间轴对齐角色名册、全部角色归属与主要角色;流水线和独立工作台入口均可传递 sidecar
  • 新增“角色与音色”配置区,按首次出现顺序显示角色颜色、名称、句数/时长、音色选择和代表句试听;多人项目要求每个有效角色明确选择音色,也可明确跟随全局音色
  • 合成音色按“单句覆盖 > 主要角色映射 > 全局音色”解析;未分配字幕使用全局音色,多人 cue 保留全部标签但只按主要角色生成一条音轨
  • 字幕列表显示角色、未分配、多人重叠、跟随角色及单句覆盖状态;切换引擎后不可用的角色音色和单句覆盖会要求重新选择
  • 修改角色音色后,只将继承该角色且已有产物的 cue 标记为“需要更新”;支持按角色或全部重新生成,并增加列表筛选和导出前确认
  • 重生成使用独立尝试文件,成功后才替换旧产物;失败时保留可试听的旧音频并继续标记过期,避免静默导出旧音色
  • 会话持久化角色名册、映射、cue 归属、实际合成音色和 stale 状态;角色重命名沿用稳定 ID,合并出不同旧映射时要求用户重新确认
  • 补齐中英文 i18n、多人配音文档,以及解析优先级、配置门禁、引擎切换、stale 判断、sidecar 对齐和旧会话恢复专项测试

安全与兼容说明

  • 无 sidecar、无有效角色或只有一个角色的字幕继续使用原有全局音色流程,不增加强制配置步骤
  • 旧配音 session 的新增字段均为可选;恢复时回落空角色数据,并可用最近一次全局音色补全旧产物的 stale 判断
  • “使用全局音色”使用显式哨兵值,与尚未配置区分;未分配 cue 不伪造角色 ID
  • 单句覆盖不参与角色批量更新;清除覆盖后重新继承主要角色,角色变更只按解析后的实际音色判断是否需要重生成
  • 删除或已不活跃角色遗留的映射冲突不会阻断生成;当前有效角色发生多映射合并时仍必须显式确认

验证

  • npm run test:dubbing:172/172
  • npm run test:proofread-speakers:31/31
  • npm run test:speaker-diarization:配置 10/10,对齐 30/30
  • npm run check:i18n
  • npm run build:Renderer + Main production build 通过
  • Prettier、git diff --check

尚未覆盖

  • 未用真实多人角色任务完整跑一次 GUI 端到端交互;sidecar 对齐、角色音色领域逻辑、相关上下游回归与生产构建已覆盖
  • npm run test:pipeline 在 Windows 上仍有 4 个 POSIX 路径分隔符断言失败;已在未修改的 upstream/main 复现,非本 PR 引入

Closes #421

@buxuku buxuku left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

感谢PR, 有两个 P1 希望修复一下

[P1] 允许 headless 配音回退到全局音色 — main/helpers/dubbing/dubbingProcessor.ts:823-829

流水线在创建/恢复带 file.proofreadDataFile 的会话时会加载多角色元数据,但在 runDubStage 调用 runDubbingBatch 之前,没有 UI 步骤去填充 session.speakerVoiceMap。因此,对任意多角色 sidecar,该门禁会直接中止自动配音并报「还有 N 个角色未选择音色」,而不是使用任务里已配置的全局音色。建议在 headless/流水线场景跳过该要求,或在开始前将未映射角色初始化为全局哨兵值。

[P1] 在流水线重建路径上拦截 stale 角色音频 — main/helpers/dubbing/dubbingProcessor.ts:1251-1254

当前 stale 音频检查只覆盖手动的 exportDubbing IPC 路径;检查员放行 / 流水线续跑则通过 rebuildDubTrackForFile → buildDubTrack 直接产出成片。若审查者在配音工作台修改了角色音色但未重生成,标记为 needsUpdate 的 cue 仍会静默进入流水线输出。需要在共享的 track 构建/重建路径上执行同样的检查。

@nightt5879

Copy link
Copy Markdown
Contributor Author

已在追加 commit dfee069 中修复这两个 P1:

  1. Headless 配音回退全局音色

    • 自动流水线在进入批量合成前,会把有实际字幕且尚未映射的角色显式初始化为“跟随任务全局音色”。
    • 已有角色映射保持不变;存在多个旧映射的真实角色合并冲突不会被全局回退覆盖,仍由原门禁阻止并要求人工确认。
    • 新增回归覆盖“保留已有映射 + 补全未配置角色”及“不覆盖合并冲突”。
  2. 流水线重建拦截 stale 音频

    • stale 检查已从仅限 exportDubbing 下沉到共享 buildDubTrack
    • 工作台导出、首次流水线构轨,以及 rebuildDubTrackForFile 检查员放行/续跑重建都会传入当前全局音色、重新计算 stale,并在存在旧音色产物时停止构轨。
    • 因此未重生成的角色音频不会再静默进入配音轨或最终成片。

验证:

  • npm run test:dubbing:172/172
  • npm run test:proofread-speakers:31/31
  • npm run test:speaker-diarization:配置 10/10,对齐 30/30
  • npm run check:i18n
  • npm run build:Renderer + Main production build通过
  • Prettier、git diff --check

@buxuku
buxuku merged commit eab5c02 into buxuku:main Aug 6, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(dubbing): 按角色批量分配音色并支持单句覆盖

2 participants