Я пытаюсь добиться транскрипции телефонного разговора в реальном времени, используя службы Nexmo и IBM Watson.Я настроил websocket для получения InputStream
двоичного аудио от Nexmo.Я также настроил подключение через веб-сокет к службе преобразования речи в текст IBM Watson.Аудиопоток, который я получаю от Nexmo, имеет кодирование PCM
на частоте 8 кГц или 16 кГц.Размер кадра каждого сообщения, полученного от Nexmo, составляет 20 мс.
Интерфейс Websocket IBM Watson Java SDK ожидает InputStream
с правильной информацией о кодировке для успешной транскрипции.Ниже приведены условия обработки данных, которые я пробовал:
- Делегировать необработанные
InputStream
, полученные от Nexmo, Уотсону с типом контента как "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, что веб-сокет был подключен и находится в 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 Speech-to-Text API ссылка