使用NAudio转换为WAV后使用SoundPlayer播放MP3

我想使用NET提供的System.Media.SoundPlayer机制播放从网上下载的MP3文件。 由于它适用于WAV格式,它需要支持例如NAudio库 – 我需要将MP3转换为WAV。

我想在内存中执行所有操作,因为我需要快速调用它,但我有问题。 下面我展示的代码按预期工作,但它与文件合作。 相反,我需要让它仅使用内存操作。

(1)工作,但涉及磁盘操作:

public void Speak(Uri mp3FileUri) { using (var client = new WebClient()) { using (var networkStream = client.OpenRead(mp3FileUri)) { if (networkStream != null) { var temp = Path.GetTempPath(); var mp3File = Path.Combine(temp, "file.mp3"); var wavFile = Path.Combine(temp, "file.wav"); using (var fileStream = File.Create(mp3File)) { networkStream.CopyTo(fileStream); } using (var reader = new Mp3FileReader(mp3File)) { WaveFileWriter.CreateWaveFile(wavFile, reader); } using(var player = new SoundPlayer(wavFile)) { player.Play(); } } } } } 

(2)不起作用 – 没有抛出exception,但没有播放:

 public void Speak(Uri mp3FileUri) { using (var client = new WebClient()) { using (var networkStream = client.OpenRead(mp3FileUri)) { if (networkStream != null) { var memStream = new MemoryStream(); networkStream.CopyTo(memStream); memStream.Position = 0; using (var reader = new Mp3FileReader(memStream)) { var outStream = new MemoryStream(); using (var writer = new WaveFileWriter(outStream, reader.WaveFormat)) { var num = 0L; var buffer = new byte[reader.WaveFormat.AverageBytesPerSecond * 4]; while (true) { var count = reader.Read(buffer, 0, buffer.Length); if (count != 0) { num += count; if (num <= int.MaxValue) writer.Write(buffer, 0, count); else throw new InvalidOperationException("Too large file or endless stream."); } else break; } writer.Flush(); outStream.Position = 0; using(var player = new SoundPlayer(outStream)) { player.Play(); /* why silence ? */ } } } } } } } 

如何完成以及第二个代码示例有什么问题?

为什么不跳过使用SoundPlayer并直接通过NAudio播放MP3? NAudio旨在实现这一目标。 只需将MP3下载到某个临时文件中,然后使用NAudio播放它,并在完成后删除临时文件。 我认为在下载文件时可以做任何事情来减少延迟。

http://naudio.codeplex.com/wikipage?title=MP3

根据Lee Harrison的回答,我创建了更好的替代代码。

(3)直接从WEB播放MP3文件而不转换为WAV而不使用磁盘操作:

 public void Speak(Uri mp3FileUri) { using (var client = new WebClient()) { using (var networkStream = client.OpenRead(mp3FileUri)) { if (networkStream != null) { using (var memStream = new MemoryStream()) { networkStream.CopyTo(memStream); memStream.Position = 0; using (var waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback())) { var waveEvent = new ManualResetEvent(false); waveOut.PlaybackStopped += (sender, e) => waveEvent.Set(); waveEvent.Reset(); using (var rdr = new Mp3FileReader(memStream)) using (var waveStream = WaveFormatConversionStream.CreatePcmStream(rdr)) using (var baStream = new BlockAlignReductionStream(waveStream)) { waveOut.Init(baStream); waveOut.Play(); if (waveOut.PlaybackState != PlaybackState.Stopped) { waveEvent.WaitOne(); /* block thread for a while because I don't want async play back (to be analogical as usage of SoundPlayer Play method) */ } } } } } } } } 

尽管如此(尽管这对我来说非常好),我仍然不知道样本(2)的问题是什么。