是否有一种便携式的、不受专利限制的方式来在 C# / .Net 中播放压缩声音文件?我想在程序中发生的各种事件上播放简短的“叮当”声音。

系统.媒体.SoundPlayer 只能处理 WAV,但这些文件通常太大而无法嵌入可下载的应用程序中。MP3 受专利保护,因此即使有完全托管的解码器/播放器,也不能自由地重新分发。可用的最佳格式似乎是 OGG Vorbis,但我没有运气让任何 C# Vorbis 库运行(我设法使用以下命令提取原始 PCM 斯沃比斯 但我不知道之后怎么玩)。

我既不想随应用程序分发任何二进制文件,也不想依赖 P/Invoke,因为该项目至少应该在 Windows 和 Linux 上运行。我很乐意捆绑 .Net 程序集,只要它们与 GPL 许可证兼容即可。

[这个问题是一个后续问题 mono-dev 上的邮件列表讨论 一年前的邮件列表]

有帮助吗?

解决方案

我终于重新审视了这个主题,并且利用了 BrokenGlass 写入 WAVE 标头, ,更新了 csvorbis。我添加了一个 奥格解码流 可以传递给 System.Media.SoundPlayer 简单地播放任何(兼容的)Ogg Vorbis 流。用法示例:

using (var file = new FileStream(oggFilename, FileMode.Open, FileAccess.Read))
{
  var player = new SoundPlayer(new OggDecodeStream(file));
  player.PlaySync();
}

在这种情况下,“兼容”意味着“当我尝试时它有效”。解码器是完全托管的,在 Microsoft .Net 上运行良好 - 目前,Mono 中似乎存在回归 SoundPlayer 这会导致失真。

过时的:

System.Diagnostics.Process.Start("fullPath.mp3");

我很惊讶但是 黛娜提到的方法 实际上有效。但是,我正在考虑在程序中发生的各种事件中播放简短的“叮当声”,我不想每次需要进行'ping!'时启动用户的媒体播放器。声音。

至于代码项目链接 - 不幸的是,这只是一个 P/Invoke 包装器。

其他提示

我既不想在我的应用程序中分发任何二进制文件,也不要依赖于P/Invoke,因为该项目至少应该在Windows和Linux上运行。只要它们与GPL兼容,我可以捆绑.NET组件。

不幸的是,要避免分发二进制文件或避免 P/Invoke 是不可能的。无论如何,.net 类库在底层使用 P/Invoke,托管代码必须在某个时刻与非托管操作系统 API 进行通信,以便执行任何操作。

在托管代码中应该可以将 OGG 文件转换为 PCM,但由于 .net 中没有对音频的本机支持,因此您实际上有 3 个选择:

  1. 调用外部程序来播放声音(如前面所建议的)

  2. P/调用C模块播放声音

  3. P/调用OS API来播放声音。

(4.) 如果您只在 Windows 上运行此代码,您可能只需使用 DirectShow。

P/Invoke可以跨平台方式使用http://www.mono-project.com/Interop_with_Native_Libraries#Library_Names

一旦你有了 PCM 数据(使用 OGG C Lib 或托管代码,类似这样 http://www.robburke.net/mle/mp3sharp/ 当然,MP3 存在许可问题),您需要一种播放它的方法,不幸的是 .net 不提供对您的声卡的任何直接评估或播放流音频的方法。您可以在启动时将 ogg 文件转换为 PCM,然后使用 System.Media.SoundPlayer 来播放生成的 wav 文件。目前微软建议使用P/Invoke来访问操作系统中的声音播放API http://msdn.microsoft.com/en-us/library/ms229685.aspx

播放 PCM 声音的跨平台 API 是 OpenAL,您应该能够使用 www.taoframework.com 上 OpenAL 的 c# 绑定来播放 (PCM) 声音,不幸的是,您需要使用您的应用程序复制许多 DLL 和 .so 文件。应用程序,以便它在分发时工作,但正如我之前解释的那样,这是不可避免的。

调用位于“System.Diagnostics”中的东西来播放声音对我来说似乎是一个非常糟糕的主意。该函数的用途如下:

    //
    // Summary:
    //     Starts a process resource by specifying the name of a document or application
    //     file and associates the resource with a new System.Diagnostics.Process component.
    //
    // Parameters:
    //   fileName:
    //     The name of a document or application file to run in the process.
    //
    // Returns:
    //     A new System.Diagnostics.Process component that is associated with the process
    //     resource, or null, if no process resource is started (for example, if an
    //     existing process is reused).
    //
    // Exceptions:
    //   System.ComponentModel.Win32Exception:
    //     There was an error in opening the associated file.
    //
    //   System.ObjectDisposedException:
    //     The process object has already been disposed.
    //
    //   System.IO.FileNotFoundException:
    //     The PATH environment variable has a string containing quotes.

我认为你应该看看 fmod,它是所有音频 api 之母

请随意梦想 http://www.fmod.org/index.php/download#FMODExProgrammersAPI

XNA 音频 API 在 .net/c# 应用程序中运行良好,并且非常适合此应用程序。基于事件的触发,以及多个声音的并发播放。正是您想要的。哦,还有压缩。

嗯,这取决于特定国家的专利相关法律,但据我所知,没有办法在不违反专利的情况下编写 mp3 解码器。我认为解决您问题的最佳跨平台开源解决方案是 GStreamer. 。它具有快速发展的 C# 绑定。然而,在 Windows 上使用和构建 GStreamer 并不是一件容易的事。 这里 是一个很好的起点。 女妖 项目使用了这种方法,但它在 Windows 上还不能真正使用(但是,有一些几乎可以工作的夜间构建)。 调频调制 也是一个不错的选择。不幸的是,它不是开源的,而且我发现它的 API 在某种程度上是 C 风格的。

有一个开源的纯 C# vorbis 解码器可用:

http://anonsvn.mono-project.com/viewvc/trunk/csvorbis/

不确定这是否仍然相关。最简单的解决方案是使用 NA音频, ,这是一个用 C# 编写的托管开源音频 API。另一件可以尝试的事情是利用 ffmpeg,并创建一个进程 ffplay程序 (正确的二进制文件位于共享构建下)。

如果不使用其他东西来进行游戏处理,您就无法做到这一点。

使用 System.Diagnostic 将启动外部软件,我怀疑您想要这样,对吧?您只想当程序中发生 Y 时 X 声音文件在后台播放,对吗?

投票是因为这看起来是一个有趣的问题。:D

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top