Взявшись за руки, вытяните java-веб-робот II (конец)

Java

Полный адрес проекта:После git ee.com/T-Zone/wit…

Введение

В прошлой статье мы кратко рассказали о решении использования Springboot с Alibaba Cloud Xiaomi для реализации текстового робота. Предыдущий адрес:Наггетс.Талант/пост/687488….

В этой главе будут представлены решения и решения по интеграции для интеллектуальных голосовых роботов.

2. Решения

проблема:

Если вы хотите внедрить интегрированного интеллектуального голосового робота, есть три основных болевых момента.

  1. Как преобразовать поток байтов с микрофона в текст
  2. Как после получения пользовательского текста проанализировать намерение пользователя и дать соответствующий ответ
  3. Получив ответ, как преобразовать соответствующий ответ в речь

решать:

  1. Текущая основная функция транскрипции речи (ASR) может использоваться для получения потока байтов микрофона.
  2. После получения текста используйте понимание естественного языка (NLU) для анализа намерений пользователя.
  3. Получив ответ, используйте функцию преобразования текста в речь (TTS).

Поэтому, если вы всегда знаете, как решить эту проблему, вы можете выбрать, какие возможности производителя использовать.Я в основном выбираю возможности искусственного интеллекта Alibaba Cloud для реализации нашего интеллектуального голосового робота.

3. Технический выбор и временная диаграмма

За кулисами

  1. springboot
  2. WebSocket
  3. Али Аср (в реальном времени)
  4. Али ТТС
  5. Облако Алибаба Сяоми

стойка регистрации

  1. HZRecorder2.js (функция записи h5, декодирование js)
  2. Socket.io (js со встроенным веб-сокетом)

Временная диаграмма:

В-четвертых, интегрировать али аср и тц

аср адрес:help.aliyun.com/document_…
ттс адрес:help.aliyun.com/document_…

  1. Внедрить необходимый 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>
    
  2. Интегрировать код 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();
                }
            }
        }
    
  3. Интегрировать метод 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-связь отключается после однократного обмена данными, и сервер не может активно передавать информацию клиенту. И длинный веб-сокет соединения решает эту проблему

  1. Внедрить необходимый SDK в проект maven

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-websocket</artifactId>
            </dependency>
    
  2. Интегрированный метод доступа к голосовому потоку

        /**
         * 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();
            }
        }
    
  3. Интеграция прослушивает, покидает ли пользователь событие

       @OnClose
        public void onClose(Session session, @PathParam("uid") String uid, @PathParam("roleType") int roleType) {
            remove(session, uid, roleType);
        }
    

6. Внешняя интеграция HZRecorder2.js (плагин для записи)

  1. Используйте recorder.js для захвата голоса с микрофона и его записи.

  2. часть кода

            //开始录音        this.start = function () {            audioInput.connect(recorder);            recorder.connect(context.destination);        }
    

7. Интерфейсный интегрированный веб-сокет для передачи голосовых байтов в режиме реального времени.

  1. Используйте recorder.js для сбора записей с микрофона и передачи их в фоновом режиме через протокол веб-сокета для анализа.

  2. часть кода

     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, для воспроизведения голоса.

  1. Воспроизведение музыки напрямую через тег audio не разрешено в основных браузерах, поэтому, учитывая некоторые проблемы совместимости, для воспроизведения используется audioContext, который может быть хорошо совместим с основными основными браузерами.

  2. часть кода

    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-программу, чтобы испытать процесс голосового взаимодействия в реальном времени.

Хорошо, это все, я надеюсь, что это может помочь вам, кому нужно распознавание голоса.

Если есть что-то, что вы не понимаете, вы можете оставить сообщение, спасибо.