Java-如何将InputStream转换为适当的格式以使用IBM Watson的语音转文本服务?

时间:2018-08-26 06:41:07

标签: java websocket speech-to-text ibm-watson nexmo

我正在尝试同时利用Nexmo和IBM Watson服务来实现电话对话的实时转录。我已经设置了一个网络套接字,以接收来自Nexmo的InputStream二进制音频。我还建立了到IBM Watson语音到文本服务的Websocket连接。我从Nexmo接收的音频流是PCM编码的,频率为8 kHz或16 kHz。从Nexmo获得的每个消息的帧大小为20毫秒长。

IBM Watson Java SDK的Websocket接口期望InputStream具有正确的编码信息才能成功进行转录。以下是我尝试过的数据条件:

  • 使用以下方法将从Nexmo获得的原始InputStream委托给Watson 内容类型为"audio/l16; rate=16000; endianness=little-endian"
  • 使用AudioInputStream方法static获取AudioSystem.getAudioInputStream(InputStream inputStream)对象。据推测,该方法推断输入流的格式并返回AudioStream对象。
  • 使用静态方法AudioStream通过传递以下AudioSystem.getAudioInputStream(AudioFormat targetFormat, AudioInputStream sourceStream)参数来获取AudioFormat对象
    • audioFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 16, 1, AudioSystem.NOT_SPECIFIED, 16, 16000, true);

但是在以上所有尝试中,我都未能从IBM服务获得任何形式的转录。我确实从IBM得到响应,说我第一次连接到服务时Websocket已连接并且位于listening state中。 IBM云中没有可用的日志以查看正在发生的情况。我已经阅读了SO和IBM开发人员论坛,但是找不到任何合适的示例。我非常确信,对从Nexmo获得的数据进行条件处理的方式不适用于Watson服务。我该如何适当地调整我的数据以便与IBM Watson抄录语音?

这是我非常简化(以提高可读性)的代码示例(将各种功能的不同方法加在一起)

// method to return Nexmo's NCCO, when the call is answered
public static String connectToWebSocket()
{
    JsonArray ncco = new JsonArray();

    JsonObject enclosingObject = new JsonObject();
    enclosingObject.addProperty("action", "connect");

    JsonObject webSocketEndpoint = new JsonObject();
    webSocketEndpoint.addProperty("type", "websocket");
    webSocketEndpoint.addProperty("uri", "ws://websocket-uri/call-stream");
    webSocketEndpoint.addProperty("content-type", "audio/l16;rate=16000");

    JsonObject header = new JsonObject();
    header.addProperty("app", "demo");

    webSocketEndpoint.add("header", header);

    JsonArray endpointArray = new JsonArray();
    endpointArray.add(webSocketEndpoint);

    enclosingObject.add("endpoint", endpointArray);

    ncco.add(enclosingObject);
    return ncco.toString();
}

// WebSocketController' onMessage method (receiving Nexmo's binary audio) 
@OnMessage
public void onMessage(InputStream inputStream, Session session)
{
    //transcriptionService.recognizeVoice(inputStream);
}

// IBMTransriptionService's recognizeVoice method
public void recognizeVoice(InputStream stream)
{
    if(stream == null) return;

    try
    {
        audioFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 16, 1, AudioSystem.NOT_SPECIFIED, 16, 16000, true);
        RecognizeOptions recognizeOptions = new RecognizeOptions.Builder().audio(new AudioInputStream(stream, audioFormat, 16))
            .contentType("audio/l16; rate=16000; endianness=little-endian")
            .interimResults(true)
            .build();

        this.speechToText.setEndPoint("https://gateway-syd.watsonplatform.net/speech-to-text/api");
        this.speechToText.recognizeUsingWebSocket(recognizeOptions, this.transcriptionReceiver);
    }
    catch (Exception e)
    {
        logger.error("Failed when creating audio stream" + e.getMessage());
    }
}

其他链接:

  • 这是Nexmo文档,详细介绍了二进制音频的格式 通过websocket

    传输

    Watson语音到文本API reference

1 个答案:

答案 0 :(得分:0)

您使用什么模型向Watson提出请求? Nexmo语音来自电话呼叫,因此即使您使用16Khz,也要将其设置为窄带模型,例如en-US_NarrowbandModel