首页 > 解决方案 > Amazon Kinesis 流上的 Google Speech-to-text:io.grpc.StatusRuntimeException:CANCELLED:操作已取消

问题描述

我想使用 Kinesis 流使用 Google 语音到文本作为语音机器人服务的一部分,使用 Amazon Connect、Amazon Lex 和 Amazon SQS(我使用了来自https://cloud.google.com/speech-to-text/docs/的代码streaming-recognize#speech-streaming-mic-recognize-java我将引用类型从 AudioInputStream 更改为 InputStream)。

我使用 Amazon Transcribe 语音到文本服务,但我想用 Google 替换它,因为 Google 支持更多语言。但是,Google Speech 不能接​​受 Amazon SDK 创建的 InputStream 对象。

我使用下面的代码。除了将 AudioInputStream 更改为 InputStream,我还尝试了 getAudioInputStream() 方法(也创建了 BufferedInputStream)。

String streamName = streamARN.substring(streamARN.indexOf("/") + 1, streamARN.lastIndexOf("/"));
InputStream kvsInputStream = KVSUtils.getInputStreamFromKVS(streamName, REGION, startFragmentNum, getAWSCredentials());
//InputStream bufferedIn = new BufferedInputStream(kvsInputStream); //to solve 'no reset/mark support in stream' error
//AudioInputStream audioStream = AudioSystem.getAudioInputStream(bufferedIn); //to solve 'no reset/mark support in stream' error
streamingMicRecognize(kvsInputStream);

在当前状态下,我收到错误

com.google.api.gax.rpc.CancelledException: io.grpc.StatusRuntimeException: CANCELLED: The operation was cancelled.

当我使用两条注释行时(我在 SO 上找到了这个解决方案),错误是

java.lang.ClassCastException: com.amazonaws.util.ServiceClientHolderInputStream cannot be cast to javax.sound.sampled.AudioInputStream

你能建议任何解决方案吗?对于英语语音机器人,Connect 提供了一个特殊模块,可让我将电话语音与 Lex 连接,但 Lex 仅支持美国英语,我也需要其他语言。我知道 Google Dialogflow(“Google 的 Lex”)可以处理多种语言并提供与电话网关的集成,但电话网关仅支持英语(这很荒谬)。提前致谢。


更新 我用以下代码解决了这个问题:

    InputStream kvsInputStream = KVSUtils.getInputStreamFromKVS(input.getStreamName(), Regions.US_EAST_1, input.getStartFragmentNum(), new SystemPropertiesCredentialsProvider());
    StreamingMkvReader streamingMkvReader = StreamingMkvReader.createDefault(new InputStreamParserByteSource(kvsInputStream));
    FragmentMetadataVisitor.BasicMkvTagProcessor tagProcessor = new FragmentMetadataVisitor.BasicMkvTagProcessor();
    FragmentMetadataVisitor fragmentVisitor = FragmentMetadataVisitor.create(Optional.of(tagProcessor));
    ByteBuffer audioBuffer = KVSUtils.getByteBufferFromStream(streamingMkvReader, fragmentVisitor, tagProcessor, input.getConnectContactId());
    SpeechClient client = SpeechClient.create();
    clientStream = client.streamingRecognizeCallable().splitCall(responseObserver); //responseObserver is an instance of ResponseObserver<StreamingRecognizeResponse>() with onXXX methods defined by user -- see Google Speech-To-Text examples
    byte[] audioBytes;
    int counter = 0;
    do {
        audioBytes = new byte[audioBuffer.remaining()];
        audioBuffer.get(audioBytes);
        request = StreamingRecognizeRequest.newBuilder()
                            .setAudioContent(ByteString.copyFrom(audioBytes))
                            .build();
        clientStream.send(request);
        audioBuffer = KVSUtils.getByteBufferFromStream(streamingMkvReader, fragmentVisitor, tagProcessor, input.getConnectContactId());
                        counter++;
    } while (audioBytes.length > 0);

解决方案是在流处理中尽可能降低级别,即获取简单的字节数组而不是流对象

标签: amazon-web-servicesamazon-lexgoogle-cloud-speechamazon-connect

解决方案


推荐阅读