feat(player): 实现自动混音与下一首预加载#70
Open
laoshuikaixue wants to merge 16 commits into
Open
Conversation
将旧版 SPlayer 的 Automix 能力完整迁移到 SPlayer-Next,同时首次支持歌曲预加载。新实现基于 Rust audio-engine 双槽架构(当前槽 + bounded preload 槽),不影响现有普通播放路径。 变更内容: - native/audio-engine 双槽播放:新增 preload/cancelPreload/crossfadeTo NAPI,preload 保留一个 bounded prepared slot,crossfadeTo 优先复用匹配预载槽。过渡期间旧槽淡出、新槽淡入,完成后释放旧槽资源。 - 迁移旧版音频分析(analysis.rs):BPM/调性/Smart Cut/transition proposal 到 native,通过主进程 worker 暴露 analyzeAudioFile、analyzeAudioFileHead、suggestTransition、suggestLongMix,避免阻塞主线程。分析结果作有界缓存,切歌/队列变化立即失效。 - 渲染层预载编排(preload.ts):根据队列、播放模式、音质解析下一首 URL,优先命中本地缓存;未命中时立即 preload 真实 URL,后台触发缓存下载。 - 渲染层 Automix 调度(automix.ts):复用旧版计划计算,输出 trigger time、crossfade duration、next start seek、initial rate、mix type,position 事件驱动,不新增高频 IPC。 - 中点 UI 提交(transitionCommit):主进程在 crossfade 中点统一提交 UI/歌词/封面/媒体状态/历史记录/预载。过渡期间忽略 native 新槽提前的 position/status,旧曲 UI 持续到 commit 点再切换。 - bassSwap 滤波:native 二阶 biquad 高通包络,旧曲前半段拉到 400Hz、新曲在 crossfade 中点释放回直通,贴合旧版 DJ 互换听感。 - 设置项:preloadNext(默认 true)、automixEnabled(默认 false)、automixMaxAnalyzeTimeSec(默认 60,范围 10-300),补充中英文 i18n 与播放设置项。
- 添加了 default 分支处理未知状态情况 - 返回空字符串避免 undefined 值导致的显示问题 - 确保函数在所有情况下都有明确的返回值
- 修正了 en-US.json 中 showLyricInBar 配置项后的多余逗号 - 修正了 zh-CN.json 中 showLyricInBar 配置项后的多余逗号 - 确保 JSON 文件格式正确性
- 将音频分析版本从13升级到14以支持新的分析特性 - 重构BPM检测算法,增加低频环境相关性计算和置信度评估 - 改进关键检测逻辑,使用更精确的分数排序和置信度计算 - 优化音频处理流程中的持续时间跟踪机制 - 调整混音参数限制,包括最大交叉淡入淡出时间和节拍置信度阈值 - 增强音频引擎中的渐变步数计算,支持动态步长调整 - 实现音频时钟同步机制,确保变速播放的时间准确性 - 添加分析超时控制和错误处理机制 - 优化过渡计划验证,增加对节拍网格可靠性的检查
- 实现 computeLoudnessGainDb 函数计算新旧歌曲间的响度差异 - 在 AutomixPlan 中加入 loudnessGainDb 字段传递响度补偿值 - 扩展 AudioOptions 类型定义支持响度补偿参数 - 在音频引擎中接收并应用响度补偿值调整目标音量 - 更新 BassSwap 算法中高通滤波器的截止频率参数 - 优化高通滤波自动化逻辑并在完成后清理相关资源
- 将原有的四次独立分析请求合并为单次双曲分析 - 减少文件IO操作,提升分析效率 - 引入PairAnalysisResult结构统一管理双曲分析结果 - 移除过时的单独过渡建议和长段混音建议函数 - 重构自动化混音逻辑以适配新的分析接口
- 删除 PairAnalysisResult 类型引用 - 移除高级过渡相关代码块和计算逻辑 - 简化过渡策略判断条件 - 优化自动混音计划生成流程 - 清理无用的过渡参数和变量声明 - 统一混音策略处理方式
- 从类型导入中删除 AdvancedTransition 类型 - 从模块作用域变量中移除 advancedTransition 变量 - 在清理函数中移除对 advancedTransition 的重置操作 - 从分析数据处理中移除 long_mix 数据赋值逻辑
- 将多行类型导入合并为单行导入语句 - 移除不必要的换行和空格 - 统一导入语句的代码风格
- 在BPM计算中添加非空断言操作符以避免类型检查错误 - 确保当前曲目和下一曲目的BPM值都被正确处理 - 保持原有的节拍网格检测和速率调整逻辑不变
…ade-dual-slot # Conflicts: # native/audio-engine/src/source.rs
Contributor
Author
|
Ready @imsyy |
Contributor
Author
2026-07-10.14-57-00.mp4 |
imsyy
requested changes
Jul 10, 2026
imsyy
left a comment
Member
There was a problem hiding this comment.
合并阻断
audio-engine 当前编译失败
验证命令:
cargo check -p audio-engine结果:失败。
核心错误:
native/audio-engine/src/lib.rs:457:25
expected Result<JoinHandle<DecoderData>, Error>, found JoinHandle<DecoderData>
native/audio-engine/src/lib.rs:435:17
cannot infer type
native/audio-engine/src/decoder.rs:171:19
expected JoinHandle<DecoderData>, found Result<JoinHandle<DecoderData>, Error>
- 在 decoder.rs 中为 resume_decode 调用添加错误传播操作符 - 在 lib.rs 中为 resume_decode 调用添加 into_napi 错误转换 - 修复 SideBar.vue 中路由跳转的代码格式问题
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
为SPlayer-Next实现自动混音(Automix)功能,在无需手动操作的情况下通过双槽预载、音频分析与交叉淡化,让歌曲之间平滑过渡。
功能概览
Native层(Rust)
audio-engine:
PreparedTrack/commit_crossfade双槽架构,原播放器在旧槽渐出期间不停止,新槽在后台渐入crossfade_volume:Equal-power(cos/sin)曲线,每秒约 100 次更新,替代原来固定 20 步线性阶梯analysis.rs:TrackAnalyzer 分析 silence、BPM(归一化自相关+低频辅助、真实 confidence)、Key(Krumhansl-Schmuckler chroma、真实 confidence)、Drop、Vocal、能量包络、LUFSanalysis.rs:新增analyze_pairNAPI 函数,单次打开每个文件同时返回两轨分析结果与过渡建议,替代原来4次独立解码shared.rs:HighPassAutomation实现 Bass Swap 高通包络(截止频率约 150Hz);cutoff_at返回Option<f32>,FadeIn 完成后自动清除source.rs:DecoderSource改为按实际输出帧推进samples_consumed,输出时钟更贴近真实播放位置lib.rs:JsCrossfadeOptions新增loudness_gain_db字段,支持过渡区短时响度补偿分析正确性修复:
chunks(4096).step_by(1024)改为正确的逐帧索引步进渲染层(TypeScript)
src/core/player/automix.ts:
tickAutomix:由 position 事件驱动,无额外 IPC;首次进入 45 秒窗口立即后台触发kickPairAnalysis(fire-and-forget),不阻塞 handler;分析未完成时最多等到PLAN_DEADLINE_MS,超时后冻结为安全兜底computePlan:依次尝试 TransitionProposal(结构感知)→本地分析兜底,统一经normalizePlan校验边界computeLoudnessGainDb:利用 LUFS 分析结果计算 ±6dB 响度补偿cuePath时不进入automix)transitioning使用try/finally保证异常时正确复位;分析 Promise有catch 与 deadline,不会无限挂起cancelAutomix状态机从 7 变量精简为 5 变量src/core/player/preload.ts:
preloadNextTrack保持独立,automix 启用时同步触发electron/preload/index.ts + electron/main/ipc/player.ts:
analyzePair、suggestTransition、suggestLongMix、crossfadeTo等 IPC 接口及 Worker 路由shared/types/player.ts:
AutomixPlan、PairAnalysisResult、CrossfadeOptions(含loudnessGainDb、uiSwitchDelayMs等)类型