Skip to content
This repository was archived by the owner on Jul 17, 2026. It is now read-only.

refactor: 提取文件、下载和音乐文件服务以重构 IPC 模块 - 将文件操作、下载和音乐元数据处理逻辑提取到独立的服务类中 - 重构 ipc-file.ts 以使用新服务,减少代码重复并提高可维护性 - 在 SongCard 组件中使用 formatFileSize 格式化文件大小显示 - 公开 LocalMusicService 的 paths getter 和错误常量ipc 01 - #855

Merged
kazukokawagawa merged 7 commits into
dev-ipcfrom
dev-ipc-01
Feb 10, 2026

Conversation

@kazukokawagawa

Copy link
Copy Markdown
Collaborator

No description provided.

- 将文件操作、下载和音乐元数据处理逻辑提取到独立的服务类中
- 重构 ipc-file.ts 以使用新服务,减少代码重复并提高可维护性
- 在 SongCard 组件中使用 formatFileSize 格式化文件大小显示
- 公开 LocalMusicService 的 paths getter 和错误常量
- 将音乐库同步的扫描、封面处理与分块发送逻辑封装到 LocalMusicService.syncLibrary 方法
- 重构 MusicFileService 的元数据解析为分批处理以避免内存压力
- 将 DownloadService 的下载流程拆分为准备、执行、后处理等独立方法
- 简化 IPC 处理程序,移除重复的封面处理与分块逻辑
- 将 DownloadService 改为 EventEmitter 以支持进度事件
- 在 IPC 层添加下载映射,将进度事件转发给对应的渲染进程
- 重构下载流程,分离原始下载与元数据处理逻辑
- 使用 Electron net 模块下载专辑封面并临时存储
- 提供默认下载选项,增强代码健壮性
- 提取网络下载功能到独立的 network.ts 工具模块
- 提取艺术家格式化功能到独立的 artist.ts 工具模块
- 重构 DownloadService,分离下载逻辑与后处理逻辑
- 简化 ipc-file.ts 中的下载进度广播逻辑,移除 WebContents 映射
- 统一下载入口为 downloadMusic 方法,增强参数处理
使用展开运算符合并默认值时,如果传入的选项包含显式的 undefined,会错误地覆盖默认值。改为使用空值合并运算符(??)确保默认值只在选项为 null 或 undefined 时生效。

同时优化封面下载的文件名生成,通过 URL 解析去除查询参数,避免生成非法文件名。
优化媒体会话封面处理逻辑,在更新播放歌曲时传递已获取的封面数据给媒体会话管理器,避免对 blob URL 封面进行重复的网络请求。同时将 blob URL 的获取方式从 axios 统一为 fetch 以保持一致性。
@kazukokawagawa kazukokawagawa self-assigned this Feb 9, 2026
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @kazukokawagawa, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

此拉取请求的核心目标是重构Electron应用程序的IPC模块,通过将文件、下载和音乐元数据处理等相关功能拆分到独立的Service类中,从而提高代码的组织性、可读性和可维护性。这一改变使得IPC层更加轻量,专注于消息传递,而业务逻辑则集中在各自的服务中。同时,还对前端组件和媒体会话管理进行了优化,以适应新的架构并提升性能。

Highlights

  • IPC模块重构: 将ipc-file.ts中的文件操作、下载和音乐元数据处理逻辑提取到独立的FileService、DownloadService和MusicFileService服务类中,显著减少了ipc-file.ts的复杂性,提高了模块化和可维护性。
  • 本地音乐服务增强: LocalMusicService新增了syncLibrary方法,封装了音乐库扫描、封面处理和分块传输的逻辑,并公开了paths getter和ERROR_SCAN_IN_PROGRESS常量,使其功能更完善、易于使用。
  • 下载服务独立化: 新增DownloadService,集中处理文件下载逻辑,包括下载选项的标准化、元数据准备、下载进度事件的发射以及下载取消功能。
  • 音乐文件服务独立化: 新增MusicFileService,封装了所有音乐文件相关的操作,如获取音乐文件列表、元数据、歌词和封面,并优化了getMusicFiles方法以支持批量处理。
  • 文件服务独立化: 新增FileService,集中管理通用的文件系统操作,如文件存在性检查、保存、删除、文件夹打开以及路径选择等。
  • 前端组件优化: SongCard组件现在使用formatFileSize辅助函数来格式化显示文件大小,提升了用户体验。
  • 媒体会话管理优化: MediaSessionManager和PlayerController中的媒体会话更新逻辑得到优化,现在可以传递封面数据的Uint8Array,避免重复下载,提高了效率。
Changelog
  • electron/main/ipc/ipc-file.ts
    • 移除大量文件系统操作、音乐元数据解析和下载逻辑。
    • 引入并实例化FileService、DownloadService和MusicFileService。
    • 将所有文件、下载和音乐相关的IPC处理程序委托给新的服务类。
    • 简化local-music-sync处理程序,现在调用LocalMusicService.syncLibrary方法。
    • 移除内部的chunkArray辅助函数。
  • electron/main/services/DownloadService.ts
    • 新增文件,实现DownloadService类。
    • 提供downloadMusic方法,处理文件下载,包括选项标准化、元数据准备和后处理(如保存歌词)。
    • 管理活跃下载任务,并发出progress事件。
    • 实现cancelDownload方法以取消指定ID的下载任务。
    • 包含内部辅助方法normalizeOptions、performDownload、postProcessMusic、prepareMetadata、processMetadata、saveLyric和handleProgress。
  • electron/main/services/FileService.ts
    • 新增文件,实现FileService类。
    • 提供fileExists、saveFile、getDefaultDir、deleteFile、openFolder、chooseImage、choosePath、checkIfSamePath、checkIfSubfolder和saveFileContent等通用文件操作方法。
  • electron/main/services/LocalMusicService.ts
    • 新增syncLibrary方法,封装音乐库同步逻辑,包括封面处理和分块发送轨道数据。
    • 将paths getter的访问权限从private修改为public。
    • 新增静态常量ERROR_SCAN_IN_PROGRESS,用于表示扫描进行中的错误状态。
  • electron/main/services/MusicFileService.ts
    • 新增文件,实现MusicFileService类。
    • 提供getMusicFiles、getMusicMetadata、setMusicMetadata、getMusicLyric、getMusicCover和readLocalLyric等音乐文件相关操作方法。
    • 优化getMusicFiles方法,采用批量处理以避免创建过多Promise。
    • getMusicFiles和getMusicMetadata方法现在返回文件大小(fileSize)为字节数,以便前端进行格式化。
    • 优化getMusicLyric方法中的外部歌词搜索逻辑,提高了效率。
  • electron/main/utils/artist.ts
    • 新增文件,提供formatArtist辅助函数,用于格式化艺术家名称。
  • electron/main/utils/network.ts
    • 新增文件,提供downloadFromUrl辅助函数,用于从URL下载文件。
  • src/components/Card/SongCard.vue
    • 更新文件大小显示逻辑,使用formatFileSize辅助函数进行格式化。
    • 从@/utils/helper导入formatFileSize。
  • src/core/player/MediaSessionManager.ts
    • 修改updateMetadata方法,使其接受可选的coverBuffer参数,以避免重复下载封面图片。
    • 在获取封面数据时,增加了对blob: URL的处理逻辑,使用fetch而不是axios。
  • src/core/player/PlayerController.ts
    • 修改封面获取逻辑,现在会检查是否需要重新获取封面。
    • 在获取到封面数据后,将coverBuffer传递给mediaSessionManager.updateMetadata,以优化媒体会话的更新过程。
Activity
  • 作者kazukokawagawa创建了此拉取请求,旨在对Electron应用程序的IPC模块进行大规模重构。
  • 此PR引入了三个新的服务类(FileService, DownloadService, MusicFileService),以实现职责分离和代码解耦。
  • 现有的ipc-file.ts文件已被大幅简化,其功能已委托给新创建的服务。
  • LocalMusicService得到了增强,增加了新的同步方法和公开的属性。
  • 前端的SongCard组件和核心播放器逻辑已更新,以适应新的后端服务架构。
  • 新增了两个工具文件(artist.ts和network.ts)来支持新的服务功能。
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

本次 PR 对 IPC 模块进行了大规模重构,将文件操作、下载、音乐元数据处理等逻辑提取到了独立的 Service 类中。这是一个非常好的改进,使得 ipc-file.ts 的代码变得极为简洁清晰,大大提高了代码的可维护性和可测试性。新的 Service 类(FileService, DownloadService, MusicFileService)职责明确,代码组织良好。此外,前端代码也进行了相应的适配,例如在 SongCard 中使用 formatFileSize,以及优化了 MediaSessionManager 的封面处理逻辑,避免了不必要的网络请求。

整体来看,这是一次高质量的重构。我发现了一些小问题,主要涉及事件通知的准确性和错误日志记录,已在具体的 review comments 中提出。修复这些问题后,代码将更加健壮。

Comment on lines 61 to +65
event.sender.send("music-sync-complete", {
success: true,
});

return { success: true };
return result;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

localMusicService.syncLibrary 在扫描进行中时会返回 { success: false, message: '...' }。当前代码在这种情况下仍然会发送 music-sync-complete 事件并附带 { success: true },这与实际结果不符,可能会误导前端。建议将 syncLibrary 的结果直接透传给 music-sync-complete 事件。

      event.sender.send("music-sync-complete", {
        success: result.success,
        message: result.message,
      });

      return result;

Comment on lines +266 to +270
try {
progressData = JSON.parse(progressData);
} catch {
return;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

捕获到错误时,建议记录日志,而不是静默处理。这有助于在出现问题时进行调试。之前的实现中是有日志记录的。

        try {
          progressData = JSON.parse(progressData);
        } catch (e) {
          ipcLog.error("Failed to parse progress json", e);
          return;
        }

@kazukokawagawa
kazukokawagawa changed the base branch from dev to dev-ipc February 10, 2026 06:58
@kazukokawagawa
kazukokawagawa merged commit ab1e74d into dev-ipc Feb 10, 2026
4 checks passed
@kazukokawagawa
kazukokawagawa deleted the dev-ipc-01 branch February 10, 2026 07:01
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant