Skip to content

✨ feat: 支持切源播放#795

Merged
imsyy merged 10 commits into
devfrom
dev-cy
Feb 1, 2026
Merged

✨ feat: 支持切源播放#795
imsyy merged 10 commits into
devfrom
dev-cy

Conversation

@kazukokawagawa
Copy link
Copy Markdown
Collaborator

No description provided.

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

此拉取请求的核心目标是增强音乐播放器的灵活性和用户体验,通过引入一个全新的功能,允许用户在播放歌曲时手动选择不同的音频源。这不仅提供了更多的播放选项,还通过保存用户偏好,确保了播放体验的个性化和一致性。底层的逻辑也得到了优化,能够更高效地发现和管理可用的音频源。

Highlights

  • 音频源切换功能: 在播放器界面引入了手动切换歌曲音频源的功能,用户现在可以在多个可用源之间进行选择。
  • 音频源偏好保存: 播放器现在会记住用户为特定歌曲选择的音频源偏好,并在下次播放时尝试使用该偏好源。
  • 并行获取与智能选择: 优化了音频源获取逻辑,现在会并行请求官方源和所有可用的解锁源,并根据用户偏好和默认策略智能选择最佳播放源。
  • UI集成: 在播放器元数据组件中添加了新的UI元素(下拉选择器),用于显示和选择可用的音频源。
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.

Copy link
Copy Markdown
Contributor

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

Choose a reason for hiding this comment

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

Code Review

这个 PR 增加了切换音源播放的功能,这是一个很棒的特性。整体实现非常不错,代码结构清晰,尤其是在 SongManager 中对音源获取逻辑的重构,通过并行请求提高了性能,并支持了音源偏好设置。我在 SongManager.ts 中发现了一些可以改进的地方,主要关于代码整洁性和缓存逻辑的一致性。请查看具体的评论。

console.log(`🔓 [${songId}] 解锁成功`, unlockUrl);
return unlockUrl;
// 解锁源
// candidates.push(...unlockSources);
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

这行被注释掉的代码似乎是开发过程中遗留的。为了提高代码的清晰度和可维护性,建议将其移除。

Comment thread src/core/player/SongManager.ts Outdated
Comment on lines +538 to +544
this.triggerCacheDownload(songId, selected.url);
// 检查本地缓存是否已存在(覆盖远程 URL)
const cachedUrl = await this.checkLocalCache(songId);
if (cachedUrl) {
console.log(`🚀 [${songId}] 使用本地缓存 (Source: ${selected.source})`);
return { ...selected, url: cachedUrl };
}
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

当前处理解锁音源缓存的逻辑与 getOnlineUrl 中处理官方音源的逻辑不一致。它会先触发下载,然后检查任何已存在的缓存文件,这可能导致播放的音质与预期不符。此外,在触发下载时没有传递音质参数。

为了保证一致性并播放正确的音质,建议先检查特定音质的缓存文件是否存在。如果未找到,再触发下载并使用远程 URL。这样也确保了音质参数能被传递给 triggerCacheDownload

          // 检查本地缓存是否已存在
          const cachedUrl = await this.checkLocalCache(songId, selected.quality);
          if (cachedUrl) {
            console.log(`🚀 [${songId}] 使用本地缓存 (Source: ${selected.source})`);
            return { ...selected, url: cachedUrl };
          }
          // 未找到缓存,触发下载并使用远程 URL
          this.triggerCacheDownload(songId, selected.url, selected.quality);

@kazukokawagawa
Copy link
Copy Markdown
Collaborator Author

/gemini review

Copy link
Copy Markdown
Contributor

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

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a great new feature allowing users to switch audio sources during playback. The implementation includes significant and thoughtful refactoring of the core player logic, particularly in PlayerController.ts and SongManager.ts, which improves performance by preloading audio and provides a more flexible source selection mechanism. The code is generally well-structured. I have a couple of suggestions to enhance type safety and improve the consistency of the caching logic.

Comment thread src/components/Modal/ThemeConfig.vue Outdated

// 3. 随机变体
const randomVariant = variantOptions[Math.floor(Math.random() * variantOptions.length)];
settingStore.themeVariant = randomVariant.value as any;
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

The as any cast here hides type information and should be avoided for better type safety and maintainability. The value from randomVariant should be compatible with settingStore.themeVariant. Please consider removing the cast or using a more specific type assertion.

  settingStore.themeVariant = randomVariant.value as typeof settingStore.themeVariant;

Comment on lines +403 to +420
if (result.code === 200 && result.url) {
const unlockUrl = result.url;
// 推断音质
let quality = QualityType.HQ;
if (unlockUrl && (unlockUrl.includes(".flac") || unlockUrl.includes(".wav"))) {
quality = QualityType.SQ;
}
// 触发缓存下载
this.triggerCacheDownload(songId, unlockUrl);

return {
id: songId,
url: unlockUrl,
isUnlocked: true,
quality,
source: source,
};
}
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

In getAudioSourceFromSpecificServer, when handling an unlock source, the code directly calls triggerCacheDownload without first checking if a cached version of the song already exists. This is inconsistent with the logic in getOnlineUrl and the refactored getAudioSource, which both check for a cached file before attempting to download. This can lead to unnecessary re-downloads.

Additionally, triggerCacheDownload is called without the quality parameter, which means it will default to 'standard', potentially mislabeling the cached file if it's of higher quality (e.g., FLAC).

To improve this, you should check for a cached file using checkLocalCache before triggering a download, and pass the inferred quality to both checkLocalCache and triggerCacheDownload.

        if (result.code === 200 && result.url) {
          const unlockUrl = result.url;
          // 推断音质
          let quality = QualityType.HQ;
          if (unlockUrl && (unlockUrl.includes(".flac") || unlockUrl.includes(".wav"))) {
            quality = QualityType.SQ;
          }
          // 检查本地缓存
          const cachedUrl = await this.checkLocalCache(songId, quality);
          if (cachedUrl) {
            return {
              id: songId,
              url: cachedUrl,
              isUnlocked: true,
              quality,
              source: source,
            };
          }
          // 触发缓存下载
          this.triggerCacheDownload(songId, unlockUrl, quality);
          
          return {
            id: songId,
            url: unlockUrl,
            isUnlocked: true,
            quality,
            source: source,
          };
        }

@imsyy imsyy merged commit 6205fbd into dev Feb 1, 2026
4 checks passed
@kazukokawagawa kazukokawagawa deleted the dev-cy branch February 1, 2026 23:46
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.

2 participants