我正在编写一个应该接收音频并将其发送到Bing Recognition API以获取文本的应用程序。 我使用了服务库,它可以使用wav文件。所以我编写了自己的流类来接收来自麦克风或网络(RTP)的音频,并将其发送到识别API。当我在音频流前添加一个WAV标题时,它可以工作几秒钟。
调试显示,识别api读取表单流的速度比音频源填充的速度快(16k采样率,16位,单声道)。
所以我的问题是:有没有办法将识别api用于实时(连续)音频流?
我知道有一个麦克风客户端的示例,但它仅适用于麦克风,我需要它用于不同的来源。
答案 0 :(得分:2)
我找到了解决问题的方法。我编写了一个继承自流的类AudioStream
,它缓冲输入并在调用Read方法并且其缓冲区为空时等待。这可以防止识别器停止,因为read方法总是返回值> 0。
以下是此类的重要部分代码:
public class AudioStream : Stream {
private AutoResetEvent _waitEvent = new AutoResetEvent(false);
internal void AddData(byte[] buffer, int count) {
_buffer.Add(buffer, count);
// Enable Read
_waitEvent.Set();
}
public override int Read(byte[] buffer, int offset, int count) {
int readCount = 0;
if ((_buffer.Empty) {
// Wait for input
_waitEvent.WaitOne();
}
......
// Fill buffer from _buffer;
_waitEvent.Reset();
return length;
}
protected override void Dispose(bool disposing) {
// Make sure, that there is no waiting Read
// Clear buffer, dispose wait event etc.
}
......
}
由于音频数据是连续接收的,因此Read方法不会“挂起”超过几毫秒(例如,所有20 ms都会收到RTP包)。
答案 1 :(得分:1)
如果您想使用麦克风以外的其他来源,可以通过调用DataRecognitionClient
的SendAudio
方法使用SpeechRecognitionServiceFactory
课程。拥有客户端对象后,您可以从任何来源获取音频 - 麦克风,网络,从文件中读取等 - 并将其发送给客户端SendAudio
方法进行处理。当您收到每个音频缓冲区时,您会对SendAudio
进行新的调用。
在您使用OnPartialResponse
发送音频的过程中,您将以客户端EndAudio
事件的形式实时(或关闭)获得部分识别结果
当您完成发送音频后,您会通过致电OnResponseReceived
向客户发出信号,告知您已为最终识别结果做好准备。然后,您应该从客户端收到包含最终识别假设的{{1}}事件。
答案 2 :(得分:0)
添加有关此主题的其他支持信息:流实现必须支持并发读/写操作,并在没有数据时阻止。