关于.net:我该如何以可移植的方式在C#中播放压缩的声音文件?

关于.net:我该如何以可移植的方式在C#中播放压缩的声音文件?

How can I play compressed sound files in C# in a portable way?

是否存在一种可移植的,不受专利限制的方法来播放C#/ .Net中的压缩声音文件?我想在程序中发生的各种事件上播放短的"叮当声"。

System.Media.SoundPlayer仅能处理WAV,但通常会将它们嵌入到可下载的附件中。 MP3受专利保护,因此,即使有一个完全托管的解码器/播放器,也无法自由分发。可用的最佳格式似乎是OGG Vorbis,但我没有运气让任何C#Vorbis库都能正常工作(我设法用csvorbis提取了原始PCM,但后来不知道如何播放)。

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

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


我终于重新讨论了这个主题,并在BrokenGlass的帮助下编写WAVE标头时更新了csvorbis。我添加了一个OggDecodeStream,可以将其传递给System.Media.SoundPlayer以简单地播放任何(兼容的)Ogg Vorbis流。用法示例:

1
2
3
4
5
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");

我很惊讶,但黛娜(Dinah)提到的方法确实有效。但是,我正在考虑在程序中发生的各种事件中播放"叮当"声,我不想每次都需要执行" ping"操作时启动用户的媒体播放器!声音。

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


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,托管代码必须在某个时候与unmanage操作系统API进行通信,以执行任何操作。

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

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

  • P /调用C模块播放声音

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

    用于播放PCM声音的跨平台API是OpenAL,并且您应该能够在www.taoframework.com上使用OpenAL的c#绑定来播放(PCM)声音,很遗憾,您需要复制多个DLL和.so文件与您的应用程序一起使用,以使其在分发时能正常工作,但这是不可避免的,正如我之前解释过的。


    我认为您应该看一下fmod,它是所有音频api的母亲。

    请随时梦见http://www.fmod.org/index.php/download#FMODExProgrammersAPI


    调用" System.Diagnostics"中的某个文件播放声音对我来说似乎是个坏主意。该功能的用途是:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
        //
        // 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.


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


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

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


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


    XNA音频API在.net / c#应用程序中运作良好,并且在该应用程序中表现出色。基于事件的触发,以及多个声音的一致播放。正是您想要的。哦,还有压缩。


    如果不使用其他方式进行播放处理,则无法进行此操作。

    使用System.Diagnostic将启动一个外部软件,我怀疑您是否想要这样做,对吗?您只想让X声音文件在程序中出现Y时在后台播放,对吗?

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


    推荐阅读

      确定java按钮响应事件的代码

      确定java按钮响应事件的代码,,* 阅读本文可以结合最后在java登录窗口界面下面是一个链接。 是定义的容器。 容器(CP =得到内容面板); / /

      90后瓶门事件图片

      90后瓶门事件图片,,现在孩子们还太早,有些女孩子总是在门口等一会儿,最近发生了一次酒瓶门事件。 近日,山东一家寄宿学校的一名女生带着一瓶

      如何分卷压缩文件

      如何分卷压缩文件,分卷,文件,本文目录如何分卷压缩文件怎么分卷压缩文件分卷压缩文件(拆分压缩文件) 怎么解压如何解压分卷压缩文件压缩包

      压缩wps背景|在WPS中压缩图片

      压缩wps背景|在WPS中压缩图片,压缩,背景,wps,1.如何在WPS中压缩图片可以在WPS演示中进行,操作步骤如下: 1、在wps演示的工具栏上方点击“插

      唐山打人事件视频源自哪里

      唐山打人事件视频源自哪里,华为,视频,唐山打人事件视频源自哪里唐山打人事件视频来源于哪里?为什么这个网友人敢于发出这个视频?不怕被威胁