Skip to content

🐛 fix: 修正 YPM TUI 远程播放健康状态 - #34

Merged
Nagi-ovo merged 2 commits into
masterfrom
fix/remote-playback-health
Aug 31, 2026
Merged

Nagi-ovo merged 2 commits into
masterfrom
fix/remote-playback-health

Conversation

@Nagi-ovo

Copy link
Copy Markdown
Member

问题

YPM TUI 在播放器尚未真正启动或已经失败时,远程状态仍可能报告 playing: true,公开频谱也会把本地模拟动画当成真实音频输出。dsh 音乐条因此会表现为歌曲卡在 0:00、声音没有播放,但频谱仍在跳动。第二个 YPM TUI 实例还可能在没有拿到控制 socket 时继续运行,让远程控制落到另一个实例。

修复

  • 只有当前 generation 收到播放器 Started 后才向远程报告正在播放
  • 公开频谱只输出真实捕获 PCM;模拟动画仍只留给 YPM 本地预览
  • 普通播放失败进入可重试暂停态,seek 失败保持非致命
  • 第二个 TUI 遇到活跃控制 socket 时明确退出;陈旧 socket 仍自动恢复
  • HTTPS 上游代理显式使用代理主机作为 TLS SNI,修复现有门禁发现的证书校验错误

验证

  • bun test:439 pass / 0 fail
  • bun run typecheck
  • bun run build:tauri:renderer
  • cargo test --workspace
  • cargo clippy --workspace --all-targets
  • cargo fmt --all -- --check
  • git diff --check
  • 本机替换后实播:remote position 持续推进、seekable: true,dsh 播放条与真实频谱同步恢复

未改版本号、未打 tag、未发布。

显式把 HTTPS 上游代理主机作为 TLS SNI,避免目标请求的 Host 头污染证书校验。
将远程 playing 与当前播放器就绪代绑定,无真实 PCM 时不再向外发布模拟频谱。播放失败保留可重试位置,seek 失败保持非致命;第二个 TUI 实例会明确退出,避免控制错误实例。
@Nagi-ovo

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Aug 31, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-08-31T17:38:45.242866Z 9d70c52 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9d70c5204a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

method: request.method,
path: target.upstreamPath,
headers,
...(net.isIP(upstreamHost) === 0 ? { servername: upstreamHost } : {}),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Handle IP-literal HTTPS proxy identities explicitly

When the configured HTTPS upstream is an IPv4 or IPv6 literal, this branch leaves servername unset; https.request can then derive the TLS server name from the forwarded Host header, which belongs to the destination rather than the proxy. Consequently, ordinary HTTP absolute-form requests through an IP-addressed HTTPS proxy present/verify the destination hostname and fail certificate validation even when the configured CA trusts the proxy's IP certificate. Explicitly suppress SNI while preserving verification against upstreamHost, rather than omitting the option.

Useful? React with 👍 / 👎.

self.ticks = self.ticks.wrapping_add(1);
let real = capture.latest(FFT_SAMPLES);
let live = playing && !real.is_empty();
self.using_captured_samples = live;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Clear simulated analyzer state before exporting captured frames

When playback first has no captured samples, tick feeds simulated samples into the smoothed analyzer while keeping using_captured_samples false; as soon as even silent captured PCM arrives, this assignment flips the flag without clearing those simulated bins. Because the analyzer decays old values gradually, remote_bins() then exports nonzero simulated energy for multiple frames despite the captured input being silent, so public consumers still receive the fake spectrum this change is intended to exclude. Reset the analyzer/bins on the simulated-to-captured transition or analyze public PCM independently.

Useful? React with 👍 / 👎.

Comment on lines 162 to 165
if std::os::unix::net::UnixStream::connect(path).is_ok() {
return Ok(None);
return Err(error);
}
std::fs::remove_file(path)?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Make stale-socket takeover exclusive

When two TUI processes start together while ctl.sock is stale, both can fail this live-owner probe before either removes the path. One process can then remove and rebind it, after which the other can unlink that newly live socket and bind its own; alternatively, the loser can receive NotFound, which the caller only warns about before continuing without a control socket. Both paths leave two TUIs running despite the new single-owner behavior, so stale recovery needs an atomic ownership lock or a retry/re-probe around unlinking and binding.

Useful? React with 👍 / 👎.

@Nagi-ovo
Nagi-ovo merged commit 18a2027 into master Aug 31, 2026
17 of 18 checks passed
@Nagi-ovo
Nagi-ovo deleted the fix/remote-playback-health branch August 31, 2026 18:50
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.

1 participant