Skip to content

✨ feat: Web Audio 音频输出优化#958

Merged
imsyy merged 10 commits into
SPlayer-Dev:devfrom
ITManCHINA:web-audio-optimization
Mar 10, 2026
Merged

✨ feat: Web Audio 音频输出优化#958
imsyy merged 10 commits into
SPlayer-Dev:devfrom
ITManCHINA:web-audio-optimization

Conversation

@ITManCHINA
Copy link
Copy Markdown
Member

本次修改为 Web Audio 输出引入了 latencyHint 配置选项,允许用户根据使用场景在 低延迟模式(interactive)与高效能模式(playback) 模式间切换。

  • 低延迟模式(interactive)
    技术特性: 申请极小的音频缓冲区(Small Buffer),维持高频率的 CPU 中断。
    优点: 响应速度极快,适合对同步要求极高的场景。
    缺点: CPU 负担较重,且在移动端(如 Android)通常会绕过系统级 DSP(如杜比全景声、内置音效),导致音质表现平平。

  • 高效能模式(playback)
    技术特性: 申请较大的音频缓冲区(Deep Buffer),降低 CPU 唤醒频率。
    优点:允许操作系统启用硬件离线处理(Audio Offload)和系统级 DSP 音效(如小米音效、杜比全景声)。
    节能降耗: 显著降低音频子系统的 CPU 占用,提升设备续航并减少发热。
    缺点: 可能存在明显的硬件输出延迟(Hardware Output Latency)1,需要配合 UI 层的延迟补偿逻辑以确保歌词同步。

Footnotes

  1. 针对 playback 模式带来的物理延迟,已在 currentTime 获取逻辑中集成了 baseLatency 和 outputLatency 补偿算法,确保在开启系统音效的情况下,歌曲输出、进度条与歌词进度仍保持高度同步。

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, 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!

本次拉取请求旨在通过引入 Web Audio 的 latencyHint 配置选项,显著优化应用程序的音频输出体验。用户现在可以根据具体使用场景,灵活选择低延迟或高效能的音频处理模式。此举不仅提升了音频播放的响应速度或稳定性,还通过精密的延迟补偿机制,解决了高效能模式下可能出现的音画不同步问题,确保了整体媒体体验的流畅性和准确性。

Highlights

  • Web Audio 延迟策略配置: 引入了新的 Web Audio 延迟策略配置选项,允许用户在“低延迟模式(interactive)”和“高效能模式(playback)”之间切换,以优化音频输出性能和稳定性。
  • 延迟补偿机制: 为“高效能模式(playback)”集成了音频输出延迟补偿算法,确保在启用系统音效时,歌曲输出、进度条与歌词进度仍能保持高度同步。
  • 用户界面设置: 在设置界面中新增了“Web Audio 延迟策略”选项,用户可直接选择偏好的模式,并提示修改后需重启应用生效。
  • AudioContext 初始化: 更新了共享 AudioContext 的初始化逻辑,使其根据用户选择的延迟策略来创建 AudioContext 实例。
Changelog
  • src/components/Setting/config/play.ts
    • 新增了“Web Audio 延迟策略”的UI配置项,允许用户选择“低延迟模式(interactive)”或“高效能模式(playback)”。
    • 为延迟策略选项添加了描述和Beta标签。
    • 实现了更改延迟策略后提示用户重启应用的逻辑。
  • src/core/audio-player/AudioElementPlayer.ts
    • 修改了 currentTime 的获取逻辑,加入了 compensatedLatency 以补偿音频输出延迟。
  • src/core/audio-player/BaseAudioPlayer.ts
    • 新增了 compensatedLatency 属性。
    • 在音频上下文初始化后,根据 latencyHint 计算并设置 compensatedLatency,用于后续的延迟补偿。
  • src/core/automix/SharedAudioContext.ts
    • 引入 useSettingStore 以获取用户配置的 audioLatencyHint
    • 修改了 getSharedAudioContext 函数,在创建 AudioContext 实例时传入用户选择的 latencyHint
  • src/stores/setting.ts
    • SettingState 接口中新增了 audioLatencyHint 属性,类型为 "interactive" | "playback"
    • audioLatencyHint 设置了默认值 "interactive"
  • src/types/audio/context.ts
    • 扩展了 IExtendedAudioContext 接口,新增了可选的 latencyHint 属性。
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 为 Web Audio 引入了 latencyHint 配置,允许在低延迟和高效能模式之间切换,并为高效能模式增加了延迟补偿,这是一个很棒的优化。代码整体实现清晰,但在一些细节上可以进一步完善,具体请看我的评论。

Comment thread src/core/automix/SharedAudioContext.ts Outdated
sharedContext = new AudioContextClass({
latencyHint: settingStore.audioLatencyHint,
}) as IExtendedAudioContext;
sharedContext.latencyHint = settingStore.audioLatencyHint;
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

AudioContext 实例上的 latencyHint 属性是只读的,其值由构造函数在创建时确定。这一行代码试图对只读属性进行赋值,这是多余的,并且在严格模式下可能会抛出错误。对于不支持 latencyHint 的旧版 webkitAudioContextBaseAudioPlayer 中的逻辑已经能够优雅地处理 latencyHintundefined 的情况(不应用延迟补偿)。因此,建议删除此行以提高代码的健壮性和清晰度。

Comment thread src/components/Setting/config/play.ts Outdated
Comment thread src/types/audio/context.ts Outdated
/** 扩充 AudioContext 接口以支持 setSinkId (实验性 API) */
export interface IExtendedAudioContext extends AudioContext {
setSinkId(deviceId: string): Promise<void>;
latencyHint?: "playback" | "interactive";
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

由于原生 AudioContextlatencyHint 属性是只读的,在类型定义中也将其标记为 readonly 是一个好习惯。这可以增强类型安全,并防止在代码中其他地方发生意外的赋值。

Suggested change
latencyHint?: "playback" | "interactive";
readonly latencyHint?: "playback" | "interactive";

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Copy link
Copy Markdown

能不能加一个全局的歌词偏差让用户改(

@ITManCHINA ITManCHINA marked this pull request as draft March 1, 2026 19:46
@ITManCHINA
Copy link
Copy Markdown
Member Author

ITManCHINA commented Mar 9, 2026

能不能加一个全局的歌词偏差让用户改(

已在 b2a739b 加上了
15016e3e29bf97c2e4a7583b79e4514c

@ITManCHINA
Copy link
Copy Markdown
Member 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

本次 PR 为 Web Audio 引入了 latencyHint 配置项,允许在低延迟和高效能模式之间切换,并通过延迟补偿优化了 playback 模式下的歌词同步问题,功能实现完整。代码整体结构清晰,并已确认一处冗余代码可以移除,以提高代码的健壮性和可读性。

Comment thread src/core/automix/SharedAudioContext.ts Outdated
sharedContext = new AudioContextClass({
latencyHint: settingStore.audioLatencyHint,
}) as IExtendedAudioContext;
sharedContext.latencyHint = settingStore.audioLatencyHint;
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

AudioContextlatencyHint 属性是只读的,并且在实例化时通过构造函数参数进行设置。第 26 行已经正确地传递了 latencyHint,因此第 28 行的赋值操作是多余的。

如果浏览器支持 latencyHint 构造选项,这行代码是冗余的;如果浏览器不支持,那么它很可能也不支持 outputLatencybaseLatency 属性,这意味着延迟补偿逻辑无论如何都不会生效。

为了代码的清晰和健壮性,建议移除此行。

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

我把这里的return (this.audioElement.currentTime || 0) + this.compensatedLatency; 换为return (this.audioElement.currentTime || 0) - this.compensatedLatency;,它的作用是?

@ITManCHINA ITManCHINA marked this pull request as ready for review March 9, 2026 05:59
@ITManCHINA ITManCHINA marked this pull request as draft March 9, 2026 09:36
@ITManCHINA
Copy link
Copy Markdown
Member 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

本次 PR 为 Web Audio 输出引入了 latencyHint 选项,允许用户在低延迟和高效能模式之间切换,并为高效能模式添加了延迟补偿,同时还增加了一个手动调整歌词同步偏移的设置。整体实现很清晰,通过添加必要的设置,将其应用于 AudioContext,并相应地调整了 currentTime 的计算。

我发现了一个小问题:代码尝试对一个只读属性进行赋值,这是多余的,应该移除。此外,我还建议改进相关的类型定义,以防止未来出现类似问题。总体而言,这是一项出色的功能增强。

Comment thread src/core/automix/SharedAudioContext.ts Outdated
sharedContext = new AudioContextClass({
latencyHint: settingStore.audioLatencyHint,
}) as IExtendedAudioContext;
sharedContext.latencyHint = settingStore.audioLatencyHint;
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

AudioContext 实例上的 latencyHint 属性是只读的。它的值在创建时确定,之后无法更改。

你已经在第 26 行的 AudioContext 构造函数中正确地传递了 latencyHint。因此,这一行代码是多余且不正确的,应当移除。

参考资料: MDN Web Docs for AudioContext.latencyHint

Comment thread src/types/audio/context.ts Outdated
ITManCHINA and others added 3 commits March 9, 2026 17:50
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
@ITManCHINA ITManCHINA marked this pull request as ready for review March 9, 2026 10:22
@ITManCHINA
Copy link
Copy Markdown
Member 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

本次 PR 为 Web Audio 引入了 latencyHint 选项,允许用户在低延迟和高效能模式之间切换,并为 playback 模式添加了自动延迟补偿和手动补偿设置。整体实现结构清晰,从 UI 设置到核心音频播放器逻辑的修改都覆盖到了。代码质量较高,逻辑清晰。我发现了一个关于只读属性赋值的小问题,建议修正。

Note: Security Review did not run due to the size of the PR.

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.

3 participants