Naudio:如何播放MP3和WAV文件?

时间:2021-09-01 19:44:41

Okay, I know this sounds like a very easy question to some but I am really stuck here. Indeed, I am building an audio player using Naudio and I have realized that in many tutorials people always show easy ways to get you started. However, in my opinion, they always forget to show how things are actually done in a real application. For example, when playing music with Naudio, I would do something like:

好吧,我知道这听起来像是一个很简单的问题,但我真的被困在这里了。实际上,我正在使用Naudio构建一个音频播放器,我意识到在许多教程中,人们总是展示简单的方法让你开始学习。然而,在我看来,他们总是忘记在实际的应用程序中显示事情是如何完成的。例如,在使用Naudio播放音乐时,我会做以下事情:

  Void PlayAudioMusic(string FilePath)

  {

     using (var ms = File.OpenRead(FilePath))
    using (var rdr = new Mp3FileReader(ms))
    using (var wavStream = WaveFormatConversionStream.CreatePcmStream(rdr))
    using (var baStream = new BlockAlignReductionStream(wavStream))
    using (var waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback()))
    {
        waveOut.Init(baStream);
        waveOut.Play();

    }
 }

This is great for testing in a simple console application. This however isn't useful if you're actually building a serious application. For example, what many tutorials never say is for example how to handle the most critical things such as:

这对于在简单的控制台应用程序中进行测试非常有用。但是,如果您实际上正在构建一个严肃的应用程序,那么这就没有用了。例如,许多教程从来没有说过如何处理最重要的事情,比如:

  1. Disposing resource and when to do it
  2. 处理资源,何时处理
  3. The best ways to handle different exceptions
  4. 处理不同异常的最佳方法
  5. What to do before you pause, stop, rewind or even exit the application
  6. 在暂停、停止、倒回甚至退出应用程序之前该怎么做
  7. Other stuffs I don't even know exist. Since I am going through this process and have notice that my application has way too many exceptions thrown, can someone please share like a wrapper class around Naudio that he used to handle this. I am sure this will answer many of the trouble some of us have been going through when trying to use Naudio.
  8. 其他我不知道存在的东西。由于我正在经历这个过程,并且注意到我的应用程序抛出了太多的异常,是否有人可以像以前处理Naudio的包装类那样共享它。我相信这将会解决我们一些人在尝试使用Naudio时遇到的许多麻烦。

Thanks.

谢谢。

1 个解决方案

#1


6  

  1. To Dispose the unmanaged resources, you call the Close method of the WaveStreams. The "when to do it" part is rather obvious... Do you really don't know when it is the right time to Dispose unmanaged resources? You Dispose them when you are not going to use them anymore.
  2. 要处理未管理的资源,可以调用WaveStreams的Close方法。“什么时候做”的部分很明显……你真的不知道什么时候应该处理非托管资源吗?当你不再使用它们的时候,你就把它们处理掉。
  3. I can't answer this one. Sorry.
  4. 我不能回答这个问题。对不起。
  5. To Pause, you call the Pause method of the WaveOut object. To rewind, you call the Seek method of the WaveStream. To Stop, DON'T call the Stop method of the WaveOut. You must call Pause and then call the Seek method of the WaveStream to go to the beginning of the buffer.
  6. 要暂停,可以调用WaveOut对象的暂停方法。要倒回去,你就得叫那瓦维斯特兰的寻找方法。要停止,不要调用波形停止方法。您必须调用Pause,然后调用WaveStream的Seek方法,以到达缓冲区的开头。
  7. The most probable cause of all the Exceptions being thrown is because most of the code you shown is actually unnecessary. All you should need to do to play a MP3 file is:
  8. 抛出所有异常的最可能原因是,您所显示的大多数代码实际上是不必要的。播放MP3文件所需要做的就是:

.

WaveStream mainOutputStream = new MP3FileReader(path_of_the_file_you_want_to_play);
WaveChannel32 volumeStream = new WaveChannel32(mainOutputStream);

WaveOutEvent player = new WaveOutEvent();

player.Init(volumeStream);

player.Play();

I personally prefer to use WaveOutEvent instead of WaveOut because it does not require you to be using Forms nor WPF, enabling you to use NAudio for absolutely any kind of application you want make with C#, even XNA games. Also, WaveOutEvent has a very fire-and-forget usability, and it's constructor not even asks for a Callback.

我个人更倾向于使用wave而不是wave,因为它不需要你使用表格或WPF,你可以使用NAudio来完成任何你想用c#,甚至是XNA游戏的应用程序。此外,WaveOutEvent有一种容易被遗忘的可用性,它的构造函数甚至不会要求回调。

All these WaveStreams meant for changing stuff about the buffer (such as Sample Rate of Bit Depth) are just ways of asking for NAudio to throw an exception. They rarely work when used like this. If you want to convert some stuff of the buffers, you have to call some Static methods of the WaveFormatConversionStream (their names are self-explanatory, at least.)

所有这些用于修改缓冲区内容的WaveStreams(例如,比特深度的采样率)只是请求NAudio抛出异常的一种方式。它们很少像这样使用。如果您想要转换缓冲区的某些内容,您必须调用一些波格式转换流的静态方法(至少它们的名称是自解释的)。

#1


6  

  1. To Dispose the unmanaged resources, you call the Close method of the WaveStreams. The "when to do it" part is rather obvious... Do you really don't know when it is the right time to Dispose unmanaged resources? You Dispose them when you are not going to use them anymore.
  2. 要处理未管理的资源,可以调用WaveStreams的Close方法。“什么时候做”的部分很明显……你真的不知道什么时候应该处理非托管资源吗?当你不再使用它们的时候,你就把它们处理掉。
  3. I can't answer this one. Sorry.
  4. 我不能回答这个问题。对不起。
  5. To Pause, you call the Pause method of the WaveOut object. To rewind, you call the Seek method of the WaveStream. To Stop, DON'T call the Stop method of the WaveOut. You must call Pause and then call the Seek method of the WaveStream to go to the beginning of the buffer.
  6. 要暂停,可以调用WaveOut对象的暂停方法。要倒回去,你就得叫那瓦维斯特兰的寻找方法。要停止,不要调用波形停止方法。您必须调用Pause,然后调用WaveStream的Seek方法,以到达缓冲区的开头。
  7. The most probable cause of all the Exceptions being thrown is because most of the code you shown is actually unnecessary. All you should need to do to play a MP3 file is:
  8. 抛出所有异常的最可能原因是,您所显示的大多数代码实际上是不必要的。播放MP3文件所需要做的就是:

.

WaveStream mainOutputStream = new MP3FileReader(path_of_the_file_you_want_to_play);
WaveChannel32 volumeStream = new WaveChannel32(mainOutputStream);

WaveOutEvent player = new WaveOutEvent();

player.Init(volumeStream);

player.Play();

I personally prefer to use WaveOutEvent instead of WaveOut because it does not require you to be using Forms nor WPF, enabling you to use NAudio for absolutely any kind of application you want make with C#, even XNA games. Also, WaveOutEvent has a very fire-and-forget usability, and it's constructor not even asks for a Callback.

我个人更倾向于使用wave而不是wave,因为它不需要你使用表格或WPF,你可以使用NAudio来完成任何你想用c#,甚至是XNA游戏的应用程序。此外,WaveOutEvent有一种容易被遗忘的可用性,它的构造函数甚至不会要求回调。

All these WaveStreams meant for changing stuff about the buffer (such as Sample Rate of Bit Depth) are just ways of asking for NAudio to throw an exception. They rarely work when used like this. If you want to convert some stuff of the buffers, you have to call some Static methods of the WaveFormatConversionStream (their names are self-explanatory, at least.)

所有这些用于修改缓冲区内容的WaveStreams(例如,比特深度的采样率)只是请求NAudio抛出异常的一种方式。它们很少像这样使用。如果您想要转换缓冲区的某些内容,您必须调用一些波格式转换流的静态方法(至少它们的名称是自解释的)。