오봉이와 함께하는 개발 블로그
Naver A.I Platform - Chatbot 서비스(음성 메세지 기능 추가) 본문
728x90
CLOVA Chatbot
- 챗봇 제작 API 서비스
- 사용자의 질문 의도를 이해하여 고객 대응 등 다양한 서비스에 활용할 수 있는 Chatbot 제작 지원
- (1) 도메인 생성
- Products & Services / CLOVA Chatbot
- (2) 빌더 실행하기
- (3) 대화 생성
- (4) 챗봇 빌드
- (5) 챗봇 테스트
- (6) 우측 상단에서 [서비스 배포]
- [Custom API Gateway와 End-point 연결이필요합니다] / [연동]
- APIGW 연동 설정
- [자동 연동] / [확인]
- [주소 복사]
- 메신저 연동 설정
- Secret Key [생성] / [복사]
- 연동 완료
- (7) 스프링에서 작업
스프링에서 챗봇 서비스 구현 실습
- (4) 음성 메시지로 챗봇에 질문하기 (답변 : 텍스트)
- 질문을 녹음해서 mp3 파일로 저장
- mp3 파일을 텍스트로 변환 : STT 서비스 사용
- 변환된 텍스트를 질문으로 챗봇 서버로 전송해서 답변 받아서 출력
- ChatbotService 사용
- STTService 사용
- TTSService 수정
public String clovaTextToSpeech2(String message) {
String clientId = "";//애플리케이션 클라이언트 아이디값";
String clientSecret = "";//애플리케이션 클라이언트 시크릿값";
String voiceFileName = "";
try {
String text = URLEncoder.encode(message, "UTF-8"); // 13자
String apiURL = "https://naveropenapi.apigw.ntruss.com/tts-premium/v1/tts";
URL url = new URL(apiURL);
HttpURLConnection con = (HttpURLConnection)url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("X-NCP-APIGW-API-KEY-ID", clientId);
con.setRequestProperty("X-NCP-APIGW-API-KEY", clientSecret);
// post request
String postParams = "speaker=nara&volume=0&speed=0&pitch=0&format=mp3&text=" + text;
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(postParams);
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
BufferedReader br;
if(responseCode==200) { // 정상 호출
InputStream is = con.getInputStream();
int read = 0;
byte[] bytes = new byte[1024];
// 랜덤한 이름으로 mp3 파일 생성
String tempname = Long.valueOf(new Date().getTime()).toString();
voiceFileName = "tts_" + tempname + ".mp3";
File f = new File("/Users/gobyeongchae/Desktop/" + voiceFileName);
f.createNewFile();
OutputStream outputStream = new FileOutputStream(f);
while ((read =is.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
is.close();
} else { // 오류 발생
br = new BufferedReader(new InputStreamReader(con.getErrorStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = br.readLine()) != null) {
response.append(inputLine);
}
br.close();
System.out.println(response.toString());
}
} catch (Exception e) {
System.out.println(e);
}
return voiceFileName;
}
@RequestMapping("/chatbotSend3")
public String chatbotSend3(@RequestParam("message") String inputText) {
String msg = "";
msg = chatbotService.main(inputText);
return msg;
}
@RequestMapping("/chatbotTTS")
public String chatbotTTS(@RequestParam("message") String message) {
String tts = "";
tts = ttsService.clovaTextToSpeech2(message);
return tts;
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>chatbotForm</title>
<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
<script src="js/chatForm3.js"></script>
<link rel="stylesheet" type="text/css" href="css/chatbot.css">
</head>
<body>
<div id="wrap">
<!-- Header -->
<div id="chatHeader">
<span>챗봇</span>
<button id="btnClose">X</button>
</div>
<h3>챗봇 서비스</h3>
<!-- 응답 메시지 출력 -->
<div id="chatBox"></div><br>
<div>
<!-- 질문 메시지 입력 폼 -->
<form id="chatForm">
<input type="text" id="message" name="message" size="30" placeholder="질문을 입력하세요">
<input type="submit" value="전송">
</form>
</div><br>
<div>
<!-- 음성 녹음 -->
음성 메세지 : <button id="record">녹음</button>
<button id="stop">정지</button>
<div id="sound-clips"></div><br>
</div>
<div hidden>
<audio preload="auto" controls></audio>
</div>
<br><br>
<a href="/">index 페이지로 이동</a>
</div>
</body>
</html>
$(function(){
// 웰컴메시지를 받기 위해 message 입력 받기 전 빈 값으로 서버에 전송해서 웰컴메세지 받음
callAjax();
////////////////////////////////////////////////////////
// 음성으로 질문하기
const record = document.getElementById("record");
const stop = document.getElementById("stop");
const soundClips = document.getElementById("sound-clips");
const audioCtx = new(window.AudioContext || window.webkitAudioContext)(); // 오디오 컨텍스트 정의
if (navigator.mediaDevices) {
var constraints = {
audio: true
}
let chunks = [];
navigator.mediaDevices.getUserMedia(constraints)
.then(stream => {
const mediaRecorder = new MediaRecorder(stream);
record.onclick = () => {
mediaRecorder.start();
record.style.background = "red";
record.style.color = "black";
}
stop.onclick = () => {//정지 버튼 클릭 시
mediaRecorder.stop();//녹음 정지
record.style.background = "";
record.style.color = "";
}
mediaRecorder.onstop = e => {
const clipName = "voiceMsg";
//태그 3개 생성
const clipContainer = document.createElement('article');
const audio = document.createElement('audio');
const a = document.createElement('a');
clipContainer.appendChild(a);
soundClips.appendChild(clipContainer);
//chunks에 저장된 녹음 데이터를 audio 양식으로 설정
//audio.controls = true;
const blob = new Blob(chunks, {
'type': 'audio/mp3 codecs=opus'
}) ;
chunks = [];
const audioURL = URL.createObjectURL(blob);
// audio.src = audioURL;
//blob:http://localhost:8011/6377d19d-2ca8-49b1-a37f-068d602ceb60
a.href=audioURL;
a.download = clipName;
//a.innerHTML = "DOWN"
a.click(); // 다운로드 폴더에 저장하도록 클릭 이벤트 발생
fileUpload(blob, clipName);
}//mediaRecorder.onstop
//녹음 시작시킨 상태가 되면 chunks에 녹음 데이터를 저장하라
mediaRecorder.ondataavailable = e => {
chunks.push(e.data)
}
})
.catch(err => {
console.log('The following error occurred: ' + err)
})
}
// 서버에 업로드
function fileUpload(blob, clipName){
var formData = new FormData();
formData.append('uploadFile', blob, clipName+".mp3");
//녹음된 mp3파일 전송하고 반환된 텍스트(result)를 챗봇 서버에 전달
$.ajax({
type:"post",
enctype: 'multipart/form-data',
url: "stt", //통신할 url
data: formData, //전송할 데이타 : 파일명 :voiceMsg.mp3
processData: false,
contentType: false,
success: function(result) {
$('#chatBox').append('<div class="msgBox send"><span id="in"><span>' +
result + '</span></span></div><br>');
// 챗봇에게 전달
$('#message').val(result);
callAjax();
$('#message').val('');
},
error: function(e) {
alert("에러가 발생했습니다 : " + e);
}
});
}
////////////////////////////////////////////////////////
// 질문하고 음답 받기(텍스트)
$('#chatForm').on('submit', function(event){
event.preventDefault();
if($('#message').val() == "") { // 질문을 입력하지 않고 전송 버튼 누를 때 웰컴 메세지 뜨지 않게
alert("질문을 입력하세요");
return false;
}
if($('#message').val() != ""){
$('#chatBox').append('<div class="msgBox send"><span id="in"><span>' +
$('#message').val() + '</span></span></div><br>');
}
callAjax();
/* 입력란 비우기*/
$('#message').val('');
}); // submit 끝
// 별도의 ajax 생성
function callAjax() {
$.ajax({
url:"chatbotSend3",
type:"post",
data:{message: $('#message').val()},
success:function(result){
/* chatBox에 받은 메시지 추가 */
$('#chatBox').append('<div class="msgBox receive"><span id="in"><span>챗봇</span><br><span>' +
result +'</span></span></div><br><br>');
// 스크롤해서 올리기
$("#chatBox").scrollTop($("#chatBox").prop("scrollHeight"));
callAjaxTTS(result);
},
error:function(){
alert("오류가 발생했습니다.")
}
});
}
function callAjaxTTS(result){
$.ajax({
type:"post",
url:"chatbotTTS",
data:{message : result},
dataType :'text',
success:function (result){ //음성 파일 이름 받음
/* chatBox에 받은 음성 메시지 플레이 */
$('audio').prop("src", '/images/'+ result)[0].play();
$('audio').hide();
},
error:function(data){
alert("에러 발생");
}
});
}
});
728x90
'Naver A.I Platform' 카테고리의 다른 글
Naver A.I Platform - JSON JS에서 파싱, 멀티링크, 링크, 이미지 구현 (4) | 2022.01.27 |
---|---|
Naver A.I Platform - Chatbot 서비스(채팅창 작성) (0) | 2022.01.26 |
Naver A.I Platform - Chatbot 서비스(메세지 직접 입력) (0) | 2022.01.26 |
Naver A.I Platform - Chatbot 서비스 (0) | 2022.01.26 |
Naver A.I Platform - Text To Speech(TTS) (0) | 2022.01.25 |
Comments