admin管理员组

文章数量:1530085

        最近在做一款软件,需要用到声音播放,同时实现背景音乐和音效的播放。在C#中声音的播放主要有六种方法:

         1.播放系统事件声音

         2.使用SoundPlayer

         3.使用API函数播放

         4.使用axWindowsMediaPlayer的COM组件来播放

         5.Microsoft speech object Library

         6.使用directX

         具体的使用方式在网上都能找到,可参考believe209的文章,本文不再做复述。(C#播放声音【六种方法】_c# 播放声音-CSDN博客)

        这里要说的是几种播放声音的测试结果,希望可以帮助在用到C#做声音播放应用的朋友。我们在开发应用的时候,常常需要同时播放多种声音,比如同时播放背景音乐和音效。这几种播放方式同时使用可能会发生冲突,停止当前播放声音,只去播放一种声音,达不到应用效果,我怀疑几种播放方式都是调用的SoundPlayer来进行播放的;我也遇到过在测试环境下播放声音正常,程序打包后无法正常播放的情况;特别是采用axWindowsMediaPlayer的COM组件来播放,文件装载延时大约2秒左右,影响软件体验效果,如果对延时要求不高的播放场景可以选择这种方式。在实际编程中,可根据不的需要选择不同的播放组合方式。

        我运用的是SoundPlayer和directX两种方式播放声音,效果较好,后面我把调用方式和遇到的问题都附在文章后面。

一、播放系统事件声音,简单语句可以实现声音播放。缺点:只能播放系统定义的声音,无法进行属性设置和修改,播放方式固定。

         System.Media.SystemSounds.Question.Play();

二、.使用SoundPlayer

         SoundPlayer player = new SoundPlayer();

         player.SoundLocation = @"C:\test.wav";     //声音文件路径

         // Application.StartupPath + @”\ test.wav”   // Debug文件夹

         player.Load(); //加载声音

         player.Play(); //启用新线程播放

         //player.PlayLooping(); //循环播放模式

         缺点:不能同时播放声音,只能播放wav声音文件,可用来循环播放背景音乐。

三、使用API函数播放

        通过调用外部winmm.dll方式播放声音,winmm.dll有三个声音播放函数,mciSendString可以播放mp3文件,其它函数也只有播放wav。这种方式在调试状态可以和SoundPlayer同时播放声音文件,不知道是不是配置问题,打包后无法播放声音,没有找到原因,如果有知道原因的大神可以在评论区告知一下,谢谢!

         [DllImport("winmm.dll", SetLastError = true)]

         static extern bool PlaySound(string pszSound, UIntPtr hmod, uint fdwSound);

        [DllImport("winmm.dll", SetLastError = true)]

        static extern long mciSendString(string strCommand,

        StringBuilder strReturn,int iReturnLength, IntPtr hwndCallback);

         [DllImport("winmm.dll")]

         private static extern long sndPlaySound(string lpszSoundName, long uFlags);

四、使用axWindowsMediaPlayer的COM组件来播放

        如果已添加了组件。工具箱->组件-> Windows Media Player,把Windows Media Player控件拖放到Winform窗体中。

        如查没有添加,在左侧打开“工具箱”,在“工具箱”内点右键,选择右键菜单“选择项”,在“选择工具箱项“窗口中,选择“COM组件”项,下拉到“Windows Media Player”,在单选框上打上勾,点击确定后组件被加入到工具箱中。如果只需要播放声音,将“Windows Media Player”的Visible属性设置为false即可。

axWindowsMediaPlayer1.URL = "123.mp3";   //不同版本设置有所不同

axWindowsMediaPlayer1.Ctlcontrols.play();

axWindowsMediaPlayer1.Ctlcontrols.Play          播放

axWindowsMediaPlayer1.Ctlcontrols.Stop          停止

axWindowsMediaPlayer1.Ctlcontrols.Pause          暂停

axWindowsMediaPlayer1.settings.playCount      文件播放次数

axWindowsMediaPlayer1.settings.balance         声道

axWindowsMediaPlayer1.settings.volume         音量

axWindowsMediaPlayer1.settings.mute          静音

五、Microsoft speech object Library

        在项目上单击右键菜单,“添加”->“引用“,打开引用管理器,在”COM“项目中找到“Microsoft speech object Library”,点击“确定”。

public voidPlaySound(string FileName){

         SpeechLib.SpVoiceClass Sp = new SpeechLib.SpVoiceClass();

        SpeechLib.SpFileStreamClass SpFs = new SpeechLib.SpFileStreamClass();

        SpFs.Open(FileName, SpeechLib.SpeechStreamFileMode.SSFMOpenForRead,true);

        SpeechLib.ISpeechBaseStream Istream = SpFs as SpeechLib.ISpeechBaseStream;

        Sp.SpeakStream(Istream, SpeechLib.SpeechVoiceSpeakFlags.SVSFIsFilename);

        SpFs.Close();

}

         Microsoft speech object Library可以将文字转换为语音做语音功能,实现语音播报,也可以将语音识别为文字,很强大的东东,拿来播放声音文件个人感觉有点大材小用。

六、使用directX

         这个比较复杂,网上大多讲得比较简单,在使用过程中遇到问题最多。

         1.下载链接:微软官方下载链接

                  https://www.microsoft/en-us/download/details.aspx?id=6812

         2.下载后运行安装。安装后的目录结构如下

问题一 :安装后命名空间无效  :具体方法:

using Microsoft.DirectX;

using Microsoft.DirectX.DirectSound;

1.安装SDK之后

他默认的位置在

C:\Windows\Microsoft.NET\DirectX for Managed Code
C:\WINDOWS\Microsoft.NET\Managed DirectX

不同版本安装文件夹名不一样


2.把里面相应版本的Microsoft.DirectX.Direct3DX.Dll都复制到,这需要与VS使用的运行环境版本文件夹位置一致
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1

C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0

3.在项目里面就可以添加引用了,这时就不会报错。

问题二 :调试运行程序卡死   解决办法:

修改配置文件App.config,修改方法如下:

App.config

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

    <startup>

        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />

    </startup>

</configuration>

修改后的App.config,添加红色字体部分

<?xml version="1.0" encoding="utf-8"?>

<configuration>

    <startup useLegacyV2RuntimeActivationPolicy="true">

        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/>

    </startup>

</configuration>

问题三:  调试报错为托管程序锁定    解决方案:

正尝试在 OS 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码,这样做会导致应用程序挂起。

 把VS菜单的 调试->窗口->异常设置->Managed Debuggin Assistants->LoaderLock 的选中状态去掉。如图

问题4:System.TypeInitializationException

该错误是因为系统没有检测到麦克风引起,所以解决方法是
- 在程序中增加异常处理机制,捕捉异常,及时处理并做相应提示。
- 插入麦克风,或者启用虚拟麦克风

我采用第一种方法,用try异常过滤器忽略掉系统检测

public static Device dv;    //建立设备

        public static SecondaryBuffer buf;    //设置缓冲对像

        public static void mciPlay(string YXfilename)

        {

            try

            {

                dv = new Device();

                dv.SetCooperativeLevel(new UF(), CooperativeLevel.Normal);//设置设备协作级别  必须设置,否则无播放声音

                buf = new SecondaryBuffer(YXfilename, dv);//(YXfilename, dv);  //开辟缓冲区

                buf.Volume = 0;

                buf.Play(0, BufferPlayFlags.Default);   //第一个参数表示优先级别,0是最低的。第2个参数是播放方式,这里是循环播放。              

            }

            catch {  }

        }

问题5:调试运行DLL版本不一致,编译器会报错,还需要在App.config文件中加入相应的版本号

        有的说将解决方案平台修改一下,X64 改为 X86 ,我试过没什么作用。或许有人通过修改也解决了这个问题。

         在引用DLL文件属性栏中,将复制本地设置为“true”,编译后,系统自动将DLL文件添加到DeBug文件夹里。

本文标签: 音效六种背景音乐声音方法