我需要使用 Google 语音到文本 api 从 twilio 电话中进行一些实时转录,并且我遵循了一些演示应用程序来展示如何设置它。我的应用程序位于 .net core 3.1 中,并且我正在使用带有 Twilio 定义的回调方法的 webhook。通过回调从 Twilio 检索媒体后,它作为原始音频以 base64 编码传递,如您在此处看到的。
https://www.twilio.com/docs/voice/twiml/stream
我在 Live Transcribe 上引用了这个演示并试图模仿 c# 中的 case 语句。一切都正确连接,媒体和有效负载从 Twilio 很好地传递到我的应用程序中。
然后将音频字符串转换为 byte[] 以传递给需要转录音频的任务
byte[] audioBytes = Convert.FromBase64String(info);
我正在关注基于 Google 文档的示例,这些文档要么从文件流式传输,要么从音频输入(例如麦克风)流式传输。我的用例不同的是,我已经拥有每个音频块的字节。我引用的例子可以在这里看到。从流输入转录音频
下面是我对后者的实现,尽管使用了原始音频字节。当 Twilio websocket 连接命中媒体事件时,会命中下面的此任务。我将有效载荷直接传递给它。从我的控制台日志中,我得到了 Print Responses hit... 控制台日志,但它不会进入while (await responseStream.MoveNextAsync())
块并将脚本记录到控制台。我没有收到任何错误(这会破坏应用程序。)这有可能吗?我还尝试将字节加载到内存流对象中,并将它们传递给 Google 文档示例。
static async Task<object> StreamingRecognizeAsync(byte[] audioBytes)
{
var speech = SpeechClient.Create();
var streamingCall = speech.StreamingRecognize();
// Write the initial request with the config.
await streamingCall.WriteAsync(
new StreamingRecognizeRequest()
{
StreamingConfig = new StreamingRecognitionConfig()
{
Config = new RecognitionConfig()
{
Encoding =
RecognitionConfig.Types.AudioEncoding.Mulaw,
SampleRateHertz = 8000,
LanguageCode = "en",
},
InterimResults = true,
SingleUtterance = true
}
}); ;
// Print responses as they arrive.
Task printResponses = Task.Run(async () =>
{
Console.WriteLine("Print Responses hit...");
var responseStream = streamingCall.GetResponseStream();
while (await responseStream.MoveNextAsync())
{
StreamingRecognizeResponse response = responseStream.Current;
Console.WriteLine("Response stream moveNextAsync Hit...");
foreach (StreamingRecognitionResult result in response.Results)
{
foreach (SpeechRecognitionAlternative alternative in result.Alternatives)
{
Console.WriteLine("Google transcript " + alternative.Transcript);
}
}
}
});
//using (MemoryStream memStream = new MemoryStream(audioBytes))
//{
// var buffer = new byte[32 * 1024];
// int bytesRead;
// while ((bytesRead = await memStream.ReadAsync(audioBytes, 0, audioBytes.Length)) > 0)
// {
// await streamingCall.WriteAsync(
// new StreamingRecognizeRequest()
// {
// AudioContent = Google.Protobuf.ByteString
// .CopyFrom(buffer, 0, bytesRead),
// });
// }
//}
await streamingCall.WriteAsync(
new StreamingRecognizeRequest()
{
AudioContent = Google.Protobuf.ByteString
.CopyFrom(audioBytes),
});
await streamingCall.WriteCompleteAsync();
await printResponses;
return 0;
}