如何用C#通过NAudio WaveOut直接将音频发送至Bing语音识别服务?
如何直接将录制的麦克风音频发送至Bing语音识别服务(不通过文件)
我已经用NAudio实现了麦克风音频录制,代码如下,但现在想不通过保存文件的方式,直接把录制的音频发送到Bing语音识别服务,请问该怎么做?
private void buttonBeginToSpeak_Click(object sender, EventArgs e) { WaveIn wi; WaveOut wo; private BufferedWaveProvider bwp; wo = new WaveOut(); wi = new WaveIn(); wi.DataAvailable += new EventHandler<WaveInEventArgs>(wi_DataAvailable); bwp = new BufferedWaveProvider(wi.WaveFormat); bwp.DiscardOnBufferOverflow = true; wo.Init(bwp); wi.StartRecording(); } private void buttonFinishSpeaking_Click(object sender, EventArgs e) { wi.StopRecording(); wo.Play(); // 播放录制的音频 } void wi_DataAvailable(object sender, WaveInEventArgs e) { bwp.AddSamples(e.Buffer, 0, e.BytesRecorded); }
解决方案
首先要说明:Bing语音识别服务现在已经整合到Azure Speech Service中,推荐使用官方的Azure Speech SDK来实现流式语音识别,这样可以直接把录制的音频数据推送到服务,无需保存到文件。下面是具体的实现步骤:
1. 准备工作
- 安装Azure Speech SDK的NuGet包:
Microsoft.CognitiveServices.Speech - 获取你的Azure Speech资源密钥和区域(可以在Azure门户中创建Speech资源后获取)
2. 修改代码实现流式识别
我们需要替换原来的BufferedWaveProvider播放逻辑,改为将音频数据直接推送到Speech SDK的输入流中,同时启动语音识别:
// 声明全局变量 private WaveIn _waveIn; private SpeechRecognizer _speechRecognizer; private PushAudioInputStream _audioInputStream; private AudioConfig _audioConfig; private void buttonBeginToSpeak_Click(object sender, EventArgs e) { // 第一步:设置音频格式为语音服务要求的格式(16kHz,16位,单声道PCM) var waveFormat = new WaveFormat(16000, 16, 1); _waveIn = new WaveIn(); _waveIn.WaveFormat = waveFormat; _waveIn.DataAvailable += WaveIn_DataAvailable; // 第二步:初始化Speech SDK的音频输入流和识别器 var speechConfig = SpeechConfig.FromSubscription("你的Azure Speech密钥", "你的资源区域"); _audioInputStream = AudioInputStream.CreatePushStream(); _audioConfig = AudioConfig.FromStreamInput(_audioInputStream, waveFormat.SampleRate, waveFormat.BitsPerSample, waveFormat.Channels); _speechRecognizer = new SpeechRecognizer(speechConfig, _audioConfig); // 注册识别结果事件 _speechRecognizer.Recognized += (s, args) => { if (args.Result.Reason == ResultReason.RecognizedSpeech) { // 识别成功,处理结果 MessageBox.Show($"识别结果:{args.Result.Text}"); } else if (args.Result.Reason == ResultReason.NoMatch) { MessageBox.Show("未识别到语音"); } }; // 开始录制和识别 _speechRecognizer.StartContinuousRecognitionAsync().Wait(); _waveIn.StartRecording(); } private void buttonFinishSpeaking_Click(object sender, EventArgs e) { // 停止录制和识别 _waveIn.StopRecording(); _audioInputStream.Close(); _speechRecognizer.StopContinuousRecognitionAsync().Wait(); // 释放资源 _waveIn.Dispose(); _speechRecognizer.Dispose(); _audioInputStream.Dispose(); } private void WaveIn_DataAvailable(object sender, WaveInEventArgs e) { // 将录制的音频数据直接推送到Speech SDK的输入流 _audioInputStream.Write(e.Buffer, 0, e.BytesRecorded); }
3. 关键说明
- 音频格式匹配:语音服务对输入音频格式有严格要求,必须设置为16kHz采样率、16位深度、单声道PCM,否则识别会失败。所以我们初始化
WaveIn时指定了这个格式。 - 流式推送:通过
PushAudioInputStream,我们可以实时把麦克风采集到的音频数据推送到服务,不需要先缓存到文件或BufferedWaveProvider中。 - 事件处理:通过
Recognized事件可以实时获取识别结果,适合连续语音识别场景。如果需要单次识别(比如一句话说完就识别),可以改用RecognizeOnceAsync()方法,而不是StartContinuousRecognitionAsync()。
内容的提问来源于stack exchange,提问作者Alvaro Fierro Clavero
相关产品推荐
相关产品推荐

