Skip to content

[Bug]: Linux 下 Rodio 0.22 音频输出迁移后播放断续,回退到 2026-08-07 Action 构建恢复正常 #168

Description

@UlinoyaPed

问题描述

在 Fedora Linux + PipeWire 环境下,Release v1.0.0 以及最新 dev Action 构建播放音乐时出现声音断断续续、输出设备偶尔失效的问题。

相同硬件、系统音频服务、播放器配置和音源下,回退到 2026-08-07 的官方 Action 构建后,播放恢复正常。其他软件音频在问题发生期间始终正常,因此问题看起来与 SPlayer-Next 新版 Rust 音频输出路径有关,而不是 PipeWire 整体失效。

环境

  • OS:Fedora Linux 44
  • Kernel:Linux 7.1.8-200.fc44.x86_64
  • Desktop:Wayland
  • PipeWire:1.6.8
  • Audio device:TTGK Technology LBZ CS43198 HiFi Audio
  • USB ID:3302:43e2
  • SPlayer-Next 输出路径:ALSA PipeWire plugin → PipeWire → CS43198 USB DAC
  • 音源:在线 FLAC、在线 MP3、本地缓存文件均可复现
  • 以 Helium 浏览器作音频测试:正常

受影响版本

Release v1.0.0 以及 2026-08-17 的最新 dev Action 构建均可复现。

受影响构建中的原生音频模块包含:

rodio 0.22.2
cpal 0.17.3

正常版本

回退至以下官方 Action 构建后恢复正常:

该构建的原生音频模块包含:

rodio 0.20.1
cpal 0.15.3

虽然新旧 RPM 的包版本字段均显示 1.0.0-1,但 RPM Build Date 和原生模块依赖版本不同:

正常构建:
Build Date: 2026-08-07
rodio 0.20.1
cpal 0.15.3

异常构建:
Build Date: 2026-08-17
rodio 0.22.2
cpal 0.17.3

复现步骤

  1. 将 CS43198 USB DAC 设置为 PipeWire 默认输出。
  2. 安装 Release v1.0.0 或包含 Rodio 0.22 迁移的最新 dev Action RPM。
  3. 启动 SPlayer-Next。
  4. 使用“系统默认”或 pipewire 输出设备。
  5. 播放在线 FLAC、在线 MP3 或本地缓存歌曲。
  6. 持续播放或切换歌曲。

实际表现

  • 声音断断续续。
  • 有时播放器无法重新建立输出流。
  • 切歌后可能连续报设备初始化失败。
  • 设备错误有时被上层错误处理显示为 NETWORK_ERROR 或 FILE_DECODE_ERROR。
  • 同时使用浏览器播放音频正常。
  • 重启 SPlayer-Next、PipeWire 或 WirePlumber 不能稳定解决。
  • 回退到 2026-08-07 Action 构建后,相同设备和 PipeWire 路由下播放正常。

期望表现

  • 使用 PipeWire 默认输出时应持续稳定播放。
  • 输出设备短暂重连后应自动恢复音频流。
  • 设备初始化错误不应被报告为网络错误或文件解码错误。
  • 新版行为不应比 Rodio 0.20 构建退化。

新版日志

播放器日志:

UNKNOWN: Error: [Device] audio device error:
Failed to get default output config:
Failed to get the config for the given device:
The requested device is no longer available.
For example, it has been unplugged.

同一设备错误还会被归类为:

FILE_DECODE_ERROR
NETWORK_ERROR

原生音频引擎日志:

audio-output-owner: build_output_sink failed
error=Failed to get default output config

重建输出设备失败:
Failed to get default output config

内核和 PipeWire 在问题发生时记录过:

snd_pcm_start: Broken pipe
snd_pcm_drop: No such device
close failed: No such device

回退后的实际输出状态

回退到 2026-08-07 Action 构建后,SPlayer-Next 能正常通过 PipeWire 输出:

PipeWire ALSA [SPlayer-Next]
  output_FL > LBZ CS43198 HiFi Audio:playback_FL [active]
  output_FR > LBZ CS43198 HiFi Audio:playback_FR [active]

原生引擎日志:

audio-output-owner: starting device=None
已选择音频输出流采样率 requested_sample_rate=44100 sample_rate=44100

因此正常构建和异常构建使用的是同一套系统音频设备及 PipeWire 路由。

疑似回归范围

1. Rodio 0.22 输出迁移

82bb492

该提交将输出从 OutputStream + OutputStreamHandle 迁移至 MixerDeviceSink + Mixer。

同时,原来的默认设备打开逻辑包含以下兜底:

尝试默认输出设备
→ 默认设备打开失败
→ 枚举其他输出设备
→ 使用第一个可以打开的设备

迁移后的 None 分支改为直接调用 DeviceSinkBuilder::open_default_sink(),旧的设备枚举兜底不再存在。

这不一定是唯一原因,但与回退结果和错误日志吻合,建议优先对比迁移前后的 Linux/ALSA 输出行为。

2. Linux 设备变化监听

相关提交:

当前原生设备监听只支持 Windows;Linux 使用每 3 秒一次的默认设备名称轮询。

Linux 下的实际路由为:

SPlayer-Next
→ ALSA PipeWire plugin
→ PipeWire
→ USB DAC

USB DAC 在 PipeWire 后面断开并重新连接时,CPAL 返回的默认设备名称可能始终是 pipewire,导致轮询无法发现底层输出已经重连,也不会触发 reinitOutput()。

此外,当前策略只在以下条件全部满足时重建:

默认设备名称发生变化
&& 当前默认设备不为空
&& 用户没有显式选择输出设备

显式选择 pipewire 或其他设备名时,默认设备轮询不会触发输出重建。

建议检查方向

  1. 对比 82bb492 前后 Rodio/CPAL 在 Linux ALSA 后端的输出行为。
  2. 恢复默认输出打开失败时的设备枚举兜底。
  3. 监听 CPAL 输出流错误,例如 DeviceNotAvailable、BrokenPipe、BackendSpecific。
  4. 收到输出流错误或 outputStalled 后,丢弃失效流、短暂退避、重新枚举设备、重建输出并恢复原播放位置。
  5. Linux 下不要只依赖默认设备名称变化判断是否需要重建。
  6. 将设备错误稳定归类为 DEVICE_NOT_FOUND 或 DEVICE_INIT_FAILED,不要根据音源 URL 将其归为 NETWORK_ERROR。
  7. 增加 Linux + PipeWire + USB DAC 的回归测试或可重复的手动测试流程。

补充说明

目前没有在本地重新构建源码。上述回归范围来自:

  • 新旧官方 Action RPM 的实际 A/B 回退结果
  • RPM Build Date
  • 原生模块内嵌的 Rodio/CPAL 版本
  • SPlayer-Next 原生日志
  • PipeWire 实时路由
  • ALSA 与内核日志
  • 相关提交的源码差异

如有需要,可以继续提供完整的脱敏日志或协助测试包含针对性修复的 Linux Action 构建。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions