웹사이트 stt 구현, speech to text 입력받아서 폼 넘기기 까지

김모씨·2022년 12월 4일
0

완성본- JS로 구현

4차 프로젝트때 주제가 '그림으로 일기쓰는 웹서비스 구현'이었다.
일기를 입력할 때 stt를 사용해서 일기를 입력받고 싶었다.

- 음성인식으로 이어서 쓰기 가능

  • js를 배운 적이 없어서 이거 검색하고 이것저것 코드보면서 시도한게 10시간은 한 것 같다.. 이번 프로젝트 끝나고 자바 스크립트를 꼭 공부해보고 싶다!
  • 파이썬과 장고 분야 최고의 개발자, 세계 최강 이진석 대표님께 이메일로 질문드리면서 코드를 공부할 수 있었다!

참고 사이트
https://prlabhotelshoe.tistory.com/9

https://github.com/amirkhan064/speech-to-text-convertor-app/blob/main/index.html
https://www.youtube.com/watch?v=ABoCeLjY0Xo&list=LLrMY3C2G9ShhFi3y6GCkk1w
https://www.labnol.org/software/add-speech-recognition-to-website/19989/
https://techmuzz.com/blogging/add-speech-recognition-to-any-input-box-in-your-website/

제가 사용한 코드는 다음의 블로그에서 참고했습니다.
https://m.blog.naver.com/jcosmoss/221402439833
https://github.com/amirkhan064/speech-to-text-convertor-app/blob/main/index.html

주의할 점

  • form태그 안에 button을 submit으로 인식되지 않도록 하기 위해 다음과 같이 지정해주었습니다.
<button type="button"></button>
  • textarea태그 안에 id로 js가 인식한다는 것도 중요했던 점!! (js를 잘 모르기 때문에 ..)

최종 코드

<!DOCTYPE html>

<html lang="ko">

<head>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous" />
</head>

<body>
    
<div class="container">

<div class="my-3">
    <button id="stt-start-button" class="btn btn-secondary" type="button"><svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-microphone" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
        <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
        <rect x="9" y="2" width="6" height="11" rx="3"></rect>
        <path d="M5 10a7 7 0 0 0 14 0"></path>
        <line x1="8" y1="21" x2="16" y2="21"></line>
        <line x1="12" y1="17" x2="12" y2="21"></line>
     </svg>&nbsp;&nbsp;음성인식 시작 </button>

    <button id="stt-stop-button" class="btn btn-secondary d-none" type="button">
        <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-microphone" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
            <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
            <rect x="9" y="2" width="6" height="11" rx="3"></rect>
            <path d="M5 10a7 7 0 0 0 14 0"></path>
            <line x1="8" y1="21" x2="16" y2="21"></line>
            <line x1="12" y1="17" x2="12" y2="21"></line>
         </svg>
        
        
        <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-antenna-bars-3" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
        <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
        <line x1="6" y1="18" x2="6" y2="15"></line>
        <line x1="10" y1="18" x2="10" y2="12"></line>
        <line x1="14" y1="18" x2="14" y2="18.01"></line>
        <line x1="18" y1="18" x2="18" y2="18.01"></line>
     </svg>
        
        &nbsp;&nbsp; 중지하기 </button>
    <p id="message">버튼을 누르고 말씀하세요.</p> 
</div>

<form action="" method="post" id="stt-form">
    {% csrf_token %}
    <div class="my-3">
        <textarea name="content" class="form-control"></textarea>
    </div>
    <input type="submit" class="btn btn-primary" />
</form>


<script>
    const stt_start_button = document.querySelector("#stt-start-button");
    const stt_stop_button = document.querySelector("#stt-stop-button");

    var message = document.querySelector("#message");
    const stt_form = document.querySelector("#stt-form");
    const content_field = document.querySelector('#stt-form [name=content]');
    let content_field_value = "";  // STT 재시작시마다 results 값이 초기화됩니다.

    const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
    const speech_recognition = new SpeechRecognition();
    speech_recognition.lang = "ko-kr";
    speech_recognition.continuous = true;

    function enable_stt() {
        content_field_value = content_field.value;

        speech_recognition.start();
        message.innerHTML = "음성인식 중...";
        stt_start_button.classList.toggle("d-none");
        stt_stop_button.classList.toggle("d-none");
    }

    function disable_stt() {
        speech_recognition.stop();
        message.innerHTML = "버튼을 누르고 말씀하세요.";
        stt_start_button.classList.toggle("d-none");
        stt_stop_button.classList.toggle("d-none");
    }
    
    // stt_start_button이 <form> 안에 있다면 submit 동작을 가지게 됩니다.
    // 그런데 다른 STT동작을 해야지, form submit을 해서는 안 되는 것이잖아요.
    // 아래 click handler에서 e.preventDefault(); 를 호출하여 원래 동작(form submit)을 안하게 하든지.
    // stt_start_button은 <form> 외부로 빼시는 것이 낫습니다.
    stt_start_button.addEventListener("click", () => { enable_stt(); });
    stt_stop_button.addEventListener("click", () => { disable_stt(); });

    speech_recognition.onresult = function (e) {
        console.log(e.results);
        // disable_stt();

        // 매 result 반환 시마다 e.results의 개수가 늘어납니다.
        const transcript = Array.from(e.results)
            .map(result => result[0])
            .map(speech => speech.transcript)
            .join(' ');

        console.log("transcript :", transcript);
        content_field.value = content_field_value + " " + transcript;
    };

    speech_recognition.onerror = function (e) {
        console.error(e);
        disable_stt();
    };

// script 안에 </html>이 있었습니다.

</script>

</div>

</body>

</html>
profile
하루하루 성장하는 코딩 실력!! 내 맘대로 기록하는 코딩 블로그

2개의 댓글

comment-user-thumbnail
2022년 12월 8일

최고다 -김채현 -

1개의 답글