조금 더 편리하게 만든 카카오STT 샘플 jsp

2023. 3. 2. 11:19기타 도구/STT

예제 HTML코드는 alert를 많이 눌러줘야해서 귀찮았는데 alert을 많이 제거한 버전이다.

alert대신 원기호를 이용해서 상태를 표시하게 만들었다.

 

사용법은 [파일선택] > [connect] > [send] 순으로 선택해주면 끝이다.

 

<!DOCTYPE html>
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<html>
<head>
    <meta charset="UTF-8">
    <title>File Upload Client</title>
    
    <script src="http://code.jquery.com/jquery-latest.js"></script>
    <script type="text/javascript">

        let ws = null;
        let cnt = 0;

        function connector(){
            // must modify endpoint
            var uri = '자신의uri를 넣어주세요';
            //alert(uri)
            $("#staCircle").css("color", "yellow");
            $("#status").text("접속중...");

            ws = new WebSocket(uri);

            ws.binaryType="arraybuffer";

            // 1. send recogStart message (RAWPCM/16/16000/1/_/_)
            ws.onopen=function(){
                const now = Date.now()
                ws.send(`{"type":"recogStart","service":"DICTATION","showFinalOnly":false,"showExtraInfo":false,"requestId":"GNTWSC-${now}","audioFormat":"_/16/16000/1/_/_"}`)
                $("#staCircle").css("color", "green");
                $("#status").text("연결 완료");
            };

            // 2. read server message
            ws.onmessage = function(e){
            	
                let out = document.getElementById('output');
                
                //partialResult가 포함 되어 있을 때만 표시하기
                if(e.data.indexOf("partialResult") != -1){
                	
                	var str1 = (e.data).indexOf('value":');
                	var str2 = (e.data).indexOf('}');
                	let resultstr = (e.data).slice(str1+7, str2);
                	
	            	if(document.getElementById("partRt" + cnt)){
	            		$("#partRt" + cnt).text(resultstr);
	            	}else{
	            		out.innerHTML += '<p id="partRt' + cnt + '">' + resultstr + '</p>';
	            	}
                }
                
            	
                //out.innerHTML += e.data + '<br>';
                
                console.log(e.data);
                
                //finalResult가 포함 되어 있을 때만 표시하기
                if(e.data.indexOf("finalResult") != -1){
                	var str1 = (e.data).indexOf('value":');
                	var str2 = (e.data).indexOf(',"durationMS":');
                	let resultstr = (e.data).slice(str1+7, str2);
                	
                	$("#partRt" + cnt).text(resultstr);
	                //$("#textBox").append(resultstr + "\n");
	                cnt++;
                }
            };

            setTimeout(function() {
                ws.close();
            }, 3600000);

            ws.onclose = function() {
                $("#staCircle").css("color", "black");
                $("#status").text("연결 종료");
            };
            ws.onerror = function(e) {
                alert("onerror: " + e.msg);
                $("#staCircle").css("color", "red");
                $("#status").text("에러 발생");
            }
        }

        function sleep(ms) {
            return new Promise((r) => setTimeout(r, ms))
        }

        function sendFile(){
            let file = document.getElementById('file').files[0];
            $("#status").text("파일을 전송중입니다.");

            let reader = new FileReader();
            let rawData;
            
            reader.loadend = function() {
                
            }
            
            // 3. async send audio binary message (file) and control sending speed
            reader.onload = async function(e) {
                rawData = e.target.result;

                const chunkLength = 640;
                const sleepDuration = 20;

                let begin = 0;
                let end = chunkLength;

                while(end < rawData.byteLength) {
                    await ws.send(rawData.slice(begin, end));
                    await sleep(sleepDuration);
                    begin = end;
                    end = begin + chunkLength;
                }
                await ws.send(rawData.slice(begin, rawData.byteLength));

                // 4. send recogEnd message
                await ws.send('{"type":"recogEnd"}');
                
                $("#status").text("파일 전송 완료");
            }

            reader.readAsArrayBuffer(file);
        }

        function addEvent(){
            document.getElementById("connect").addEventListener("click", connector, false);
            document.getElementById("send").addEventListener("click", sendFile, false);
        }

        window.addEventListener("load", addEvent, false);
    </script>

</head>
<body>
<p><span id=staCircle></span><span id=status>연결 안됨</span></p>
<br>
<input id="file" type="file" accept=".wav, .mp3">
<input id="connect" type="button" value="connect">
<input id="send" type="button" value="send">
<br>
<br>
<br>
<!-- <textarea id="textBox" style="width: 1200px; height: 400px;"></textarea> -->


<div id="output"></div>

</body>
</html>