用 NAudio 录制音频让我无法接受
Posted
技术标签:
【中文标题】用 NAudio 录制音频让我无法接受【英文标题】:Recording audio with NAudio cuts me off 【发布时间】:2020-03-29 23:22:45 【问题描述】:我正在录制音频以将其发送到 Google 语音到文本,但是当我使用 naudio 制作音频时,它只记录了我 5 秒,然后停止录制。我复制了C#中的代码,这是我第一次使用这个API,但我不知道为什么它会打断我,如果我按下保存按钮时它应该停止录制,应用程序是一个带有2个按钮的简单表单,一个用于录制,另一个用于停止。
namespace WindowsFormsApp1
public partial class Form1 : Form
private BufferedWaveProvider bwp;
WaveIn waveIn;
WaveOut waveOut;
WaveFileWriter writer;
WaveFileReader reader;
string output = "audio.raw";
public Form1()
InitializeComponent();
waveOut = new WaveOut();
waveIn = new WaveIn();
waveIn.DataAvailable += new EventHandler<WaveInEventArgs>(waveIn_DataAvailable);
waveIn.WaveFormat = new NAudio.Wave.WaveFormat(16000, 1);
bwp = new BufferedWaveProvider(waveIn.WaveFormat);
bwp.DiscardOnBufferOverflow = true;
btnRecordVoice.Enabled = true;
btnSave.Enabled = false;
//btnSpeechInfo.Enabled = false;
private void btnRecordVoice_Click(object sender, EventArgs e)
if (NAudio.Wave.WaveIn.DeviceCount < 1)
Console.WriteLine("No se encuentra un microfono!");
return;
waveIn.StartRecording();
btnRecordVoice.Enabled = false;
btnSave.Enabled = true;
private void btnSave_Click(object sender, EventArgs e)
waveIn.StopRecording();
if (File.Exists("audio.raw"))
File.Delete("audio.raw");
writer = new WaveFileWriter(output, waveIn.WaveFormat);
btnRecordVoice.Enabled = false;
btnSave.Enabled = false;
byte[] buffer = new byte[bwp.BufferLength];
int offset = 0;
int count = bwp.BufferLength;
var read = bwp.Read(buffer, offset, count);
if (count > 0)
writer.Write(buffer, offset, read);
waveIn.Dispose();
waveIn = null;
writer.Close();
writer = null;
reader = new WaveFileReader("audio.raw"); // (new MemoryStream(bytes));
waveOut.Init(reader);
waveOut.PlaybackStopped += new EventHandler<StoppedEventArgs>(waveOut_PlaybackStopped);
waveOut.Play();
void waveIn_DataAvailable(object sender, WaveInEventArgs e)
bwp.AddSamples(e.Buffer, 0, e.BytesRecorded);
private void waveOut_PlaybackStopped(object sender, StoppedEventArgs e)
waveOut.Stop();
reader.Close();
reader = null;
【问题讨论】:
Stack Overflow 仅支持英语。我已经使用谷歌翻译编辑了你的问题,请检查它以确保它没问题btnSave_Click()
中的代码从BufferedWaveProvider
复制到WaveFileWriter
是...奇怪。您将bwp.Read()
的结果存储在read
中,然后检查count
,它是bwp.Read()
的参数(上限)。此外,通常那些Read(byte[], int, int)
方法不能保证读取所有请求的数据,因此您需要一个循环,而不是if
。试试int read; while ((read = bwp.Read(buffer, 0, buffer.Length)) > 0) writer.Write(buffer, 0, read);
。
【参考方案1】:
您获得一个 5 秒的音频剪辑不仅是因为您从 BufferedWaveProvider
中读取了一次性的 BufferLength
...
int count = bwp.BufferLength;
var read = bwp.Read(buffer, offset, count);
...5 秒是default value of that property,但因为BufferedWaveProvider
uses a circular buffer,所以BufferLength
是它可用的所有数据。
对我有用的是跳过BufferedWaveProvider
,并在新数据可用时立即将新数据写入WaveFileWriter
...
void waveIn_DataAvailable(object sender, WaveInEventArgs e)
writer.Write(e.Buffer, 0, e.BytesRecorded);
为了支持该更改,按钮事件处理程序更改为以下...
private void btnRecordVoice_Click(object sender, EventArgs e)
if (NAudio.Wave.WaveIn.DeviceCount < 1)
Console.WriteLine("No se encuentra un microfono!");
return;
writer = new WaveFileWriter(output, waveIn.WaveFormat);
waveIn.StartRecording();
btnRecordVoice.Enabled = false;
btnSave.Enabled = true;
private void btnSave_Click(object sender, EventArgs e)
waveIn.StopRecording();
writer.Close();
writer = null;
btnRecordVoice.Enabled = false;
btnSave.Enabled = false;
reader = new WaveFileReader("audio.raw"); // (new MemoryStream(bytes));
waveOut.Init(reader);
waveOut.PlaybackStopped += new EventHandler<StoppedEventArgs>(waveOut_PlaybackStopped);
waveOut.Play();
这似乎与Recording a WAV file in a WinForms app with WaveIn 中使用的方法相同。
【讨论】:
以上是关于用 NAudio 录制音频让我无法接受的主要内容,如果未能解决你的问题,请参考以下文章