NAudio 未读取包含 wav 数据的 MemoryStream
NAudio is not reading MemoryStream containing wav data
我正在尝试使用 NAudio 录制 8 秒的流式音频,将其存储在 System.IO.MemoryStream
中,然后立即播放。为此,我 运行 以下代码:
using System.IO;
using NAudio.Wave;
public class AudioCapture{
static WaveFileWriter wri;
static bool stopped = false;
public AudioCapture(){
//record from loopback
IWaveIn waveIn = new WasapiLoopbackCapture();
waveIn.DataAvailable += waveIn_DataAvailable;
waveIn.RecordingStopped += waveIn_RecordingStopped;
//write loopback capture to MemoryStream
Stream sos = new MemoryStream();
wri = new WaveFileWriter(sos, waveIn.WaveFormat);
//record 8 seconds of streaming audio
waveIn.StartRecording();
System.Threading.Thread.Sleep(8000);
waveIn.StopRecording();
//flush and dispose objects
wri.Flush();
waveIn.Dispose();
wri.Dispose();
//play back recorded audio
WaveOut waveOut = new WaveOut();
WaveFileReader waveFileReader = new WaveFileReader(sos);
waveOut.Init(waveFileReader);
waveOut.Play();
}
static void waveIn_RecordingStopped(object sender, StoppedEventArgs e){
stopped = true;
}
static void waveIn_DataAvailable(object sender, WaveInEventArgs e){
if (wri != null) wri.Write(e.Buffer, 0, e.BytesRecorded);
}
}
我收到以下异常,告诉我无法读取流:
Activated Event Time Duration Thread
Exception: Exception thrown: 'System.ArgumentException' in NAudio.dll
("Stream was not readable."). Exception thrown: 'System.ArgumentException' in
NAudio.dll ("Stream was not readable.") 17.86s [17404] <No Name>
我不太确定问题出在哪里,因为根据文档,WaveFileWriter 明确接受 MemoryStream
。我缺少一些转换吗?任何帮助,将不胜感激。谢谢!
澄清一下:错误似乎在这一行:
WaveFileReader waveFileReader = new WaveFileReader(sos);
WaveFileWriter
的设计方式(不幸的是)在您处理 WaveFileWriter
时 总是 处理它写入的流。它本可以接受一些标志来控制这种行为,但它没有。因此,如果您稍后需要使用该流,则需要不要过早处理 WaveFileWriter
,或者克隆该已关闭的内存流。如果你选择不处理writer - 你需要将内存流倒回到位置0,这样读取就可以从头开始(在写入位置结束后):
wri.Flush();
waveIn.Dispose();
// wri.Dispose(); < too early
sos.Seek(0, SeekOrigin.Begin);
如果您想使用克隆 - 不需要倒带:
wri.Flush();
waveIn.Dispose();
wri.Dispose();
sos = new MemoryStream(sos.ToArray());
克隆的缺点是它创建了整个字节数组的不必要副本(ToArray
调用)。
在这种情况下不需要使用 WaveFileReader
或 WaveFileWriter
。只需将收到的音频写入 MemoryStream
即可:
static void waveIn_DataAvailable(object sender, WaveInEventArgs e){
if (sos != null) sos.Write(e.Buffer, 0, e.BytesRecorded);
}
然后,当您完成并准备开始播放时,倒回 MemoryStream
并使用 RawSourceWaveStream
:
//play back recorded audio
var waveOut = new WaveOut();
sos.Position = 0;
var waveFileReader = new RawSourceWaveStream(sos, waveIn.WaveFormat);
waveOut.Init(waveFileReader);
waveOut.Play();
我正在尝试使用 NAudio 录制 8 秒的流式音频,将其存储在 System.IO.MemoryStream
中,然后立即播放。为此,我 运行 以下代码:
using System.IO;
using NAudio.Wave;
public class AudioCapture{
static WaveFileWriter wri;
static bool stopped = false;
public AudioCapture(){
//record from loopback
IWaveIn waveIn = new WasapiLoopbackCapture();
waveIn.DataAvailable += waveIn_DataAvailable;
waveIn.RecordingStopped += waveIn_RecordingStopped;
//write loopback capture to MemoryStream
Stream sos = new MemoryStream();
wri = new WaveFileWriter(sos, waveIn.WaveFormat);
//record 8 seconds of streaming audio
waveIn.StartRecording();
System.Threading.Thread.Sleep(8000);
waveIn.StopRecording();
//flush and dispose objects
wri.Flush();
waveIn.Dispose();
wri.Dispose();
//play back recorded audio
WaveOut waveOut = new WaveOut();
WaveFileReader waveFileReader = new WaveFileReader(sos);
waveOut.Init(waveFileReader);
waveOut.Play();
}
static void waveIn_RecordingStopped(object sender, StoppedEventArgs e){
stopped = true;
}
static void waveIn_DataAvailable(object sender, WaveInEventArgs e){
if (wri != null) wri.Write(e.Buffer, 0, e.BytesRecorded);
}
}
我收到以下异常,告诉我无法读取流:
Activated Event Time Duration Thread
Exception: Exception thrown: 'System.ArgumentException' in NAudio.dll
("Stream was not readable."). Exception thrown: 'System.ArgumentException' in
NAudio.dll ("Stream was not readable.") 17.86s [17404] <No Name>
我不太确定问题出在哪里,因为根据文档,WaveFileWriter 明确接受 MemoryStream
。我缺少一些转换吗?任何帮助,将不胜感激。谢谢!
澄清一下:错误似乎在这一行:
WaveFileReader waveFileReader = new WaveFileReader(sos);
WaveFileWriter
的设计方式(不幸的是)在您处理 WaveFileWriter
时 总是 处理它写入的流。它本可以接受一些标志来控制这种行为,但它没有。因此,如果您稍后需要使用该流,则需要不要过早处理 WaveFileWriter
,或者克隆该已关闭的内存流。如果你选择不处理writer - 你需要将内存流倒回到位置0,这样读取就可以从头开始(在写入位置结束后):
wri.Flush();
waveIn.Dispose();
// wri.Dispose(); < too early
sos.Seek(0, SeekOrigin.Begin);
如果您想使用克隆 - 不需要倒带:
wri.Flush();
waveIn.Dispose();
wri.Dispose();
sos = new MemoryStream(sos.ToArray());
克隆的缺点是它创建了整个字节数组的不必要副本(ToArray
调用)。
在这种情况下不需要使用 WaveFileReader
或 WaveFileWriter
。只需将收到的音频写入 MemoryStream
即可:
static void waveIn_DataAvailable(object sender, WaveInEventArgs e){
if (sos != null) sos.Write(e.Buffer, 0, e.BytesRecorded);
}
然后,当您完成并准备开始播放时,倒回 MemoryStream
并使用 RawSourceWaveStream
:
//play back recorded audio
var waveOut = new WaveOut();
sos.Position = 0;
var waveFileReader = new RawSourceWaveStream(sos, waveIn.WaveFormat);
waveOut.Init(waveFileReader);
waveOut.Play();