English 中文(简体)
如何以可移植的方式在C#中播放压缩的声音文件?
原标题:
  • 时间:2008-08-30 11:33:55
  •  标签:

有没有一种便携的、非专利限制的方式可以在C#/.Net中播放压缩的声音文件?我想播放节目中发生的各种事件的简短“顺口溜”声。

System.Media.SoundPlayer只能处理WAV,但这些通常太大了,无法嵌入到可下载的应用程序中。MP3受到专利保护,所以即使有完全管理的解码器/播放器,它也不能免费重新分发。可用的最佳格式似乎是OGG Vorbis,但我没能幸运地让任何C#Vorbis库正常工作(我设法用csvorbis但我不知道之后该怎么玩)。

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

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

最佳回答

我终于重提了这个话题,并在BrokenGlass写WAVE头,更新了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 s<code>SoundPlayer

过时的:

System.Diagnostics.Process.Start(“fullPath.mp3”)

我很惊讶,但Dinah提到的方法确实有效。然而,我正在考虑播放程序中发生的各种事件的简短“顺口溜”声音,我不想每次需要发出ping!声音时都启动用户的媒体播放器。

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

问题回答

I neither want to distribute any binaries with my application nor depend on P/Invoke, as the project should run at least on Windows and Linux. I m fine with bundling .Net assemblies as long as they are license-compatible with GPL.

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

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

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

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

  3. P/调用操作系统API来播放声音。

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

P/Invoke can be used in a cross platform way 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文件,以便在分发时使其工作,但正如我之前解释的那样,这是不可避免的。

调用位于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并不是一件容易的事。这里是一个很好的起点。Banshee项目使用了这种方法,但它还不能在windows上真正使用(然而,有一些几乎可以在夜间运行的构建)。FMOD也是一个很好的选择。不幸的是,它不是开源的,我发现它的API在某种程度上是C风格的。

有一个纯粹的C#vorbis解码器是开源的:

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

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

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

使用System.Diagnostic会启动一个外部软件,我怀疑你是否想要,对吧?当Y出现在你的程序中时,你只想让X声音文件在后台播放,对吧?

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





相关问题