Полный адрес проекта:После git ee.com/T-Zone/wit…
Введение
В прошлой статье мы кратко рассказали о решении использования Springboot с Alibaba Cloud Xiaomi для реализации текстового робота. Предыдущий адрес:Наггетс.Талант/пост/687488….
В этой главе будут представлены решения и решения по интеграции для интеллектуальных голосовых роботов.
2. Решения
проблема:
Если вы хотите внедрить интегрированного интеллектуального голосового робота, есть три основных болевых момента.
- Как преобразовать поток байтов с микрофона в текст
- Как после получения пользовательского текста проанализировать намерение пользователя и дать соответствующий ответ
- Получив ответ, как преобразовать соответствующий ответ в речь
решать:
- Текущая основная функция транскрипции речи (ASR) может использоваться для получения потока байтов микрофона.
- После получения текста используйте понимание естественного языка (NLU) для анализа намерений пользователя.
- Получив ответ, используйте функцию преобразования текста в речь (TTS).
Поэтому, если вы всегда знаете, как решить эту проблему, вы можете выбрать, какие возможности производителя использовать.Я в основном выбираю возможности искусственного интеллекта Alibaba Cloud для реализации нашего интеллектуального голосового робота.
3. Технический выбор и временная диаграмма
За кулисами
- springboot
- WebSocket
- Али Аср (в реальном времени)
- Али ТТС
- Облако Алибаба Сяоми
стойка регистрации
- HZRecorder2.js (функция записи h5, декодирование js)
- Socket.io (js со встроенным веб-сокетом)
Временная диаграмма:
В-четвертых, интегрировать али аср и тц
аср адрес:help.aliyun.com/document_…
ттс адрес:help.aliyun.com/document_…
-
Внедрить необходимый SDK в проект maven
<dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-core</artifactId> <version>4.5.2</version> </dependency> <dependency> <groupId>com.alibaba.nls</groupId> <artifactId>nls-sdk-tts</artifactId> <version>2.1.6</version> </dependency> <dependency> <groupId>com.alibaba.nls</groupId> <artifactId>nls-sdk-transcriber</artifactId> <version>2.1.6</version> </dependency>
-
Интегрировать код asr в проект
public void process() { SpeechSynthesizer synthesizer = null; try { //创建实例,建立连接。 synthesizer = new SpeechSynthesizer(client, getSynthesizerListener()); synthesizer.setAppKey(appKey); //设置返回音频的编码格式 synthesizer.setFormat(OutputFormatEnum.WAV); //设置返回音频的采样率 synthesizer.setSampleRate(SampleRateEnum.SAMPLE_RATE_16K); //发音人 synthesizer.setVoice("siyue"); //语调,范围是-500~500,可选,默认是0。 synthesizer.setPitchRate(100); //语速,范围是-500~500,默认是0。 synthesizer.setSpeechRate(100); //设置用于语音合成的文本 synthesizer.setText("欢迎使用阿里巴巴智能语音合成服务,您可以说北京明天天气怎么样啊"); // 是否开启字幕功能(返回相应文本的时间戳),默认不开启,需要注意并非所有发音人都支持该参数。 synthesizer.addCustomedParam("enable_subtitle", false); //此方法将以上参数设置序列化为JSON格式发送给服务端,并等待服务端确认。 long start = System.currentTimeMillis(); synthesizer.start(); logger.info("tts start latency " + (System.currentTimeMillis() - start) + " ms"); SpeechSynthesizerDemo.startTime = System.currentTimeMillis(); //等待语音合成结束 synthesizer.waitForComplete(); logger.info("tts stop latency " + (System.currentTimeMillis() - start) + " ms"); } catch (Exception e) { e.printStackTrace(); } finally { //关闭连接 if (null != synthesizer) { synthesizer.close(); } } }
-
Интегрировать метод TTS в проект
public void process() { SpeechSynthesizer synthesizer = null; try { //创建实例,建立连接。 synthesizer = new SpeechSynthesizer(client, getSynthesizerListener()); synthesizer.setAppKey(appKey); //设置返回音频的编码格式 synthesizer.setFormat(OutputFormatEnum.valueOf(ttsParam.getFormat())); //设置返回音频的采样率 synthesizer.setSampleRate(ttsParam.getSampleRate() == 8000 ? SampleRateEnum.SAMPLE_RATE_8K : SampleRateEnum.SAMPLE_RATE_16K); //发音人 // synthesizer.setVoice("Aixia"); synthesizer.setVoice(ttsParam.getVoice()); //语调,范围是-500~500,可选,默认是0。 synthesizer.setPitchRate(0); //语速,范围是-500~500,默认是0。 synthesizer.setSpeechRate(ttsParam.getSpeechRate()); //设置用于语音合成的文本 synthesizer.setText(ttsParam.getText()); // 是否开启字幕功能(返回相应文本的时间戳),默认不开启,需要注意并非所有发音人都支持该参数。 synthesizer.addCustomedParam("enable_subtitle", false); //此方法将以上参数设置序列化为JSON格式发送给服务端,并等待服务端确认。 long start = System.currentTimeMillis(); synthesizer.start(); log.info("tts start latency " + (System.currentTimeMillis() - start) + " ms"); SpeechSynthesizerUtil.startTime = System.currentTimeMillis(); //等待语音合成结束 synthesizer.waitForComplete(); log.info("tts stop latency " + (System.currentTimeMillis() - start) + " ms"); } catch (Exception e) { e.printStackTrace(); } finally { //关闭连接 if (null != synthesizer) { synthesizer.close(); } } }
5. Встроенный веб-сокет
Поскольку интеллектуальный голосовой робот должен часто передавать байты, он использует длинный веб-сокет соединения для взаимодействия с потоком байтов.
Введение в веб-сокеты:
Проще говоря: традиционная http-связь отключается после однократного обмена данными, и сервер не может активно передавать информацию клиенту. И длинный веб-сокет соединения решает эту проблему
-
Внедрить необходимый SDK в проект maven
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>
-
Интегрированный метод доступа к голосовому потоку
/** * 1.获取到前台传输来的语音流,并且储存到asr需要识别的文件中 * 2.WebScoketUtils.intentSwitchMap判断机器人是否可以说话 * 3.判断公共变量中使用存有TTS语音文件,如果存在的话,就转换为byte数组传输给前台 * @param message * @param session * @param uid * @param roleType * @throws IOException */ @OnMessage(maxMessageSize = 1024000) public void onMessage(byte[] message, Session session, @PathParam("uid") String uid, @PathParam("roleType") int roleType) throws IOException { String keyId = WebScoketUtils.getScoketKey(uid, roleType); writeFile(message, uid, roleType); try { if (null != WebScoketUtils.userMap.get(keyId) && !WebScoketUtils.userMap.get(keyId).equals("")) { if ("on".equals(WebScoketUtils.intentSwitchMap.get(keyId))) { log.info("机器人说话"); String filePath = WebScoketUtils.userMap.get(keyId); WebScoketUtils.userMap.remove(keyId); onMessageByte(keyId, filePath); WebScoketUtils.intentSwitchMap.put(keyId, "off"); } } } catch (Exception e) { e.printStackTrace(); } }
-
Интеграция прослушивает, покидает ли пользователь событие
@OnClose public void onClose(Session session, @PathParam("uid") String uid, @PathParam("roleType") int roleType) { remove(session, uid, roleType); }
6. Внешняя интеграция HZRecorder2.js (плагин для записи)
-
Используйте recorder.js для захвата голоса с микрофона и его записи.
-
часть кода
//开始录音 this.start = function () { audioInput.connect(recorder); recorder.connect(context.destination); }
7. Интерфейсный интегрированный веб-сокет для передачи голосовых байтов в режиме реального времени.
-
Используйте recorder.js для сбора записей с микрофона и передачи их в фоновом режиме через протокол веб-сокета для анализа.
-
часть кода
var wssurl = WS_SOCKET; var url = wssurl + 'audioMessage/' + obj.channelId + "/" + obj.roleType; console.log("url=" + url); socket = new WebSocket(url); socket.onopen = onChannelOpened; socket.onmessage = onChannelMessage; socket.onclose = onChannelClosed; socket.onerror = onChannelError;
Во-вторых, используйте audioContext, поставляемый с h5, для воспроизведения голоса.
-
Воспроизведение музыки напрямую через тег audio не разрешено в основных браузерах, поэтому, учитывая некоторые проблемы совместимости, для воспроизведения используется audioContext, который может быть хорошо совместим с основными основными браузерами.
-
часть кода
reader.onload = function(evt) { if (evt.target.readyState == FileReader.DONE) { var data = new Uint8Array(evt.target.result); audioContext.decodeAudioData(evt.target.result, function(buffer) { //解码成pcm流 var audioBufferSouceNode = audioContext.createBufferSource(); audioBufferSouceNode.buffer = buffer; audioBufferSouceNode.connect(audioContext.destination); audioBufferSouceNode.start(0); }, function(e) { // alert("Fail to decode the file."); }); } } reader.readAsArrayBuffer(data);
9. Демонстрационный эффект
10. Заключение
Что ж, после того, как вышеперечисленные операции в основном завершены, распознавание речи в основном реализовано.Вы можете сначала открыть html-запись и записать ее, а затем запустить java-программу, чтобы испытать процесс голосового взаимодействия в реальном времени.
Хорошо, это все, я надеюсь, что это может помочь вам, кому нужно распознавание голоса.
Если есть что-то, что вы не понимаете, вы можете оставить сообщение, спасибо.