You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用C#实现客户端录制内录+麦克风音频并流式传输至服务器

C#实现系统音频+麦克风录制合并并流式传输到服务器

核心依赖

首先需要用到NAudio库(NuGet安装NAudio),它简化了Windows音频捕获、处理和流式操作,是实现无杂音音频处理的关键。


1. 客户端:双音频源捕获

要同时捕获系统内部声音(比如Spotify)和麦克风输入,必须确保两个捕获设备的音频格式完全一致(采样率、位深度、通道数),这是避免杂音的基础。

捕获系统内部声音

使用WasapiLoopbackCapture捕获系统输出音频:

var loopbackCapture = new WasapiLoopbackCapture();
// 统一设置为44.1kHz 16位立体声(可根据需求调整)
loopbackCapture.WaveFormat = new WaveFormat(44100, 16, 2);

捕获麦克风输入

使用WasapiCapture(或WaveInEvent)捕获麦克风,强制匹配系统音频格式:

var micCapture = new WasapiCapture();
micCapture.WaveFormat = loopbackCapture.WaveFormat;

2. 无杂音音频合并

直接叠加原始音频字节会导致音量过载(破音),必须使用NAudio的MixingSampleProvider进行线性混合,它会自动处理音量平衡,避免异常音频问题:

// 将两个捕获设备转换为SampleProvider
var loopbackProvider = loopbackCapture.ToSampleProvider();
var micProvider = micCapture.ToSampleProvider();

// 创建混合器并添加两个音频源
var mixer = new MixingSampleProvider(new[] { loopbackProvider, micProvider });
mixer.WaveFormat = loopbackCapture.WaveFormat; // 确保混合格式与输入一致

3. 客户端流式传输到服务器

使用TcpClient建立TCP连接,先发送音频格式信息(服务器需用此解析音频),再流式发送混合后的音频数据:

// 连接服务器
var client = new TcpClient("服务器IP", 8888);
var stream = client.GetStream();

// 先发送WaveFormat的长度和字节数据
byte[] formatBytes = loopbackCapture.WaveFormat.ToByteArray();
stream.Write(BitConverter.GetBytes(formatBytes.Length), 0, 4);
stream.Write(formatBytes, 0, formatBytes.Length);

// 转换混合音频为WaveProvider,开始读取并发送
var waveProvider = mixer.ToWaveProvider();
byte[] buffer = new byte[4096];
int bytesRead;

// 启动音频捕获
loopbackCapture.StartRecording();
micCapture.StartRecording();

while ((bytesRead = waveProvider.Read(buffer, 0, buffer.Length)) > 0)
{
    try
    {
        stream.Write(buffer, 0, bytesRead);
        stream.Flush();
    }
    catch (IOException)
    {
        // 处理连接断开情况
        break;
    }
}

// 停止捕获并清理资源
loopbackCapture.StopRecording();
micCapture.StopRecording();
client.Close();

4. 服务器端接收与处理

服务器使用TcpListener监听连接,先接收音频格式,再持续接收音频数据(可保存为文件或实时处理):

var listener = new TcpListener(IPAddress.Any, 8888);
listener.Start();

while (true)
{
    var client = listener.AcceptTcpClient();
    var stream = client.GetStream();

    // 读取WaveFormat信息
    byte[] lengthBuffer = new byte[4];
    stream.Read(lengthBuffer, 0, 4);
    int formatLength = BitConverter.ToInt32(lengthBuffer, 0);
    byte[] formatBytes = new byte[formatLength];
    stream.Read(formatBytes, 0, formatLength);
    var waveFormat = WaveFormat.FromByteArray(formatBytes);

    // 示例:将接收的音频保存为WAV文件
    using (var writer = new WaveFileWriter("received_audio.wav", waveFormat))
    {
        byte[] buffer = new byte[4096];
        int bytesRead;
        while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
        {
            writer.Write(buffer, 0, bytesRead);
        }
    }

    client.Close();
}

关键注意事项(避免杂音/异常)

  • 强制统一音频格式:所有捕获设备和混合器必须使用相同的采样率、位深度和通道数,否则会出现音频错位、杂音。
  • 使用SampleProvider混合:绝对不要手动叠加字节数组,MixingSampleProvider会自动处理音频样本的线性混合,防止音量过载。
  • 缓冲区大小适配:选择4096或8192字节的缓冲区,过小会导致卡顿,过大则增加延迟。
  • 异常处理:捕获IO异常、设备断开等情况,避免程序崩溃。

内容的提问来源于stack exchange,提问作者Errant Wanderer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 04:57:10