Skip to content

v1.0.24

Latest

Choose a tag to compare

@github-actions github-actions released this 24 Oct 10:58

本版更新

这一版新增了桌面「播放器」组件:律动条和唱片机两种形态,跟随系统正在播放的内容,律动条按真实频谱跳动。为了让它在各种播放器上都能用,这一版还把三条底层链路补结实了——托盘图标、音频会话枚举、换歌时的封面刷新。

新增

  • 播放器组件:桌面上的「正在播放」。创建时选定形态,之后不可更改:
    • 律动条:一排跳动的频谱,默认按系统混音的真实频谱跳动(WASAPI 环回 + 手写 FFT,无需第三方库),可在属性面板切回模拟律动;安静时条子落回底部,暂停即静;
    • 唱片机:黑胶盘 + 旋转的专辑封面 + 唱臂,转速可调;
    • 两种形态都支持磁贴模式(只留内容,不画背景与边框)、圆角/尖角、液态玻璃、背景图、位置与尺寸记忆。
  • 曲目与封面:读取系统正在播放的曲名、歌手、专辑与封面,可直接上一曲 / 暂停 / 下一曲。
  • 封面取色:从专辑封面提取主色,用在律动条颜色、分割线和唱片机中心标签上;封面取不到可用主色时退回手设颜色。
  • 跟随指定应用:同时有多个播放器在放时,可以让某个组件只跟某个应用(另一个跟别的),播放控制也只发给它。下拉每次展开都会重新读取系统会话。
  • 两套预设卡:律动条与唱片机各自一套预设,分开存放、互不混用,卡片缩略图按形态自绘(含液态玻璃与配色)。
  • 兜底识别:没有接入系统媒体会话的播放器(如网易云音乐)靠音频会话电平 + 窗口标题 + 它自己的播放缓存识别,控制走系统媒体键;连"是谁在出声"都认不出时,条子/唱盘照样动,只是不显示曲目内容。

改进

  • 播放器属性面板新增「播放与显示」分区,律动条 / 唱片机各自的样式分区独立;
  • 管理窗口侧栏与页面新增播放器入口,可见性与删除和分区、时钟一致;
  • 新增启动诊断日志(版本、便携模式、完整性级别、数据路径、组件数量),排障时不再靠猜。

修复

  • 托盘图标在部分环境注册失败:图标改为自建隐藏宿主窗口承载(不再借用主窗口句柄)、固定 GUID 让系统记住"始终显示"、并处理 explorer 重启后的重建广播;注册失败会退避重试并写日志,不再静默。
  • 兜底识别整条失效(真凶):MMDeviceEnumerator 原先在三个音频模块里各用一份 [ComImport] 类去创建,同名同 CLSID 的三份类型会抢同一份 RCW,谁先创建谁定型,后面的模块一律抛 InvalidCastException。结果是兜底识别每秒都失败、P1 真实频谱也一直是哑的。现在统一到一个 CoreAudioInterop 入口创建、共享,两个功能一起复活。
  • 换歌后唱片机封面不刷新:元数据先到、封面晚一两秒到,那一两秒里曲目没变,只有封面变了——原来不发变更通知,唱片机就一直挂旧图,非要暂停再播一下。现在封面变化同样通知界面,并用内容哈希识别"歌名换了但封面还是上一首"的脏图,自动复查替换。
  • 网易云封面反查:播放缓存真实路径是 Cache\Cache\,改为递归扫描,封面与曲目信息恢复。
  • 配置保存失败、音频枚举失败等关键路径现在都有 Release 也写的日志,并在沙箱/低完整性环境下给出明确提示。

提示

网易云音乐默认不把播放信息交给 Windows:在它自己的「设置 → 系统媒体控制(SMTC)」里打开,就能显示曲名、歌手和封面并使用控制按钮。这个开关不打开也能用——兜底识别会通过音频会话认出它在播放,只是可能拿不到封面、控制走系统媒体键。


What's New

This release adds the desktop Player widget — bars and vinyl, following whatever is playing, with bars driven by the real system spectrum. Three deeper plumbing problems had to be fixed along the way: the tray icon, the audio-session enumerator and the artwork refresh on track change.

Added

  • Player widget: "now playing" on the desktop. The shape is picked at creation and fixed afterwards:
    • Bars: a row of bouncing spectrum bars driven by the real system mix by default (WASAPI loopback + a hand-written FFT, no third-party library), switchable back to simulated motion in the property panel. Silence drops the bars; pause freezes them;
    • Vinyl: a black record with the album cover spinning on it, plus a tonearm and adjustable spin speed;
    • Both shapes support tile mode (content only, no background or border), rounded/sharp corners, liquid glass, background images, and remember their position and size.
  • Track and artwork: reads the title, artist, album and cover of whatever is playing, with prev / play-pause / next.
  • Accent from cover: the dominant colour of the album artwork drives the bar colour, the divider and the vinyl centre label, falling back to your own colours when the cover has no usable colour.
  • Follow one app: with several players around, a widget can follow a single app (another one can follow a different app), and the transport buttons only go to that session. The list is re-read every time you open it.
  • Two preset sets: bars presets and vinyl presets are stored separately and never mixed; each card draws its own thumbnail from the saved look, liquid glass included.
  • Fallback recognition: players that never register a system media session (e.g. NetEase Cloud Music) are recognised through audio-session level, window title and their own play-queue cache, with controls sent as system media keys. When even the source can't be identified, the bars and the record still react — just without track text.

Improved

  • A new "Playback & display" section in the player property panel, with separate bars / vinyl style sections.
  • New player entries in the management sidebar and page; visibility and deletion behave like zones and clocks.
  • Startup diagnostics (version, portable mode, integrity level, data path, widget counts) so troubleshooting no longer relies on guessing.

Fixed

  • Tray icon failing to register in some environments: the icon now lives on its own hidden host window (no longer borrowing the main window's handle), uses a fixed GUID so Windows remembers "always show", and rebuilds itself when explorer restarts. Failed registrations retry with backoff and are logged instead of failing silently.
  • Fallback detection completely dead (root cause): MMDeviceEnumerator used to be created through three separate [ComImport] classes — one in each audio module. Same CLSID, three distinct managed types: the first one to run pinned the RCW's type, and every other module then threw InvalidCastException forever. That killed the fallback detection every single second and left the real spectrum silently dead. All creation now goes through one shared CoreAudioInterop entry point, and both features came back to life.
  • Vinyl cover not refreshing on track change: metadata arrives first and the thumbnail one or two seconds later — in between, only the artwork changes, and that used to raise no notification, so the record kept showing the old cover until you paused and played again. Artwork changes now notify the UI as well, and a content hash detects "new title, stale image" so it can be re-checked and replaced.
  • NetEase Cloud Music artwork lookup: the play cache actually lives in Cache\Cache\; the scan is now recursive, restoring both track info and artwork.
  • Config-save and audio-enumeration failures are now logged in release builds too, with explicit hints when the app is running in a sandboxed / low-integrity environment.

Note

NetEase Cloud Music does not share its playback info with Windows by default. Turn on Settings → System media control (SMTC) inside NetEase Cloud Music to get the title, artist, artwork and working transport buttons. It works with the switch off too — the fallback recognises that it is playing through its audio session — but artwork may be missing and controls go through the system media keys.