Запись звука с помощью NAudio меня отрубает
Я записываю звук, чтобы отправить его в 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;
}
}
}
1 ответ
Вы получаете 5-секундный аудиоклип не только потому, что делаете разовый BufferLength
читать из BufferedWaveProvider
...
int count = bwp.BufferLength;
var read = bwp.Read(buffer, offset, count);
... и 5 секунд - значение этого свойства по умолчанию, но посколькуBufferedWaveProvider
использует кольцевой буфер, поэтому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();
}
Похоже, что это тот же подход, который использовался при записи файла WAV в приложении WinForms с помощью WaveIn.