WaveStream waveStream = new Mp3FileReader(mp3FileToPlay);
var waveOut = new WaveOut();
waveOut.Init(waveStream);
waveOut.Play();
这会抛出一个异常:
当调用 waveOutOpen 时,WaveBadFormat
Nadudio 中的编码类型是 "MpegLayer3"。
我该如何使用 NAudio 播放 mp3 文件?
对于NAudio 1.6及以上版本的用户,请不要使用原始已接受答案中的代码。您不需要添加 WaveFormatConversionStream
或 BlockAlignReductionStream
,并且应避免在使用函数回调时使用 WaveOut
(如果您不在WinForms或WPF应用程序中,则最好使用 WaveOutEvent
)。此外,除非您想要阻塞播放,否则通常不会等到音频完成才休眠。只需订阅WaveOut
的 PlaybackStopped
事件即可。
以下代码将很好地播放 NAudio 中的 MP3:
var reader = new Mp3FileReader("test.mp3");
var waveOut = new WaveOut(); // or WaveOutEvent()
waveOut.Init(reader);
waveOut.Play();
试试这样:
class Program
{
static void Main()
{
using (var ms = File.OpenRead("test.mp3"))
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();
while (waveOut.PlaybackState == PlaybackState.Playing)
{
Thread.Sleep(100);
}
}
}
}
编辑此代码已经过时(涉及到NAudio 1.3)。不建议在更新的版本中使用。请参考替代答案。
我在使用NAudio播放MP3文件时,更喜欢采用以下方式。我倾向于阻塞播放线程,直到通过事件监听器停止播放。此外,为了获得最佳兼容性,我使用MP3Sharp加载MP3文件,然后将其传递给NAudio,因为NAudio没有附带MP3编解码器。
using System;
using NAudio.Wave;
using System.Threading;
using MP3Sharp;
using System.IO;
namespace jessielesbian.NAudioTest
{
public static class Program
{
static void Main(string[] args)
{
Console.WriteLine("loading and parsing MP3 file...");
MP3Stream stream = new MP3Stream("c:\\workspaces\\Stunning! Boeing's 737 MAX on Flying Display.mp3");
WaveFormat waveFormat = new WaveFormat(stream.Frequency, stream.ChannelCount);
Console.WriteLine("allocating playback cache...");
FastWaveBuffer fastWaveBuffer = new FastWaveBuffer(waveFormat, (int) stream.Length);
Console.WriteLine("populating playback cache...");
stream.CopyTo(fastWaveBuffer);
fastWaveBuffer.Seek(0, SeekOrigin.Begin);
Console.WriteLine("unloading MP3 file...");
stream.Dispose();
Console.WriteLine("prepairing player...");
WaveOutEvent waveOutEvent = new WaveOutEvent();
waveOutEvent.Init(fastWaveBuffer);
waveOutEvent.Volume = 1;
Console.WriteLine("arming ManualResetEvent...");
ManualResetEvent manualResetEvent = new ManualResetEvent(false);
waveOutEvent.PlaybackStopped += (object sender, StoppedEventArgs e) => {
manualResetEvent.Set();
};
Console.WriteLine("done!");
waveOutEvent.Play();
manualResetEvent.WaitOne();
}
}
public sealed class FastWaveBuffer : MemoryStream, IWaveProvider
{
public FastWaveBuffer(WaveFormat waveFormat, byte[] bytes) : base(bytes)
{
WaveFormat = waveFormat;
}
public FastWaveBuffer(WaveFormat waveFormat, int size = 4096) : base()
{
WaveFormat = waveFormat;
Capacity = size;
}
public WaveFormat WaveFormat
{
get;
}
}
}