Воспроизведение MP3 с помощью SoundPlayer после преобразования в WAV с помощью NAudio
Я хочу воспроизвести MP3-файл, загруженный из интернета, используя систему NET provided .Средства массовой информации.Механизм SoundPlayer . Поскольку он работает с форматами 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) не работает-исключение не выбрасывается, но ничего не воспроизводится:
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 ? */
}
}
}
}
}
}
}
Как это можно сделать и что не так со вторым образцом кода ?
2 ответа:
Почему бы не пропустить использование SoundPlayer и не воспроизвести MP3 непосредственно через NAudio? Наудио был создан для этого. Просто загрузите MP3 в какой-нибудь временный файл, воспроизведите его с NAudio и удалите временный файл, как только закончите с ним. Хотя я не думаю, что можно что-то сделать, чтобы уменьшить задержку при загрузке файла.
Основываясь на ответе ли Харрисона, я создал альтернативный код, который лучше.
(3) воспроизведение непосредственно 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).