19

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

System.Media.SoundPlayer只能处理 WAV,但它们通常太大而无法嵌入可下载的应用程序中。MP3 受专利保护,因此即使有完全托管的解码器/播放器,也不能免费重新分发。可用的最佳格式似乎是 OGG Vorbis,但我没有让任何 C# Vorbis 库工作(我设法用csvorbis提取原始 PCM,但我不知道之后如何播放它)。

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

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

4

9 回答 9

8

我终于重新审视了这个话题,并在BrokenGlass 的帮助下编写 WAVE header,更新了 csvorbis。我添加了一个OggDecodeStream可以传递给它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 包装器。

于 2008-08-30T15:41:12.307 回答
2

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

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

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

  1. 调用外部程序来播放声音(如前所述)

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

  3. P/调用操作系统 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 文件。Microsoft 建议的当前方法使用 P/Invoke 访问操作系统中的声音播放 API http://msdn.microsoft.com/en-us/library/ms229685.aspx

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

于 2009-06-02T12:07:04.423 回答
1

调用位于“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.
于 2008-09-24T23:36:14.597 回答
1

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

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

于 2010-03-19T01:55:03.383 回答
0

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

于 2010-05-20T13:42:23.450 回答
0

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

于 2010-05-23T11:57:23.707 回答
0

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

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

于 2010-05-24T02:35:20.727 回答
0

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

于 2011-08-02T14:55:40.027 回答
-1

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

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

投票赞成,因为它看起来像一个有趣的问题。:D

于 2009-10-18T23:01:29.923 回答