Skip to content

feat(proofread): 支持角色命名、纠错与批量管理 - #422

Merged
buxuku merged 2 commits into
buxuku:mainfrom
nightt5879:nightt5879/feat-420-proofread-speaker-management
Aug 5, 2026
Merged

feat(proofread): 支持角色命名、纠错与批量管理#422
buxuku merged 2 commits into
buxuku:mainfrom
nightt5879:nightt5879/feat-420-proofread-speaker-management

Conversation

@nightt5879

@nightt5879 nightt5879 commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

变更内容

  • 将校对 sidecar 升级为 v2,新增稳定角色名册(不可变 ID、可编辑名称、语义色)与显式主要角色;读取 v1 时自动生成名册并清理已有技术标签
  • 在有角色元数据的字幕行展示可读名称、稳定颜色、未分配与多人重叠状态;点击标签即可增删角色、新建角色或调整主要角色
  • 新增角色管理弹层,支持统一重命名、换色、按角色定位、移动全部字幕、合并误拆角色及删除空角色;批量操作先展示目标角色和影响句数
  • 增加全部、具体角色、未分配、多人重叠筛选,并与现有失败项筛选组合;过滤状态下禁用区间字幕合并,避免可见索引与真实索引混淆
  • 将角色归属和名册快照接入现有撤销 / 重做栈;拆分、合并、删除、时间调整、重新对齐、保存和恢复继续保留角色数据
  • 保存默认只写结构化角色元数据,不修改字幕正文;可选在字幕文件中写入当前用户可见角色名,主要角色优先且保留多人信息
  • 补齐中英文 i18n、校对与角色分离使用文档,以及 sidecar 迁移、归属规范化、批量移动和导出前缀专项测试

安全与兼容说明

  • 没有 sidecar 或角色信息的普通字幕保持原校对界面和保存流程,不增加额外操作负担
  • v1 sidecar 读取时在内存中迁移,首次保存升级为 v2;重命名不会改变 cue 的稳定角色 ID
  • 未分配 以空归属表示,不伪造角色 ID;多人 cue 保留完整 speakerIds,主要角色通过独立字段持久化
  • 角色名称仅在用户明确勾选后于字幕输出边界渲染;校对正文、AI 优化输入和 sidecar 文本保持无角色前缀
  • 角色名限制长度并清理控制字符,导出时转义方括号;颜色限制在兼顾深浅主题的固定色板内,界面始终同时显示名称

验证

  • npm run test:proofread-speakers:31/31(v1→v2 迁移、名册生成、主要角色、多角色去重、批量移动、名称清理与导出前缀)
  • npm run test:speaker-diarization:配置 10/10,对齐 30/30
  • npm run test:dubbing:151/151
  • npm run test:alignment-e2e:离线 31/31
  • npm run check:i18n
  • npm run build:Renderer + Main production build 通过
  • Prettier、git diff --check

尚未覆盖

  • 未用真实角色分离任务完整跑一次 GUI 端到端交互;数据迁移、角色领域操作、相关下游回归与生产构建已覆盖

Closes #420

@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] 保证“未分配”状态能够持久化 — /renderer/components/proofread/SpeakerCueControl.tsx:162-162
    对已有角色的字幕执行此操作后,normalizeSpeakerAssignment 会删除 speakerIds;保存时 updateProofreadDataFromSubtitles 又通过 subtitle.speakerIds || previous?.speakerIds 回退到旧角色。因此界面暂时显示“未分配”,但保存并重新打开后原角色会恢复。保存逻辑需要区分显式清空与旧数据缺失,例如保留空数组或按属性是否存在判断。

  • [P1] 时间调整后仍以手工角色修改为准 — /main/helpers/proofreadData.ts:293-297
    当用户先调整 cue 时间、再纠正或批量移动其角色且尚未保存时,上面的 speakerIds 来自 realignSpeakerIdsForCue(existing.cues);只要新区间仍与旧 cue 重叠,该函数就返回旧角色并忽略当前字幕上的 fallback,最终这里会把手工修改覆盖掉。导出的字幕甚至可能使用新角色,而 sidecar 在重新打开后恢复旧角色;应只对没有显式编辑过角色的行重新对齐,或在时间编辑时完成对齐后直接持久化当前状态。

@nightt5879

Copy link
Copy Markdown
Contributor Author

已在追加提交 7fd2266 中处理这两项持久化问题:

  1. “未分配”可持久化:现在保留显式 speakerIds: [],并与“没有角色元数据”(属性缺失)区分;保存、重新读取和撤销/重做都不会再回退到旧角色。
  2. 人工角色修改优先于时间重对齐:人工单句分配、新建角色分配和批量移动会写入 speakerAssignmentSource: manual;保存时仅对未人工修改的自动归属执行时间重对齐,人工选择(包括显式未分配)始终以当前行数据为准。该来源标记会写入 sidecar,重新打开后仍然有效。

同时补充了显式空归属、缺失元数据区分、人工来源恢复及重对齐门禁测试。

验证:

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

麻烦再帮忙 review 一下,谢谢。

@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.

感谢提交,已经真机验证通过

@buxuku
buxuku merged commit 5a74ce0 into buxuku:main Aug 5, 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(proofread): 在字幕校对台支持角色命名、纠错与批量管理

2 participants