http或websocket通信返回的音频数据流,导出到音频文件,然后再用AudioFileReader
读取文件流,可以播放比较多格式的音频(例如:webm)。但是如果不创建临时文件,改如何直接播放流MemoryStream
?
var filename = "./tmp.webm";
using (var audioFile = new AudioFileReader(filename))
using (var waveOut = new WaveOutEvent())
{
waveOut.Init(audioFile);
waveOut.Play();
while (waveOut.PlaybackState == PlaybackState.Playing)
Thread.Sleep(100);
}
AudioFileReader
构造函数,其中CreateReaderStream
方法是成功播放wav、mp3、aiff这3类音频的关键,所以需要找到能MediaFoundationReader
相关联的类;// 摘要:
// Creates the reader stream, supporting all filetypes in the core NAudio library,
// and ensuring we are in PCM format
//
// 参数:
// fileName:
// File Name
private void CreateReaderStream(string fileName)
{
if (fileName.EndsWith(".wav", StringComparison.OrdinalIgnoreCase))
{
readerStream = new WaveFileReader(fileName);
if (readerStream.WaveFormat.Encoding != WaveFormatEncoding.Pcm && readerStream.WaveFormat.Encoding != WaveFormatEncoding.IeeeFloat)
{
readerStream = WaveFormatConversionStream.CreatePcmStream(readerStream);
readerStream = new BlockAlignReductionStream(readerStream);
}
}
else if (fileName.EndsWith(".mp3", StringComparison.OrdinalIgnoreCase))
{
if (Environment.OSVersion.Version.Major < 6)
{
readerStream = new Mp3FileReader(fileName);
}
else
{
readerStream = new MediaFoundationReader(fileName);
}
}
else if (fileName.EndsWith(".aiff", StringComparison.OrdinalIgnoreCase) || fileName.EndsWith(".aif", StringComparison.OrdinalIgnoreCase))
{
readerStream = new AiffFileReader(fileName);
}
else
{
// 一切其他格式音频IO流读取方式
readerStream = new MediaFoundationReader(fileName);
}
}
MediaFoundationReader
的子类StreamMediaFoundationReader
public class StreamMediaFoundationReader : MediaFoundationReader
{
private readonly Stream stream;
public StreamMediaFoundationReader(Stream stream, MediaFoundationReaderSettings settings = null)
{
this.stream = stream;
Init(settings);
}
// 省略
}
byte[] buffer;
using (var ms = new MemoryStream(buffer))
using (var media = new StreamMediaFoundationReader(ms))
using (var waveOut = new WaveOutEvent())
{
waveOut.Init(media);
waveOut.Play();
while (waveOut.PlaybackState == PlaybackState.Playing)
Thread.Sleep(100);
}