来自 websocket 的 Google Speech API 流式传输音频



我正在尝试从 Fleck websocket 音频流中获取最终的语音转录/识别结果。该方法OnOpen首次建立 websocket 连接时执行代码,OnBinary方法在从客户端接收二进制数据时执行代码。我已经通过将语音回显到 websocket 中并以相同的速率将相同的二进制数据写回 websocket 来测试 websocket。这个测试有效,所以我知道二进制数据被正确发送(640字节的消息,20ms帧大小(。

因此,我的代码失败了,而不是服务失败了。我的目标是做到以下几点:

  1. 创建 websocket 连接后,将初始音频配置请求发送到 APISingleUtterance == true
  2. 运行侦听流式处理结果的后台任务,等待isFinal == true
  3. 将收到的每条二进制消息发送到 API 进行听录
  4. 当后台任务识别isFinal == true时,停止当前流式处理请求并创建新请求 - 重复步骤 1 到 4

此项目的上下文是在实时电话呼叫中转录所有单个语句。

socket.OnOpen = () =>
{
firstMessage = true;
};
socket.OnBinary = async binary =>
{
var speech = SpeechClient.Create();
var streamingCall = speech.StreamingRecognize();
if (firstMessage == true)
{
await streamingCall.WriteAsync(
new StreamingRecognizeRequest()
{
StreamingConfig = new StreamingRecognitionConfig()
{
Config = new RecognitionConfig()
{
Encoding = RecognitionConfig.Types.AudioEncoding.Linear16,
SampleRateHertz = 16000,
LanguageCode = "en",
},
SingleUtterance = true,
}
});
Task getUtterance = Task.Run(async () =>
{
while (await streamingCall.ResponseStream.MoveNext(
default(CancellationToken)))
{
foreach (var result in streamingCall.ResponseStream.Current.Results)
{
if (result.IsFinal == true)
{
Console.WriteLine("This test finally worked");
}
}
}
});
firstMessage = false;
}
else if (firstMessage == false)
{
streamingCall.WriteAsync(new StreamingRecognizeRequest()
{
AudioContent = Google.Protobuf.ByteString.CopyFrom(binary, 0, 640)
}).Wait();
}
};

.Wait()是在异步/等待中调用的阻塞调用。它们不能很好地混合,并可能导致死锁。

只需始终保持代码异步

//...omitted for brevity
else if (firstMessage == false) {
await streamingCall.WriteAsync(new StreamingRecognizeRequest() {
AudioContent = Google.Protobuf.ByteString.CopyFrom(binary, 0, 640)
});
}

最新更新