我有以下代码来记录音频输入和输出
using System;
using System.Diagnostics;
using System.IO;
using NAudio.Wave;
using Yeti.MMedia.Mp3;
namespace SoundRecording
{
public class SoundManager
{
private WaveInEvent _waveIn;
private WaveFileWriter _waveInFile;
private WasapiLoopbackCapture _waveOut;
private WaveFileWriter _waveOutFile;
private Process _lameProcess;
public void StartRecording()
{
InitLame();
DateTime dtNow = DateTime.Now;
try
{
InitAudioOut(dtNow);
}
catch
{
}
try
{
InitAudioIn(dtNow);
}
catch
{
}
}
private void InitLame()
{
string outputFileName = @"c:\Rec\test.mp3";
_lameProcess = new Process();
_lameProcess.StartInfo.FileName = @"lame.exe";
_lameProcess.StartInfo.UseShellExecute = false;
_lameProcess.StartInfo.RedirectStandardInput = true;
_lameProcess.StartInfo.Arguments = "-r -s 44.1 -h -b 256 --bitwidth 32 - \"" + outputFileName + "\"";
_lameProcess.StartInfo.CreateNoWindow = true;
_lameProcess.Start();
}
private void InitAudioIn(DateTime dtNow)
{
string pathIn = @"C:\Rec\(" + dtNow.ToString("HH-mm-ss") + " " + dtNow.ToString("dd-MM-yyyy") + " IN).wav";
_waveIn = new WaveInEvent();
_waveIn.WaveFormat = new WaveFormat(8000, 1);
_waveIn.DataAvailable += WaveInDataAvailable;
_waveIn.RecordingStopped += WaveInRecordStopped;
_waveInFile = new WaveFileWriter(pathIn, _waveIn.WaveFormat);
_waveIn.StartRecording();
}
private void InitAudioOut(DateTime recordMarker)
{
string pathOut = @"C:\Rec\(" + recordMarker.ToString("HH-mm-ss") + " " + recordMarker.ToString("dd-MM-yyyy") + " OUT).mp3";
_waveOut = new WasapiLoopbackCapture();
//_waveOut.WaveFormat = new WaveFormat(44100, 1);
_waveOut.DataAvailable += WaveOutDataAvailable;
_waveOut.RecordingStopped += WaveOutRecordStopped;
_waveOutFile = new WaveFileWriter(pathOut, new Mp3WaveFormat(_waveOut.WaveFormat.SampleRate, _waveOut.WaveFormat.Channels, 0, 128));
_waveOut.StartRecording();
}
private void WaveInDataAvailable(object sender, WaveInEventArgs e)
{
if (_waveInFile != null)
{
_waveInFile.Write(e.Buffer, 0, e.BytesRecorded);
_waveInFile.Flush();
}
}
private void WaveOutDataAvailable(object sender, WaveInEventArgs e)
{
if (_waveInFile != null)
{
using (var memStream = new MemoryStream(e.Buffer))
{
using (WaveStream wStream = new RawSourceWaveStream(memStream, _waveOut.WaveFormat))
{
var format = new WaveFormat(_waveOut.WaveFormat.SampleRate, _waveOut.WaveFormat.Channels);
var transcodedStream = new ResamplerDmoStream(wStream, format);
var read = (int)transcodedStream.Length;
var bytes = new byte[read];
transcodedStream.Read(bytes, 0, read);
var fmt = new WaveLib.WaveFormat(transcodedStream.WaveFormat.SampleRate, transcodedStream.WaveFormat.BitsPerSample, transcodedStream.WaveFormat.Channels);
var beconf = new Yeti.Lame.BE_CONFIG(fmt, 128);
// Encode WAV to MP3
byte[] mp3Data;
using (var mp3Stream = new MemoryStream())
{
using (var mp3Writer = new Mp3Writer(mp3Stream, fmt, beconf))
{
int blen = transcodedStream.WaveFormat.AverageBytesPerSecond;
mp3Writer.Write(bytes, 0, read);
mp3Data = mp3Stream.ToArray();
}
}
_waveOutFile.Write(mp3Data, 0, mp3Data.Length);
_waveOutFile.Flush();
}
}
}
}
private byte[] WavBytesToMp3Bytes(IWaveProvider waveStream, uint bitrate = 128)
{
// Setup encoder configuration
var fmt = new WaveLib.WaveFormat(waveStream.WaveFormat.SampleRate, waveStream.WaveFormat.BitsPerSample, waveStream.WaveFormat.Channels);
var beconf = new Yeti.Lame.BE_CONFIG(fmt, bitrate);
// Encode WAV to MP3
int blen = waveStream.WaveFormat.AverageBytesPerSecond;
var buffer = new byte[blen];
byte[] mp3Data = null;
using (var mp3Stream = new MemoryStream())
{
using (var mp3Writer = new Mp3Writer(mp3Stream, fmt, beconf))
{
int readCount;
while ((readCount = waveStream.Read(buffer, 0, blen)) > 0)
{
mp3Writer.Write(buffer, 0, readCount);
}
mp3Data = mp3Stream.ToArray();
}
}
return mp3Data;
}
private void WaveInRecordStopped(object sender, StoppedEventArgs e)
{
if (_waveIn != null)
{
_waveIn.Dispose();
_waveIn = null;
}
if (_waveInFile != null)
{
_waveInFile.Dispose();
_waveInFile = null;
}
_lameProcess.StandardInput.BaseStream.Close();
_lameProcess.StandardInput.BaseStream.Dispose();
_lameProcess.Close();
_lameProcess.Dispose();
}
private void WaveOutRecordStopped(object sender, StoppedEventArgs e)
{
if (_waveOutFile != null)
{
_waveOutFile.Close();
_waveOutFile = null;
}
_waveOut = null;
}
public void StopRecording()
{
try
{
_waveIn.StopRecording();
}
catch
{
}
try
{
_waveOut.StopRecording();
}
catch
{
}
}
}
}
我正在使用 NAudio 来捕获音频输入/输出,而 Yetis 的蹩脚包装器将其即时转换为 mp3 文件,问题是生成的音频输出文件已损坏且无法读取,可能是缺少 mp3 标头或其他我错过了...