Skip to content

feat(audio): make virtual output locking configurable - #1011

Open
XIGUAjuice wants to merge 1 commit into
AlkaidLab:masterfrom
XIGUAjuice:feat/virtual-audio-output-lock
Open

feat(audio): make virtual output locking configurable#1011
XIGUAjuice wants to merge 1 commit into
AlkaidLab:masterfrom
XIGUAjuice:feat/virtual-audio-output-lock

Conversation

@XIGUAjuice

Copy link
Copy Markdown

改动概述

新增 virtual_sink_lock 配置开关,用于控制串流期间是否强制保持虚拟音频设备为系统默认输出设备。

该选项默认开启,因此不会改变现有用户的行为。

关闭该选项后:

  • 串流开始时,Sunshine 仍会像以前一样选择串流使用的虚拟音频设备。
  • 串流期间,用户可以将系统音频输出切换到音箱、耳机或其他设备。
  • Sunshine 不会再把系统音频输出强制切回虚拟音频设备。
  • 将系统音频输出切回虚拟音频设备后,客户端声音可以恢复,不需要重新开始串流。
  • 如果用户在串流期间手动切换过输出设备,串流结束时会保留用户最后选择的设备。

改动原因

目前,在使用虚拟音频设备进行串流时,只要 Windows 默认音频输出设备发生变化,Sunshine 就会立即将其重新切换到虚拟音频设备。

这意味着用户即使手动将声音切换到音箱或耳机,也会很快被 Sunshine 强制切回。

这种行为对于副屏串流等场景不够友好。例如,用户在副屏上保持串流的同时,可能希望临时将主机声音切换到本地音箱或耳机,而不希望因此停止串流。

本次改动允许用户关闭这种强制锁定行为,同时不会改变 Sunshine 选择和采集音频设备的方式。

配置行为

virtual_sink_lock 行为
开启(默认) 保持现有行为。串流期间如果 Windows 默认音频输出设备发生变化,Sunshine 会重新选择虚拟音频设备。
关闭 允许用户在串流期间自由切换 Windows 音频输出设备,Sunshine 不再强制切回虚拟音频设备。

关闭该选项后的典型流程:

  1. 开始串流。
  2. Sunshine 选择串流使用的虚拟音频设备。
  3. 用户将主机音频输出切换到音箱或耳机。
  4. Sunshine 不会将输出设备强制切回。
  5. 主机声音从音箱或耳机播放,串流客户端没有声音。
  6. 用户将输出切回虚拟音频设备后,客户端声音恢复。
  7. 结束串流时,Sunshine 保留用户最后手动选择的输出设备。

实现说明

  • 新增 virtual_sink_lock 配置项。
  • 默认值为开启,以保持向后兼容。
  • 在 Web 管理界面的“音频/视频”页面中添加对应开关。
  • 调整 Windows WASAPI 默认输出设备变化通知的处理逻辑:
    • 开关开启时,保持原有行为,将默认输出重新设置为虚拟音频设备,并重新初始化采集。
    • 开关关闭时,不修改用户选择的默认输出设备,同时保持现有的虚拟音频采集会话。
  • 记录串流期间由外部触发的默认输出设备变化。
  • 如果用户在串流期间手动切换过设备,结束串流时不再恢复串流前的输出设备。
  • 在音频采集对象销毁前处理尚未消费的最后一次设备变化通知,避免用户在串流即将结束时进行的设备切换被遗漏。
  • 添加配置文档和 Web 管理界面的多语言文案。

兼容性

  • virtual_sink_lock 默认开启,因此升级后不会改变现有用户的音频行为。
  • 关闭该选项不会改变 Sunshine 配置的音频采集设备。

测试

已完成以下检查:

  • npm run lint:webui

  • npm run test:webui,119 项测试通过

  • npm run build

  • 多语言配置验证和格式检查

  • 使用 MSYS2 UCRT64、GCC 16.2、CMake 和 Ninja 完成 Windows CMake 配置

  • 完成 Windows 原生构建:

    cmake --build --preset dev-local --parallel 6
    

@coderabbitai

coderabbitai Bot commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 57c17302-948a-4ae1-97e1-4ee35553bdf3

📥 Commits

Reviewing files that changed from the base of the PR and between ce6b69a and d99a8cc.

📒 Files selected for processing (28)
  • docs/configuration.md
  • src/audio.cpp
  • src/config.cpp
  • src/config.h
  • src/platform/common.h
  • src/platform/windows/audio.cpp
  • src_assets/common/assets/web/composables/useConfig.js
  • src_assets/common/assets/web/configs/tabs/AudioVideo.vue
  • src_assets/common/assets/web/public/assets/locale/bg.json
  • src_assets/common/assets/web/public/assets/locale/cs.json
  • src_assets/common/assets/web/public/assets/locale/de.json
  • src_assets/common/assets/web/public/assets/locale/en.json
  • src_assets/common/assets/web/public/assets/locale/en_GB.json
  • src_assets/common/assets/web/public/assets/locale/en_US.json
  • src_assets/common/assets/web/public/assets/locale/es.json
  • src_assets/common/assets/web/public/assets/locale/fr.json
  • src_assets/common/assets/web/public/assets/locale/it.json
  • src_assets/common/assets/web/public/assets/locale/ja.json
  • src_assets/common/assets/web/public/assets/locale/ko.json
  • src_assets/common/assets/web/public/assets/locale/pl.json
  • src_assets/common/assets/web/public/assets/locale/pt.json
  • src_assets/common/assets/web/public/assets/locale/pt_BR.json
  • src_assets/common/assets/web/public/assets/locale/ru.json
  • src_assets/common/assets/web/public/assets/locale/sv.json
  • src_assets/common/assets/web/public/assets/locale/tr.json
  • src_assets/common/assets/web/public/assets/locale/uk.json
  • src_assets/common/assets/web/public/assets/locale/zh.json
  • src_assets/common/assets/web/public/assets/locale/zh_TW.json

Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.

📜 Recent review details
🧰 Additional context used
📓 Path-based instructions (3)
基于 Vue.js 的 Web 配置面板。审查 XSS/CSRF 安全性、 组件设计、状态管理和可访问性。

⚙️ CodeRabbit configuration file

Files:

  • src_assets/common/assets/web/composables/useConfig.js
  • src_assets/common/assets/web/configs/tabs/AudioVideo.vue
平台抽象层代码(Windows/Linux/macOS)。确保各平台实现一致, 注意 Windows API 调用的错误处理和资源释放。

⚙️ CodeRabbit configuration file

Files:

  • src/platform/windows/audio.cpp
  • src/platform/common.h
Sunshine 核心 C++ 源码,自托管游戏串流服务器。审查要点:内存安全、 线程安全、RAII 资源管理、安全漏洞。注意预处理宏控制的平台相关代码。

⚙️ CodeRabbit configuration file

Files:

  • src/config.cpp
  • src/config.h
  • src/audio.cpp
  • src/platform/windows/audio.cpp
  • src/platform/common.h
🔇 Additional comments (28)
src/config.h (1)

147-147: LGTM!

src/config.cpp (1)

486-486: LGTM!

Also applies to: 1485-1485

src/platform/common.h (1)

750-758: LGTM!

src/platform/windows/audio.cpp (1)

627-633: LGTM!

Also applies to: 663-673, 753-753, 861-877, 986-990, 1288-1288

src/audio.cpp (1)

686-690: LGTM!

src_assets/common/assets/web/composables/useConfig.js (1)

63-63: LGTM!

src_assets/common/assets/web/configs/tabs/AudioVideo.vue (1)

116-123: LGTM!

docs/configuration.md (1)

756-780: LGTM!

src_assets/common/assets/web/public/assets/locale/en.json (1)

753-754: LGTM!

Also applies to: 834-834

src_assets/common/assets/web/public/assets/locale/pt.json (1)

753-754: LGTM!

src_assets/common/assets/web/public/assets/locale/pt_BR.json (1)

753-754: LGTM!

src_assets/common/assets/web/public/assets/locale/ru.json (1)

753-754: LGTM!

src_assets/common/assets/web/public/assets/locale/sv.json (1)

753-754: LGTM!

src_assets/common/assets/web/public/assets/locale/tr.json (1)

753-754: LGTM!

src_assets/common/assets/web/public/assets/locale/uk.json (1)

753-754: LGTM!

src_assets/common/assets/web/public/assets/locale/zh.json (1)

753-754: LGTM!

src_assets/common/assets/web/public/assets/locale/zh_TW.json (1)

753-754: LGTM!

src_assets/common/assets/web/public/assets/locale/bg.json (1)

753-754: LGTM!

src_assets/common/assets/web/public/assets/locale/cs.json (1)

753-754: LGTM!

src_assets/common/assets/web/public/assets/locale/de.json (1)

753-754: LGTM!

src_assets/common/assets/web/public/assets/locale/en_GB.json (1)

753-754: LGTM!

src_assets/common/assets/web/public/assets/locale/en_US.json (1)

753-754: LGTM!

src_assets/common/assets/web/public/assets/locale/es.json (1)

753-754: LGTM!

src_assets/common/assets/web/public/assets/locale/fr.json (1)

753-754: LGTM!

src_assets/common/assets/web/public/assets/locale/it.json (1)

753-754: LGTM!

src_assets/common/assets/web/public/assets/locale/ja.json (1)

753-754: LGTM!

src_assets/common/assets/web/public/assets/locale/ko.json (1)

753-754: LGTM!

src_assets/common/assets/web/public/assets/locale/pl.json (1)

753-754: LGTM!


Summary by CodeRabbit

  • 新功能

    • Windows 音频设置新增“串流期间保持虚拟音频设备”的选项,默认启用。
    • 禁用后可在串流期间切换扬声器或耳机,并在结束后保留最后选择的设备。
    • 音频设备发生变化时,系统将按设置决定是否恢复原输出设备。
  • 文档

    • 补充该配置项的使用说明、默认值及 Windows 平台适用范围。
  • 本地化

    • 新增多种语言的设置名称与说明文本。

Walkthrough

新增 virtual_sink_lock 配置。Windows 音频后端根据该配置处理默认设备变更,并决定流停止时是否恢复原输出设备。Web 界面、文档和多语言资源同步更新。

Changes

虚拟音频设备锁定

Layer / File(s) Summary
配置字段与解析
src/config.h, src/config.cpp, src/platform/common.h
新增 audio_t::virtual_sink_lock,默认值为 true。配置文件支持解析该字段。audio_control_t 新增 should_restore_sink()
Windows 设备变更处理
src/platform/windows/audio.cpp
默认端点变更回调改为返回布尔值。启用锁定时重新初始化捕获设备;禁用锁定时保留当前捕获会话,并记录停止时是否保留默认输出。
流停止时的 sink 恢复
src/audio.cpp, src/platform/windows/audio.cpp
stop_audio_control 在恢复 sink 前检查 should_restore_sink()。当结果为 false 时,跳过恢复。
Web 设置、文档与本地化
src_assets/common/assets/web/composables/useConfig.js, src_assets/common/assets/web/configs/tabs/AudioVideo.vue, docs/configuration.md, src_assets/common/assets/web/public/assets/locale/*
Windows 设置页面新增复选框。默认配置、配置文档和多语言文本新增 virtual_sink_lock 内容。英文资源同时调整两个键的顺序。

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: 🔵 Low · up to d99a8

When output locking is disabled, a stale preservation decision may carry across streams and cause a later stream to leave the system using the wrong audio output instead of restoring the prior device. This is a bounded Windows audio-routing issue and the PR is mergeable with explicit owner awareness or follow-up.

Sequence Diagram(s)

sequenceDiagram
  participant Windows音频捕获
  participant 默认端点变更回调
  participant 音频控制
  participant 流停止逻辑
  Windows音频捕获->>默认端点变更回调: 检测默认输出设备变更
  默认端点变更回调->>音频控制: 更新保留默认输出标志
  默认端点变更回调-->>Windows音频捕获: 返回是否重新初始化
  流停止逻辑->>音频控制: 查询 should_restore_sink()
  音频控制-->>流停止逻辑: 返回恢复决定
  流停止逻辑->>Windows音频捕获: 恢复或保留当前输出设备
Loading

Suggested reviewers: qiin2333, yundi339

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 12 functions across 6 files. (22 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed 标题准确概括了主要变更:为虚拟音频输出锁定行为增加可配置选项。标题简洁且与代码、配置和界面变更一致。
Description check ✅ Passed 描述详细说明了 virtual_sink_lock 的行为、默认值、实现范围、兼容性和测试结果,与变更内容一致。
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 12 functions across 6 files. (22 skipped: 22 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Yundi339

Copy link
Copy Markdown
Member

在使用虚拟音频设备进行串流时,只要 Windows 默认音频输出设备发生变化,Sunshine 就会立即将其重新切换到虚拟音频设备。

这是个bug,只是一直没修。正常重装虚拟声卡驱动,或者是卸载虚拟声卡驱动,也能解决。不需要加配置来优化

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.

2 participants