使用 System.Media.SoundPlayer 播放 Windows 系统声音

Posted

技术标签:

【中文标题】使用 System.Media.SoundPlayer 播放 Windows 系统声音【英文标题】:Playing Windows System Sounds with System.Media.SoundPlayer 【发布时间】:2014-03-02 04:32:55 【问题描述】:

System.Media.SoundPlayer 是否可能无法播放 c:\Windows\Media 中的 Windows 系统声音??

我有代码:

using (var soundPlayer = 
       new SoundPlayer(@"c:\Windows\Media\Landscape\Windows Notify.wav")) 
 
    soundPlayer.Play(); 

然而,当我运行这段代码时,我得到了错误:

Sound API only supports playing PCM wave files.

我错过了什么吗?有没有办法从 WPF 应用程序播放这些文件? (不将它们转换为 PCM)

【问题讨论】:

【参考方案1】:

SystemSounds 类包含以下预定义的系统声音:

星号 嘟 感叹 手 问题

例如,播放 Stop:

System.Media.SystemSounds.Hand.Play();

所有其他声音都需要您从注册表中读取所需的声音并使用如下代码播放:

SoundPlayer simpleSound = new SoundPlayer(@"c:\Windows\Media\Landscape\Windows Notify.wav");

【讨论】:

你说我应该用什么来播放“所有其他声音”和我在做什么有区别吗?在您的(第二个)示例中,我也没有看到您正在从注册表中读取数据。我错过了什么。【参考方案2】:

这是一个有趣的问题,但答案很简单。在阅读了这个问题之后,我尝试了你的代码并得到了同样的问题,所以我在网上搜索了一个解决方案。虽然没有找到确切的解决方案,但我确实在 *** 上找到了 SoundPlayer not playing any bundled windows sounds PCM wav files 帖子,其中显示了一些成功播放来自 Windows\Media 文件夹的音频文件的代码。

我尝试了 那个 代码并且它起作用了,所以我只需要弄清楚为什么你的示例不起作用。我在音频编辑器中检查了播放的音频文件和您的通知音频文件之间的任何差异,但它们都是绝对是 WAV 文件。

我尝试从Windows\Media\Landscape 文件夹播放不同的音频文件并得到同样的错误。然后我尝试从Windows\Media 文件夹中的不同子文件夹播放音频文件,但仍然出现相同的错误。但是,我随后注意到Windows\Media 文件夹中的许多文件夹都包含相同的音频文件。

这让我开始思考,我最终意识到这些文件夹中的所有音频文件实际上直接在Windows\Media 文件夹中。所以您可以播放声音,但您只需忽略子文件夹中的声音并播放Windows\Media 文件夹中的声音。这将起作用:

SoundPlayer soundPlayer = new SoundPlayer(@"C:\Windows\Media\Windows Notify.wav");
soundPlayer.Play();

但是,我无法告诉您为什么会出现这个奇怪的错误,但我只能假设文件夹中的文件可能是指向 Windows\Media 文件夹中实际文件的某种链接,并且只是由用于将它们分组的操作系统......或类似的东西。

【讨论】:

链接响应中的问题是调用 SoundPlayer.Play() 方法的父进程正在结束并因此取消其子进程。 Play() 从新线程播放声音。 PlaySync() 将是另一个问题的另一个答案,因为它在父线程中播放声音,并会阻止进程在声音播放完毕之前结束。 链接帖子的答案与这篇帖子的答案几乎没有关系,除了它为我提供了一个SoundPlayer对象成功播放的工作示例Windows\Media 文件夹中的音频文件。因此,我认为您关于另一篇文章的有效和正确观点最好放在另一篇文章上。 可能是对的。它仍然让我想知道如何在不将它们转换为 PCM 的情况下播放这些音频文件——而且它们不是 PCM 很奇怪。【参考方案3】:

“横向”是指Windows“声音方案”,其中的wav文件由Windows操作系统使用。正如您已经确定的那样,这些文件不能直接使用。

Landscape 目录中的 Windows Notify.wav 文件与基础 Windows\Media 目录中的 Windows Notify.wav 文件的文件大小相当大; 222KB 与 25.5KB ---

如果您进入“声音”控制面板小程序并浏览到“声音”选项卡,您将看到“声音方案:”的下拉列表,Windows\Media 中的其他文件夹将显示在该列表中。

我没有链接来支持这一点,但是在以编程方式处理控制面板声音无数小时后,我大胆猜测“声音方案”wav 文件只包含相关数据(可能是效果数据),即在运行时播放这些声音的修改版本......我可能对最后一部分大错特错;这只是一个猜测。无论如何,您将无法直接在代码中使用这些声音方案文件。

如果您必须播放通知 wav 的“横向”版本,那么我建议播放声音并将其保存到音频编辑器中的新波形文件中。您可以将 wave 文件添加到您的安装程序/部署项目中,以将其播放到 Windows\Media 文件夹中,并以您已经使用的方式直接调用它。

【讨论】:

【参考方案4】:

由于声音似乎是压缩格式,因此必须先将其解压缩,然后才能使用 SoundPlayer 播放。您可以使用 Windows Audio Compression Manager 解压缩声音进行播放:

https://msdn.microsoft.com/en-us/library/windows/desktop/dd742945(v=vs.85).aspx

但是,这实现起来相当复杂,所以我发现了一个不错的库,可以为您完成所有这些工作,NAudio:

http://naudio.codeplex.com/

使用 NAudio 似乎比使用 System.Media.SoundPlayer 稍微复杂一些,但它似乎也提供了更多功能。

【讨论】:

以上是关于使用 System.Media.SoundPlayer 播放 Windows 系统声音的主要内容,如果未能解决你的问题,请参考以下文章

在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?

今目标使用教程 今目标任务使用篇

Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)

MySQL db 在按日期排序时使用“使用位置;使用临时;使用文件排序”

使用“使用严格”作为“使用强”的备份

Kettle java脚本组件的使用说明(简单使用升级使用)