-
Notifications
You must be signed in to change notification settings - Fork 2
feat: integrate Zhipu AI translation service with comprehensive subtitle translation #228
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
56fd2ef
035a31b
2a69577
456e608
42cdc77
1d5f659
79ac87b
332079c
c841671
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -55,3 +55,4 @@ resources/media-server | |
| .ffmpeg-cache | ||
| .ffprobe-cache | ||
| .cursor | ||
| openspec/changes | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,96 @@ | ||||||||||||||||||
| ## Purpose | ||||||||||||||||||
|
|
||||||||||||||||||
| 配置管理服务 SHALL 为应用程序提供统一的配置项管理功能,包括 API Key、用户偏好设置等的存储、读取和更新。系统 SHALL 支持多种配置类型的安全存储和实时通知机制。 | ||||||||||||||||||
|
Comment on lines
+1
to
+3
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 补充一级标题以通过 MD041。 建议将首行改为顶级标题,示例: -## Purpose
+# 配置管理(Config Management)
+
+## Purpose📝 Committable suggestion
Suggested change
🧰 Tools🪛 markdownlint-cli2 (0.18.1)1-1: First line in a file should be a top-level heading (MD041, first-line-heading, first-line-h1) 🤖 Prompt for AI Agents |
||||||||||||||||||
|
|
||||||||||||||||||
| ## Requirements | ||||||||||||||||||
|
|
||||||||||||||||||
| ### Requirement: Zhipu API Key 配置管理 | ||||||||||||||||||
|
|
||||||||||||||||||
| ConfigManager SHALL 支持 Zhipu API Key 的配置管理功能,包括配置枚举扩展、默认值设置、getter/setter 方法实现,以及配置变更通知机制。 | ||||||||||||||||||
|
|
||||||||||||||||||
| #### Scenario: 配置枚举扩展 | ||||||||||||||||||
|
|
||||||||||||||||||
| - **WHEN** 系统初始化 ConfigManager 时 | ||||||||||||||||||
| - **THEN** ConfigKeys 枚举 SHALL 包含 `ZhipuApiKey = 'zhipuApiKey'` 配置项 | ||||||||||||||||||
| - **AND** 类型系统 SHALL 正确识别新的配置项 | ||||||||||||||||||
|
|
||||||||||||||||||
| #### Scenario: 配置方法实现 | ||||||||||||||||||
|
|
||||||||||||||||||
| - **WHEN** 调用 `configManager.setZhipuApiKey('zhipu-api-key')` 时 | ||||||||||||||||||
| - **THEN** 系统 SHALL 正确保存 API Key | ||||||||||||||||||
| - **AND** 调用 `configManager.getZhipuApiKey()` SHALL 返回设置的值 | ||||||||||||||||||
|
|
||||||||||||||||||
| #### Scenario: 默认值配置 | ||||||||||||||||||
|
|
||||||||||||||||||
| - **WHEN** 新安装应用程序或配置未设置时 | ||||||||||||||||||
| - **THEN** `configManager.getZhipuApiKey()` SHALL 返回空字符串作为默认值 | ||||||||||||||||||
|
|
||||||||||||||||||
| ### Requirement: 配置持久化存储 | ||||||||||||||||||
|
|
||||||||||||||||||
| Zhipu API Key SHALL 使用 electron-conf 进行安全存储,支持配置变更时的自动通知,并提供配置验证和错误处理功能。 | ||||||||||||||||||
|
|
||||||||||||||||||
|
Comment on lines
+30
to
+31
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. “使用 electron-conf 进行安全存储”表述不准确,存在安全姿态风险。
🤖 Prompt for AI Agents |
||||||||||||||||||
| #### Scenario: 配置持久化 | ||||||||||||||||||
|
|
||||||||||||||||||
| - **WHEN** 应用程序重启后 | ||||||||||||||||||
| - **THEN** 之前设置的 Zhipu API Key SHALL 能够正确恢复 | ||||||||||||||||||
| - **AND** 配置值 SHALL 保持不变 | ||||||||||||||||||
|
|
||||||||||||||||||
| #### Scenario: 配置变更通知 | ||||||||||||||||||
|
|
||||||||||||||||||
| - **WHEN** 调用 `configManager.setZhipuApiKey('new-key')` 时 | ||||||||||||||||||
| - **THEN** 系统 SHALL 触发订阅者回调通知配置变更 | ||||||||||||||||||
| - **AND** 回调函数 SHALL 接收到新的配置值 | ||||||||||||||||||
|
|
||||||||||||||||||
| ### Requirement: 默认值管理 | ||||||||||||||||||
|
|
||||||||||||||||||
| ConfigManager SHALL 在 defaultValues 对象中包含所有配置项的默认值,新添加的 Zhipu API Key 配置项 SHALL 有相应的默认值设置。 | ||||||||||||||||||
|
|
||||||||||||||||||
| #### Scenario: 默认值配置更新 | ||||||||||||||||||
|
|
||||||||||||||||||
| - **WHEN** 初始化 defaultValues 对象时 | ||||||||||||||||||
| - **THEN** 对象 SHALL 包含 `[ConfigKeys.ZhipuApiKey]: ''` 配置项 | ||||||||||||||||||
| - **AND** 默认值 SHALL 为空字符串 | ||||||||||||||||||
|
|
||||||||||||||||||
| ### Requirement: 配置类型定义 | ||||||||||||||||||
|
|
||||||||||||||||||
| 配置管理 SHALL 确保所有配置项都有明确的 TypeScript 类型定义,保证编译时类型安全。 | ||||||||||||||||||
|
|
||||||||||||||||||
| #### Scenario: 类型定义完整性 | ||||||||||||||||||
|
|
||||||||||||||||||
| - **WHEN** 使用 `ConfigKeys.ZhipuApiKey` 时 | ||||||||||||||||||
| - **THEN** TypeScript 编译器 SHALL 正确识别类型 | ||||||||||||||||||
| - **AND** 不应产生类型错误 | ||||||||||||||||||
|
|
||||||||||||||||||
| ## 现有配置项 | ||||||||||||||||||
|
|
||||||||||||||||||
| ### Deepgram 配置 | ||||||||||||||||||
|
|
||||||||||||||||||
| - **DeepgramApiKey**: Deepgram 语音识别 API Key | ||||||||||||||||||
| - **DefaultLanguage**: 默认转写语言 | ||||||||||||||||||
| - **Model**: 转写模型选择 | ||||||||||||||||||
|
|
||||||||||||||||||
| ### 通用配置 | ||||||||||||||||||
|
|
||||||||||||||||||
| - 各种用户偏好设置 | ||||||||||||||||||
| - 应用程序行为配置 | ||||||||||||||||||
| - 界面显示选项 | ||||||||||||||||||
|
|
||||||||||||||||||
| ## 技术要求 | ||||||||||||||||||
|
|
||||||||||||||||||
| ### 存储机制 | ||||||||||||||||||
|
|
||||||||||||||||||
| - 使用 electron-conf 进行配置持久化 | ||||||||||||||||||
| - 支持配置的原子性更新 | ||||||||||||||||||
| - 提供配置变更的事件通知 | ||||||||||||||||||
|
|
||||||||||||||||||
| ### 类型安全 | ||||||||||||||||||
|
|
||||||||||||||||||
| - 所有配置项都有明确的 TypeScript 类型定义 | ||||||||||||||||||
| - 枚举值确保配置键的一致性 | ||||||||||||||||||
| - 编译时类型检查防止配置错误 | ||||||||||||||||||
|
|
||||||||||||||||||
| ### 错误处理 | ||||||||||||||||||
|
|
||||||||||||||||||
| - 配置读取失败时提供合理的默认值 | ||||||||||||||||||
| - 配置写入失败时记录错误日志 | ||||||||||||||||||
| - 支持配置验证和格式检查 | ||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,168 @@ | ||
| ## Purpose | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 修复 markdownlint MD041:首行应为一级标题 将首行 “## Purpose” 提升为 H1。 -## Purpose
+# Purpose🧰 Tools🪛 markdownlint-cli2 (0.18.1)1-1: First line in a file should be a top-level heading (MD041, first-line-heading, first-line-h1) 🤖 Prompt for AI Agents |
||
|
|
||
| 字幕翻译服务 SHALL 使用 Zhipu AI 的 glm-4.5-flash 模型将生成的字幕自动翻译成中文,为语言学习者提供更好的学习体验。系统 SHALL 支持批量处理、智能翻译、错误重试和数据库集成。 | ||
|
|
||
| ## Requirements | ||
|
|
||
| ### Requirement: 翻译服务核心功能 | ||
|
|
||
| SubtitleTranslationService SHALL 提供字幕翻译的核心功能,包括服务初始化、批量翻译处理和翻译结果管理。 | ||
|
|
||
| #### Scenario: 服务初始化 | ||
|
|
||
| - **WHEN** 创建新的 SubtitleTranslationService 实例时 | ||
| - **THEN** 服务 SHALL 能够正确初始化而不抛出异常 | ||
| - **AND** SHALL 准备好接收翻译请求 | ||
|
|
||
| #### Scenario: 批量翻译调用 | ||
|
|
||
| - **WHEN** 调用 `translationService.translateSubtitles()` 时 | ||
| - **THEN** 系统 SHALL 返回包含成功状态和翻译映射的结果 | ||
| - **AND** SHALL 支持指定目标语言、API Key 和视频文件名 | ||
|
|
||
| ### Requirement: 智能翻译处理 | ||
|
|
||
| 翻译服务 SHALL 构建包含上下文信息的智能翻译提示词,提供高质量的本土化翻译。 | ||
|
|
||
| #### Scenario: 智能提示词构建 | ||
|
|
||
| - **WHEN** 构建翻译提示词时 | ||
| - **THEN** 系统 SHALL 包含视频文件名作为上下文 | ||
| - **AND** SHALL 为每条字幕提供前后字幕作为翻译参考 | ||
| - **AND** SHALL 明确要求本土化翻译,避免直译 | ||
|
|
||
| #### Scenario: 批量翻译处理 | ||
|
|
||
| - **WHEN** 处理大量字幕时 | ||
| - **THEN** 系统 SHALL 将字幕分成 10-20 条的小批次 | ||
| - **AND** SHALL 为每批字幕提供前后上下文 | ||
| - **AND** SHALL 最多并发处理 2 个批次 | ||
|
|
||
| ### Requirement: 错误处理和重试机制 | ||
|
|
||
| 翻译服务 SHALL 实现完善的错误处理机制,确保系统稳定性。 | ||
|
|
||
| #### Scenario: 网络错误重试 | ||
|
|
||
| - **WHEN** 遇到网络错误时 | ||
| - **THEN** 系统 SHALL 自动重试最多 3 次 | ||
| - **AND** SHALL 使用指数退避策略 | ||
| - **AND** 最终失败时 SHALL 返回错误信息 | ||
|
|
||
| #### Scenario: API Key 错误处理 | ||
|
|
||
| - **WHEN** API Key 无效时 | ||
| - **THEN** 系统 SHALL 立即失败并返回适当的错误信息 | ||
| - **AND** SHALL 不进行重试操作 | ||
|
|
||
| ### Requirement: 数据库集成 | ||
|
|
||
| 翻译服务 SHALL 支持将翻译结果批量更新到数据库中。 | ||
|
|
||
| #### Scenario: 批量更新翻译 | ||
|
|
||
| - **WHEN** 翻译完成时 | ||
| - **THEN** 系统 SHALL 使用字幕 ID 映射翻译结果 | ||
| - **AND** SHALL 批量更新数据库中的 translatedText 字段 | ||
| - **AND** 更新失败时 SHALL 记录详细错误信息 | ||
|
|
||
| ### Requirement: ASR 服务集成 | ||
|
|
||
| 翻译服务 SHALL 与 ASR 字幕生成流程无缝集成。 | ||
|
|
||
| #### Scenario: 自动翻译触发 | ||
|
|
||
| - **WHEN** ASR 字幕保存到数据库后且配置了 Zhipu API Key 时 | ||
| - **THEN** 系统 SHALL 自动启动后台翻译任务 | ||
| - **AND** SHALL 不阻塞字幕生成的主流程 | ||
|
|
||
| #### Scenario: 翻译失败隔离 | ||
|
|
||
| - **WHEN** 翻译任务失败时 | ||
| - **THEN** 系统 SHALL 记录错误日志 | ||
| - **AND** SHALL 不影响字幕生成的成功状态 | ||
| - **AND** 原始字幕 SHALL 正常显示给用户 | ||
|
|
||
| ### Requirement: 数据库层扩展 | ||
|
|
||
| 数据访问层 SHALL 支持字幕翻译的批量更新操作。 | ||
|
|
||
| #### Scenario: 批量更新方法 | ||
|
|
||
| - **WHEN** 调用 `updateSubtitleTranslations()` 方法时 | ||
| - **THEN** 系统 SHALL 接收字幕 ID 和翻译文本的映射 | ||
| - **AND** SHALL 支持事务处理确保数据一致性 | ||
| - **AND** SHALL 返回详细的更新统计信息 | ||
|
|
||
| ## 与其他服务的集成 | ||
|
|
||
| ### ASR 服务集成 | ||
|
|
||
| #### Requirement: ASR-015: 在 ASR 流程中集成翻译功能 | ||
|
|
||
| **Description**: 在字幕生成完成后自动启动后台翻译任务 | ||
|
|
||
| **Acceptance Criteria**: | ||
|
|
||
| - 在字幕保存到数据库后检查 Zhipu API Key 配置 | ||
| - 使用 Promise.resolve().then() 启动后台任务,不阻塞主流程 | ||
| - 翻译过程完全静默进行,不影响用户操作 | ||
| - 翻译完成后更新数据库中的 translatedText 字段 | ||
|
|
||
| **File**: `src/main/services/ASRSubtitleService.ts` | ||
|
|
||
| #### Scenario: ASR-015-01: 自动翻译触发 | ||
|
|
||
| ```typescript | ||
| // 在 generateSubtitle 方法的字幕保存后 | ||
| if (subtitleLibraryId && configManager.getZhipuApiKey()) { | ||
| // 应该启动后台翻译任务 | ||
| // 不应该阻塞字幕生成流程 | ||
| } | ||
| ``` | ||
|
|
||
| #### Scenario: ASR-015-02: 翻译失败处理 | ||
|
|
||
| ```typescript | ||
| // 翻译任务失败时 | ||
| // 应该记录错误日志 | ||
| // 不应该影响字幕生成的成功状态 | ||
| // 原始字幕应该正常显示给用户 | ||
| ``` | ||
|
|
||
| ### 数据库层集成 | ||
|
|
||
| #### Requirement: DB-010: 添加批量更新翻译方法 | ||
|
|
||
| **Description**: 在数据访问层添加批量更新字幕翻译的方法 | ||
|
|
||
| **Acceptance Criteria**: | ||
|
|
||
| - 添加 `updateSubtitleTranslations(subtitleLibraryId, translations)` 方法 | ||
| - 接收字幕 ID 和翻译文本的映射 | ||
| - 支持事务处理,确保数据一致性 | ||
| - 提供详细的错误信息和统计结果 | ||
|
|
||
| **File**: `src/main/db/dao.ts` | ||
|
|
||
| #### Scenario: DB-010-01: 批量更新实现 | ||
|
|
||
| ```typescript | ||
| const result = await db.subtitleLibrary.updateSubtitleTranslations(subtitleLibraryId, translations) | ||
| // 应该返回更新统计信息 | ||
|
Comment on lines
+136
to
+152
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major 规范与实现存在“批量更新”方法命名偏差 规范使用 |
||
| // 应该处理部分更新的情况 | ||
| ``` | ||
|
|
||
| ## 技术约束 | ||
|
|
||
| - **当前版本仅支持翻译为中文**(代码中需要 TODO 标记未来扩展) | ||
| - **使用 zhipu-ai-provider npm 包**(已安装) | ||
| - **遵循项目的异步文件操作规范** | ||
| - **使用 loggerService 记录日志** | ||
|
|
||
| ## 性能要求 | ||
|
|
||
| - 批量处理大小:10-20 条字幕/批次 | ||
| - 并发批次数量:最多 2 个 | ||
| - 重试策略:指数退避,最多 3 次重试 | ||
| - 翻译过程必须在后台进行,不阻塞用户操作 | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
workflow_run 分支:使用“最新发布”可能与触发的运行不匹配,存在同步错误风险。
示例最小修改(仅示意关键片段):