如何以便携方式播放 C# 中的压缩声音文件?
是否有一种便携式的、不受专利限制的方式来在 C# / .Net 中播放压缩声音文件? 我想在程序中发生的各种事件上播放简短的“叮当”声音。
System.Media.SoundPlayer 只能处理 WAV,但是这些文件通常太大而无法嵌入可下载的应用程序中。 MP3 受专利保护,因此即使有完全托管的解码器/播放器,也不能自由地重新分发。 可用的最佳格式似乎是 OGG Vorbis,但我没有运气让任何 C# Vorbis 库正常工作(我设法使用 csvorbis 但我不知道之后如何玩)。
我既不想随应用程序分发任何二进制文件,也不想依赖 P/Invoke,因为该项目至少应该在 Windows 和 Linux 上运行。 我很乐意捆绑 .Net 程序集,只要它们与 GPL 许可证兼容即可。
[这个问题是邮件列表讨论的后续问题一年前的 mono-dev 邮件列表]
Is there a portable, not patent-restricted way to play compressed sound files in C# / .Net? I want to play short "jingle" sounds on various events occuring in the program.
System.Media.SoundPlayer can handle only WAV, but those are typically to big to embed in a downloadable apllication. MP3 is protected with patents, so even if there was a fully managed decoder/player it wouldn't be free to redistribute. The best format available would seem to be OGG Vorbis, but I had no luck getting any C# Vorbis libraries to work (I managed to extract a raw PCM with csvorbis but I don't know how to play it afterwards).
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.
[this question is a follow up to a mailing list discussion on mono-dev mailing list a year ago]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
有一个开源的纯 C# vorbis 解码器可用:
http://anonsvn。 mono-project.com/viewvc/trunk/csvorbis/
There is a pure C# vorbis decoder available that is open source:
http://anonsvn.mono-project.com/viewvc/trunk/csvorbis/
嗯,这取决于特定国家的专利相关法律,但据我所知,没有办法在不违反专利的情况下编写 mp3 解码器。 我认为解决您的问题的最佳跨平台开源解决方案是 GStreamer。 它具有快速发展的 C# 绑定。 然而,在 Windows 上使用和构建 GStreamer 并不是一件容易的事。 这里是一个很好的初始点。 Banshee 项目使用了这种方法,但它在 Windows 上还不能真正使用(但是,有一些几乎-每晚构建)。 FMOD 也是一个不错的选择。 不幸的是,它不是开源的,而且我发现它的 API 在某种程度上是 C 风格的。
Well, it depends on a patent-related laws in a given country, but there is no way to write a mp3 decoder without violating patents, as far as i know. I think the best cross-platform, open source solution for your problem is GStreamer. It has c# bindings, which evolve rapidly. Using and building GStreamer on Windows is not an easy task however. Here is a good starting point. Banshee project uses this approach, but it is not really usable on windows yet (however, there are some almost-working nightly builds). FMOD is also a good alternative. Unfortunately, it is not open source and i find that its API is somehow C-styled.
不幸的是,要避免分发二进制文件或避免 P/Invoke 是不可能的。 无论如何,.net 类库在底层使用 P/Invoke,托管代码必须在某个时刻与非托管操作系统 API 进行通信,以便执行任何操作。
将 OGG 文件转换为 PCM 应该可以在托管代码中实现,但由于 .net 中没有对音频的本机支持,因此您实际上有 3 个选择:
调用外部程序来播放声音(如之前建议的那样)
P/调用 C 模块来播放声音
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 文件。 目前微软建议使用P/Invoke来访问操作系统中的声音播放API http ://msdn.microsoft.com/en-us/library/ms229685.aspx
用于播放 PCM 声音的跨平台 API 是 OpenAL,您应该能够使用 OpenAL 的 C# 绑定来播放 (PCM) 声音www.taoframework.com,不幸的是,您需要将许多 DLL 和 .so 文件与您的应用程序一起复制,以便它在分发时工作,但正如我之前解释的那样,这是不可避免的。
Unfortunatly its going to be impossible to avoid distributing binaries, or avoid P/Invoke. The .net class libraries use P/Invoke underneath anyway, the managed code has to communicate with the unmanage operating system API at some point, in order to do anything.
Converting the OGG file to PCM should be possible in Managed code, but because there is no Native Support for Audio in .net, you really have 3 options:
Call an external program to play the sound (as suggested earlier)
P/Invoke a C module to play the sound
P/Invoke the OS APIs to play the sound.
(4.) If you're only running this code on windows you could probably just use DirectShow.
P/Invoke can be used in a cross platform way
http://www.mono-project.com/Interop_with_Native_Libraries#Library_Names
Once you have your PCM data (using a OGG C Lib or Managed Code, something like this http://www.robburke.net/mle/mp3sharp/ of course there are licencing issues with MP3), you will need a way to play it, unfortunatly .net does not provide any direct assess to your sound card or methods to play streaming audio. You could convert the ogg files to PCM at startup, and then use System.Media.SoundPlayer, to play the wav files generated. The current method Microsoft suggests uses P/Invoke to access Sound playing API in the OS http://msdn.microsoft.com/en-us/library/ms229685.aspx
A cross platform API to play PCM sound is OpenAL and you should be able to play (PCM) sound using the c# bindings for OpenAL at www.taoframework.com, you will unfortunatly need to copy a number of DLL and .so files with your application in order for it to work when distributed, but this is, as i've explained earlier unavoidable.
XNA 音频 API 在 .net/c# 应用程序中运行良好,并且非常适合此应用程序。 基于事件的触发,以及多个声音的并发播放。 正是您想要的。 哦,还有压缩。
The XNA Audio APIs work well in .net/c# applications, and work beautifully for this application. Event-based triggering, along with concurent playback of multiple sounds. Exactly what you want. Oh, and compression as well.
我认为你应该看看 fmod,它是所有音频 api 之母,
请随意梦想 http://www.fmod.org/index.php/download#FMODExProgrammersAPI
i think you should have a look a fmod, which is the mother of all audio api
please feel free to dream about http://www.fmod.org/index.php/download#FMODExProgrammersAPI
调用位于“System.Diagnostics”中的东西来播放声音对我来说似乎是一个非常糟糕的主意。 该函数的用途如下:
Calling something which is located in 'System.Diagnostics' to play a sound looks like a pretty bad idea to me. Here is what that function is meant for:
我终于重新审视了这个主题,并利用 BrokenGlass 编写 WAVE header 的帮助,更新了 csvorbis。 我添加了一个 OggDecodeStream ,可以传递给 < code>System.Media.SoundPlayer 来简单地播放任何(兼容的)Ogg Vorbis 流。 用法示例:
在这种情况下,“兼容”意味着“当我尝试时它有效”。 解码器是完全托管的,在 Microsoft .Net 上运行良好 - 目前,Mono 的
SoundPlayer
中似乎存在回归,导致失真。过时:
System.Diagnostics.Process.Start("fullPath.mp3");
我很惊讶,但是 黛娜提到的方法确实有效。 但是,我正在考虑在程序中发生的各种事件上播放简短的“叮当”声音,我不想每次需要执行“ping!”时启动用户的媒体播放器。 声音。
至于代码项目链接 - 不幸的是,这只是一个 P/Invoke 包装器。I finally revisited this topic, and, using help from BrokenGlass on writing WAVE header, updated csvorbis. I've added an OggDecodeStream that can be passed to
System.Media.SoundPlayer
to simply play any (compatible) Ogg Vorbis stream. Example usage:'Compatible' in this case means 'it worked when I tried it out'. The decoder is fully managed, works fine on Microsoft .Net - at the moment, there seems to be a regression in Mono's
SoundPlayer
that causes distortion.Outdated:
System.Diagnostics.Process.Start("fullPath.mp3");
I am surprised but the method Dinah mentioned actually works. However, I was thinking about playing short "jingle" sounds on various events occurring in the program, I don't want to launch user's media player each time I need to do a 'ping!' sound.
As for the code project link - this is unfortunately only a P/Invoke wrapper.不确定这是否仍然相关。 最简单的解决方案是使用 NAudio,它是一个用 C# 编写的托管开源音频 API。 另一件可以尝试的事情是利用 ffmpeg,并创建一个 ffplay.exe 的进程(正确的二进制文件是在共享构建下)。
Not sure if this is still relevant. Simplest solution would be to use NAudio, which is a managed open source audio API written in C#. Another thing to try would be utilizing ffmpeg, and creating a process to ffplay.exe (the right binaries are under shared builds).
如果不使用其他东西来进行游戏处理,您就无法做到这一点。
使用 System.Diagnostic 将启动外部软件,我怀疑您想要这样,对吧? 您只想当程序中发生 Y 时 X 声音文件在后台播放,对吧?
投票是因为这看起来是一个有趣的问题。 :D
There is no way for you to do this without using something else for your play handling.
Using the System.Diagnostic will launch an external software and I doubt you want that, right? You just want X sound file to play in the background when Y happens in your program, right?
Voted up because it looks like an interesting question. :D