1. 问题来源
系统是Windows11 24H2版本,音频设备使用的是一款飞傲家的FiiO BTR7蓝牙解码耳放,蓝牙不怎么用,大多数时候还是直接连接电脑当作有线DAC使用,后面内容对这个设备就用DAC来称呼。
使用时碰到一个问题是,在Windows11系统进入睡眠状态后,从睡眠状态唤醒,随意打开一个能播放声音的软件。例如音乐软件,可以明显感觉到声音变慢,一些软件播放视频还会有丢失声音的情况。
2. 寻找解决方案
由于主机隔一段时间不用会自动进入睡眠,这时候一个解决办法就是直接不让它进入睡眠就可以了,保持唤醒状态。但这么做耗电少不了一点,睡眠状态在微软官方说法中,属于S3状态。在S3状态下,主机仅保留内存持续运行,其他如CPU或者硬盘就会处于关闭状态,直到唤醒。这么做能在不用电脑的情况下,节省一定的电。
睡眠在一定时间后,还会进入休眠状态,也就是S4状态。休眠实际上和关机类似,关机是S5状态。休眠和关机都是把主机关闭掉,唯一的区别是,休眠关机前会把内存中的数据存放在硬盘上的休眠文件中,下次从休眠状态开机时,还保留着之前打开的软件,可以使用键鼠设备进行唤醒。而刚好在睡眠状态下,内存一直保存运行状态,进入休眠前就刚好把内存中的数据保存下来,最后关机。至于S5关机状态,关机后就需要用电源键或者WOL唤醒开机,无法用键鼠唤醒。
这样做的一个好处,如果长时间主机忘记关机的情况下,一定时间后进入睡眠。如果仍有一段时间没有唤醒,就进入休眠状态,主机关机。进入休眠后,即使给主机供电的设备出现意外断电的情况,也不用担心数据丢失。 微软官方提供的电源状态说明:
所以如果一直保持唤醒状态,不进入睡眠直到休眠,在长时间使用的情况下,各种意外风险因素可能逐渐增加,导致系统运行数据丢失。这个方案就PASS了,还需要寻找其他方案。
这个问题早在大半年之前就出现了,当时是查询了各种资料,中文互联网上有关解决这个问题的资料少之又少。英文互联网上有搜到一些类似的问题,但也没给出解决方法。我自己摸索出的一个解决办法就是,在睡眠唤醒后,手动去切换音频设备的输出格式,这样声音就能恢复正常了。如下图里的设置,把当前的格式切换成另一个即可:
之后日常用基本是靠这种办法解决,但终究很难受,直到前几天才想起来一个办法,为什么不尝试用脚本去帮我自动化处理。虽然没法根治问题,但至少保证日常用不需要我自己手动处理,也能达到一样的效果。
于是尝试询问deepseek,问他能不能给我一个脚本解决方案。还真给出了方案,综合询问下来有两种方案:
- 使用SoundVolumeView工具,配合脚本执行命令达成目的
- 使用C#编写一个程序,通过Windows提供的 Core Audio API或第三方库,例如NAudio来达成。
第二种方案经过实测,如果用NAudio库来实现,是临时修改的效果,并不能实现直接修改。而如果用Core Audio API,实现过于复杂,只能尝试使用第一种方案。
3. 最终解决方案
使用第一种方案的过程中也不是想象中那么容易,中间又出现了其他各种问题,反复测试修改才实现了效果。
首先是SoundVolumeView这个工具,说实话如果不是为了解决这个问题,可能一辈子都碰不到这个软件。但这个软件确实很厉害,能通过命令调用工具来达成切换输出格式的效果。这里需要注意,AI给出的调用命令是错误的,需要参照官方的文档说明来编写。
其次是Powershell脚本的编写和任务计划执行,脚本本身可以让AI辅助编写修改,但是任务计划执行这块,AI给出的答案有问题。如果按它说的弄,任务计划无法正常执行脚本的。
最后即使脚本顺利执行了,没想到还有新的问题。原来编写的切换输出格式方案是,先切换和当前格式不一样的,再切换回去。大多数时候我都这样做的,能让声音恢复正常。结果任务计划执行后,发现声音依然存在问题,后来才发现,大多数时候我切换,是因为听到声音出现问题了才去切换,声音在播放的情况下这种切换法是正常的。
最后选择两种常用的输出格式,正常也听不出区别的,每次检测到当前是啥格式,就切换另一种格式。这里AI还出了个错的代码,想通过工具命令读取当前格式,但根据文档说明,压根没有这个东西。
Tips:事实上后面测试发现,即使只切换了另一种输出格式,依然无法恢复正常,最后是通过先切换到16位48000hz,然后再切换到与当前输出格式不一样的格式,才达成了效果。
接下来就是实际解决问题的过程办法了,如果你碰到类似睡眠唤醒后,声音异常的情况下,可以通过切换输出格式解决的,可以尝试本方案。这里需要你对powershell脚本有一定的了解,一般直接去微软商店中搜索安装powershell,配合Windows Terminal就能使用了。
微软商店里的两个软件:
首先去下面的链接里下载SoundVolumeView工具,并解压到相应的目录: https://www.nirsoft.net/utils/soundvolumeview-x64.zip
接着找一个目录,新建个文件夹,例如叫FixAudio文件夹,文件夹下有三个文件需要你新建一下,注意后缀名。分别是下面三个文件:
- config.json 用于保存当前音频输出格式配置
- FixAudio.ps1 powershell执行脚本
- FixAudioLog.txt 执行输出日志,便于核对调试
config.json的内容如下:- {
- "bit": 24,
- "hz": 96000
- }
复制代码 bit就是位数,16、24、32这种
hz就是44100、96000、192000这种
他们各自的值设置成你系统当前设置的输出格式 FixAudio.ps1内容如下:- # 设置控制台输出编码为 UTF-8
- [console]::OutputEncoding = [System.Text.Encoding]::UTF8
- # 设置路径(包含中文)
- $toolPath = "E:\软件\音频工具\soundvolumeview-x64\SoundVolumeView.exe"
- $deviceName = "FiiO Q series"
- $configPath = "$PSScriptRoot\config.json"
- # 读取当前音频输出格式配置
- $config = Get-Content -Path $configPath | ConvertFrom-Json
- $bit = $config.bit
- $hz = $config.hz
- # 日志文件路径
- $logFile = "$PSScriptRoot\FixAudioLog.txt"
- # 写入日志函数
- function Write-Log {
- param ([string]$message)
- try {
- Add-Content -Path $logFile -Value "$(Get-Date): $message"
- }
- catch {
- Write-Host "日志写入失败: $_" -ForegroundColor Red
- }
- }
- function changeAudioFormat {
- param ()
- try {
- # 切换到 48000Hz 16位
- Write-Log "切换到 48000Hz 16位"
- & $toolPath /setDefaultFormat $deviceName 16 48000
- Start-Sleep -Seconds 2
- }
- catch {
- Write-Log "切换音频格式失败: $_"
- }
-
- }
- try {
- Write-Log "开始执行脚本..."
- Write-Log "工具路径: $toolPath"
- Write-Log "设备名称: $deviceName"
- # 检查工具路径是否存在
- Write-Log "开始检查工具路径..."
- if (-Not (Test-Path $toolPath)) {
- Write-Log "错误: 找不到工具路径 $toolPath"
- exit
- }
- Write-Log "工具路径检查通过"
- if ($bit -eq 24 -and $hz -eq 96000) {
- changeAudioFormat
- Write-Log "当前音频输出格式为 24 位 96000Hz,切换为 24 位 192000Hz。"
- & $toolPath /setDefaultFormat $deviceName 24 192000
- #保存当前音频输出格式
- $config.bit = 24
- $config.hz = 192000
- $config | ConvertTo-Json | Set-Content -Path $configPath -Encoding UTF8
- }
- elseif ($bit -eq 24 -and $hz -eq 192000) {
- changeAudioFormat
- Write-Log "当前音频输出格式为 24 位 192000Hz,切换为 24 位 96000Hz。"
- & $toolPath /setDefaultFormat $deviceName 24 96000
- #保存当前音频输出格式
- $config.bit = 24
- $config.hz = 96000
- $config | ConvertTo-Json | Set-Content -Path $configPath -Encoding UTF8
- }
- else {
- Write-Log "当前音频输出格式不符合预期,无法执行操作。"
- exit
- }
- # # 切换到 48000Hz 16位
- # Write-Log "切换到 48000Hz 16位"
- # & $toolPath /setDefaultFormat $deviceName 16 48000
- # Start-Sleep -Seconds 2
- # # 切换回 96000Hz 24位
- # Write-Log "切换回 96000Hz 24位"
- # & $toolPath /setDefaultFormat $deviceName 24 96000
- # Write-Log "操作完成!"
- # # 启用空间音效
- # Write-Log "启用空间音效"
- # & $toolPath /SetSpatial $deviceName "Windows Sonic For Headphones"
- # Start-Sleep -Seconds 2
- # # 禁用空间音效
- # Write-Log "禁用空间音效"
- # & $toolPath /SetSpatial $deviceName ""
- # Write-Log "操作完成!"
- }
- catch {
- Write-Log "脚本执行出错: $_"
- }
复制代码 上面两个文件和配置弄好后,可以直接手动用powershell执行一下看有没有达到切换的效果。可以右键FixAudio.ps1,找到使用Powershell运行。如果没切换成功,就可以查看同一目录生成的FixAudioLog.txt文件,看报错的情况。
如果执行没问题,接下来就是弄任务计划,我指定的是在系统睡眠后唤醒后,自动执行一次这个脚本。
按下Win+R键,输入taskschd.msc,就能打开任务计划。在右边操作中点击创建任务,注意不是创建基本任务。
常规配置:
新建触发器参考,开始任务选择工作站解锁时:
操作参考,选择启动程序,程序或脚本是powershell的目录,添加参数参考下面发的:
程序或脚本:- "C:\Program Files\WindowsApps\Microsoft.PowerShell_7.5.0.0_x64__8wekyb3d8bbwe\pwsh.exe"
复制代码 如果你不确定自己电脑上的powershell脚本目录,在打开powershell终端后,输入下面的命令就可以得到 目录:
添加参数(File后面就是你的脚本位置):- -ExecutionPolicy Bypass -File "E:\脚本\FixAudio\FixAudio.ps1"
复制代码 起始于:就是脚本所在硬盘。 在任务计划创建好后,可以尝试右键这个任务计划,立即执行一遍核对效果。如果还有其他的问题,可以多尝试询问AI。 目前通过这个办法,成功解决了让我头疼大半年的问题,也不用去买新的来替代,除了要花点时间成本以外,还能顺带学习巩固一下powershell脚本的知识。 感
谢您的阅读,每一次的阅读都是汲取知识和互相讨论交流的机会~
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |