Hololens 2中如何将WindowsMicrophoneStream接入Azure Speech SDK
解决方案:将Hololens 2 Room Capture麦克风流接入Azure Speech SDK
方案一:自定义PullAudioInputStreamCallback实现(优先推荐)
Speech SDK的Pull模式是SDK主动从回调拉取音频数据,刚好适配你已经初始化好的Room Capture流,步骤如下:
先确认你的Windows麦克风流(Room Capture类别)格式和Speech SDK要求一致:
- 采样率:16000Hz(SDK默认强制要求)
- 位深:16位
- 声道:单声道
- 编码:PCM原始格式
实现
PullAudioInputStreamCallback核心类,重点完成Read()方法的音频数据读取逻辑:using Microsoft.CognitiveServices.Speech.Audio; using Windows.Media.Capture; using Windows.Media.MediaProperties; using Windows.Storage.Streams; public class RoomCaptureAudioCallback : PullAudioInputStreamCallback { private readonly MediaCapture _mediaCapture; private readonly AudioFrameInputNode _audioInputNode; private readonly byte[] _buffer; private bool _isStreaming = true; // 传入你已经初始化好的MediaCapture和对应的AudioFrameInputNode public RoomCaptureAudioCallback(MediaCapture mediaCapture, AudioFrameInputNode audioInputNode) { _mediaCapture = mediaCapture; _audioInputNode = audioInputNode; // 按10ms音频数据量初始化缓冲区(16000Hz*1声道*2字节/采样 = 320字节) _buffer = new byte[320]; } public override int Read(byte[] dataBuffer, uint size) { if (!_isStreaming || _audioInputNode == null) { return 0; // 返回0告知SDK流已结束 } uint bytesRead = 0; try { // 从Room Capture流中获取音频帧并读取PCM数据 using (var frame = _audioInputNode.GetFrame()) using (var audioBuffer = frame.LockBuffer(AudioBufferAccessMode.Read)) using (var bufferRef = audioBuffer.CreateReference()) { var inputStream = bufferRef as IInputStream; var readResult = inputStream.ReadAsync(_buffer.AsBuffer(), size, InputStreamOptions.None).AsTask().Wait(); bytesRead = (uint)_buffer.Length; // 将读取到的数据复制到SDK要求的输出缓冲区 System.Buffer.BlockCopy(_buffer, 0, dataBuffer, 0, (int)bytesRead); } } catch { // 捕获流中断等异常,标记流停止 _isStreaming = false; bytesRead = 0; } return (int)bytesRead; } public override void Close() { _isStreaming = false; _audioInputNode?.Dispose(); base.Close(); } }关联回调与Speech SDK初始化:
// 实例化自定义回调(传入你已初始化的MediaCapture和AudioFrameInputNode) var audioCallback = new RoomCaptureAudioCallback(yourMediaCapture, yourAudioInputNode); // 创建Pull模式音频输入流 var audioInputStream = AudioInputStream.CreatePullStream(audioCallback); // 生成SDK可用的音频配置 var audioConfig = AudioConfig.FromStreamInput(audioInputStream); // 初始化语音识别器 var speechRecognizer = new SpeechRecognizer(yourSpeechConfig, audioConfig);
方案二:Push模式主动推送音频数据
如果更倾向于主动将麦克风数据推送给SDK,可以实现后台读取线程,把Room Capture流数据推送到PushAudioInputStream:
实现Push流处理类:
using Microsoft.CognitiveServices.Speech.Audio; using Windows.Media.Capture; using Windows.Media.MediaProperties; using Windows.Storage.Streams; public class RoomCapturePushStreamHandler { private readonly PushAudioInputStream _pushStream; private readonly MediaCapture _mediaCapture; private readonly AudioFrameInputNode _audioInputNode; private bool _isRunning = true; public RoomCapturePushStreamHandler(MediaCapture mediaCapture, AudioFrameInputNode audioInputNode) { _mediaCapture = mediaCapture; _audioInputNode = audioInputNode; _pushStream = AudioInputStream.CreatePushStream(); // 启动后台线程读取并推送数据 _ = ReadAndPushAudioData(); } private async Task ReadAndPushAudioData() { var buffer = new byte[320]; // 同10ms音频数据量 while (_isRunning) { try { using (var frame = _audioInputNode.GetFrame()) using (var audioBuffer = frame.LockBuffer(AudioBufferAccessMode.Read)) using (var bufferRef = audioBuffer.CreateReference()) { var inputStream = bufferRef as IInputStream; var readResult = await inputStream.ReadAsync(buffer.AsBuffer(), (uint)buffer.Length, InputStreamOptions.None); if (readResult.Length > 0) { // 将PCM数据推送给SDK _pushStream.Write(buffer, 0, (int)readResult.Length); } } // 匹配音频采样频率控制读取间隔 await Task.Delay(10); } catch { _isRunning = false; break; } } } // 返回SDK可用的音频配置 public AudioConfig GetAudioConfig() { return AudioConfig.FromStreamInput(_pushStream); } // 停止推送并释放资源 public void Stop() { _isRunning = false; _pushStream.Close(); } }初始化Speech识别器:
var pushHandler = new RoomCapturePushStreamHandler(yourMediaCapture, yourAudioInputNode); var audioConfig = pushHandler.GetAudioConfig(); var speechRecognizer = new SpeechRecognizer(yourSpeechConfig, audioConfig);
关键注意事项
- 必须保证Room Capture流的音频格式严格匹配SDK要求,否则会出现识别失败、杂音等问题。
- Hololens 2端需要在Unity Player Settings中开启
Microphone权限,同时在Package.appxmanifest中添加microphone和spatialPerception权限(Room Capture依赖空间感知)。 - 场景退出或识别停止时,务必释放MediaCapture、AudioNode、Speech识别器等实例,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Leado
相关产品推荐
相关产品推荐

