오봉이와 함께하는 개발 블로그

Naver A.I Platform - CLOVA Speech Recognition (CSR : 음성 인식) 본문

Naver A.I Platform

Naver A.I Platform - CLOVA Speech Recognition (CSR : 음성 인식)

오봉봉이 2022. 1. 25. 15:43
728x90

CLOVA Speech Recognition (CSR) : 음성 인식

  • 음성 인식 API 서비스
  • 사람의 목소리를 텍스트로 변환
  • 음성을 텍스트로 변환 : STT(Speech-To-Text)
  • 음성 파일을 입력 받아서 변환된 텍스트로 반환
  • 언어 선택 가능
  • (1) 결과를 콘솔에 출력
    • STTService 클래스 생성
    • clovaSpeechToText() 메소드 추가
    • 콘솔 창에 텍스트 출력
@Service
public class STTService {
    public void clovaSpeechToText() {
        String clientId = "";             // Application Client ID";
        String clientSecret = "";     // Application Client Secret";

        try {
            String imgFile = "/Users/gobyeongchae/Desktop/voice/kor1.mp3";
            File voiceFile = new File(imgFile);

            String language = "Kor";        // 언어 코드 ( Kor, Jpn, Eng, Chn )
            String apiURL = "https://naveropenapi.apigw.ntruss.com/recog/v1/stt?lang=" + language;
            URL url = new URL(apiURL);

            HttpURLConnection conn = (HttpURLConnection)url.openConnection();
            conn.setUseCaches(false);
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setRequestProperty("Content-Type", "application/octet-stream");
            conn.setRequestProperty("X-NCP-APIGW-API-KEY-ID", clientId);
            conn.setRequestProperty("X-NCP-APIGW-API-KEY", clientSecret);

            OutputStream outputStream = conn.getOutputStream();
            FileInputStream inputStream = new FileInputStream(voiceFile);
            byte[] buffer = new byte[4096];
            int bytesRead = -1;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            outputStream.flush();
            inputStream.close();
            BufferedReader br = null;
            int responseCode = conn.getResponseCode();
            if(responseCode == 200) { // 정상 호출
                br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            } else {  // 오류 발생
                System.out.println("error!!!!!!! responseCode= " + responseCode);
                br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            }
            String inputLine;
            if(br != null) {
                StringBuffer response = new StringBuffer();
                while ((inputLine = br.readLine()) != null) {
                    response.append(inputLine);
                }
                br.close();
                System.out.println(response.toString());
            } else {
                System.out.println("error !!!");
            }
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}
@RequestMapping("/sttService")
    public void sttService() {
        sttService.clovaSpeechToText();
    }
  • (2) 파일 업로드 / 추출된 텍스트 출력
    • sttView.jsp
    • stt.js
    • APIRestController에 추가
    • 추출된 텍스트를 파일로 저장
      • resultToFileSave() 메소드 추가
@RequestMapping("/stt")
    public String sttService(@RequestParam("uploadFile") MultipartFile file) {
        String stt = "";
        try {
            // 1. 파일 저장 경로 설정 : 실제 서비스되는 위치 (프로젝트 외부에 저장)
            String uploadPath = "/Users/gobyeongchae/Desktop/productImages";
            // 2. 원본 파일 이름 알아오기
            String originalFileName = file.getOriginalFilename();
            String filePathName = uploadPath + originalFileName;
            // 3. 파일 생성
            File file1 = new File(filePathName);
            // 4. 서버로 전송
            file.transferTo(file1);
            // 서비스에 파일 path와 파일명 전달  -> 서비스 메소드에서 변경
            // 서비스에서 반환된 PoseVO 리스트 저장
            stt = sttService.clovaSpeechToText(filePathName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return stt;
    }
@Service
public class STTService {
    public String clovaSpeechToText(String filePathName) {
        String clientId = "";             // Application Client ID";
        String clientSecret = "";     // Application Client Secret";
        String resultText = "";
        try {
            String imgFile = filePathName;
            File voiceFile = new File(imgFile);

            String language = "Kor";        // 언어 코드 ( Kor, Jpn, Eng, Chn )
            String apiURL = "https://naveropenapi.apigw.ntruss.com/recog/v1/stt?lang=" + language;
            URL url = new URL(apiURL);

            HttpURLConnection conn = (HttpURLConnection)url.openConnection();
            conn.setUseCaches(false);
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setRequestProperty("Content-Type", "application/octet-stream");
            conn.setRequestProperty("X-NCP-APIGW-API-KEY-ID", clientId);
            conn.setRequestProperty("X-NCP-APIGW-API-KEY", clientSecret);

            OutputStream outputStream = conn.getOutputStream();
            FileInputStream inputStream = new FileInputStream(voiceFile);
            byte[] buffer = new byte[4096];
            int bytesRead = -1;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            outputStream.flush();
            inputStream.close();
            BufferedReader br = null;
            int responseCode = conn.getResponseCode();
            if(responseCode == 200) { // 정상 호출
                br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            } else {  // 오류 발생
                System.out.println("error!!!!!!! responseCode= " + responseCode);
                br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            }
            String inputLine;
            if(br != null) {
                StringBuffer response = new StringBuffer();
                while ((inputLine = br.readLine()) != null) {
                    response.append(inputLine);
                }
                br.close();
                System.out.println(response.toString());
                resultText = jsonToString(response.toString());
                resultToFileSave(resultText); // 파일로 저장
            } else {
                System.out.println("error !!!");
            }
        } catch (Exception e) {
            System.out.println(e);
        }
        return resultText;
    }

    public String jsonToString(String jsonResultStr) {
        String resultText = "";
        try {
            JSONObject jsonObject = new JSONObject(jsonResultStr);
            resultText = (String)jsonObject.get("text");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultText;
    }
    // 음성 파일에서 추출한 텍스트 파일로 저장
    public void resultToFileSave(String result) {
        try {
            String fileName = Long.valueOf(new Date().getTime()).toString();
            String filePathName = "/Users/gobyeongchae/Desktop/voice/" + "stt_" + fileName + ".txt";

            FileWriter fw = new FileWriter(filePathName);
            fw.write(result);
            fw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
<html>
  <head>
      <title>STT Form</title>
  </head>
  <script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
  <script src="js/stt.js"></script>
  <body>
      <!--  파일 업로드 -->
      <h3>음석 인식</h3>
      <form id="sttForm" enctype="multipart/form-data">
          파일 : <input type="file" id="uploadFile" name="uploadFile">
          <input type="submit" value="결과 확인">
      </form>
      <br><br>
      <!-- 객체와 좌표 값 출력 -->
      STT 결과 : <div id="resultDiv"></div>
      <br><br>
      <div><audio preload="auto" controls></audio></div>
      <a href="/">index 페이지로 이동</a>
  </body>
</html>
$(function () {
    // submit 했을 때 처리
    $('#sttForm').on('submit', function (event) {
        event.preventDefault();
        var formData = new FormData($('#sttForm')[0]);
        var fileName = $('#uploadFile').val().split("\\").pop();
        $('audio').prop("src", '/voice/' + fileName);
        $.ajax({
            type : "post",
            enctype : "multipart/form-data",
            url : "stt",
            data : formData,
            processData : false, // 필수
            contentType : false, // 필수
            success:function (result) {
                $('#resultDiv').text(result);
            },
            error:function (e) {
                alert("오류 발생" + e);
            }
        });
    })
})
  • (3) 언어 선택 <select name=”language”> 추가
    • sst2.jsp
    • sst2.js
// 언어 선택
    @RequestMapping("/stt2")
    public String sttService2(@RequestParam("uploadFile") MultipartFile file, @RequestParam("language") String language) {
        String stt = "";
        try {
            // 1. 파일 저장 경로 설정 : 실제 서비스되는 위치 (프로젝트 외부에 저장)
            String uploadPath = "/Users/gobyeongchae/Desktop/productImages";
            // 2. 원본 파일 이름 알아오기
            String originalFileName = file.getOriginalFilename();
            String filePathName = uploadPath + originalFileName;
            // 3. 파일 생성
            File file1 = new File(filePathName);
            // 4. 서버로 전송
            file.transferTo(file1);
            // 서비스에 파일 path와 파일명 전달  -> 서비스 메소드에서 변경
            // 서비스에서 반환된 PoseVO 리스트 저장
            stt = sttService2.clovaSpeechToText(filePathName, language);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return stt;
    }
@Service
public class STTService2 {
    public String clovaSpeechToText(String filePathName, String language) {
        String clientId = "";             // Application Client ID";
        String clientSecret = "";     // Application Client Secret";
        String resultText = "";
        try {
            String imgFile = filePathName;
            File voiceFile = new File(imgFile);

            //String language = SelLanguage;        // 언어 코드 ( Kor, Jpn, Eng, Chn )
            String apiURL = "https://naveropenapi.apigw.ntruss.com/recog/v1/stt?lang=" + language;
            URL url = new URL(apiURL);

            HttpURLConnection conn = (HttpURLConnection)url.openConnection();
            conn.setUseCaches(false);
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setRequestProperty("Content-Type", "application/octet-stream");
            conn.setRequestProperty("X-NCP-APIGW-API-KEY-ID", clientId);
            conn.setRequestProperty("X-NCP-APIGW-API-KEY", clientSecret);

            OutputStream outputStream = conn.getOutputStream();
            FileInputStream inputStream = new FileInputStream(voiceFile);
            byte[] buffer = new byte[4096];
            int bytesRead = -1;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            outputStream.flush();
            inputStream.close();
            BufferedReader br = null;
            int responseCode = conn.getResponseCode();
            if(responseCode == 200) { // 정상 호출
                br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            } else {  // 오류 발생
                System.out.println("error!!!!!!! responseCode= " + responseCode);
                br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            }
            String inputLine;
            if(br != null) {
                StringBuffer response = new StringBuffer();
                while ((inputLine = br.readLine()) != null) {
                    response.append(inputLine);
                }
                br.close();
                System.out.println(response.toString());
                resultText = jsonToString(response.toString());
                resultToFileSave(resultText); // 파일로 저장
            } else {
                System.out.println("error !!!");
            }
        } catch (Exception e) {
            System.out.println(e);
        }
        return resultText;
    }

    public String jsonToString(String jsonResultStr) {
        String resultText = "";
        try {
            JSONObject jsonObject = new JSONObject(jsonResultStr);
            resultText = (String)jsonObject.get("text");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultText;
    }
    // 음성 파일에서 추출한 텍스트 파일로 저장
    public void resultToFileSave(String result) {
        try {
            String fileName = Long.valueOf(new Date().getTime()).toString();
            String filePathName = "/Users/gobyeongchae/Desktop/voice/" + "stt2_" + fileName + ".txt";

            FileWriter fw = new FileWriter(filePathName);
            fw.write(result);
            fw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
<html>
  <head>
      <title>STT Service2</title>
    <script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
    <script src="js/stt2.js"></script>
  </head>
  <body>
    <!--  파일 업로드 -->
    <h3>음석 인식</h3>
    <form id="sttForm" enctype="multipart/form-data">
      파일 : <input type="file" id="uploadFile" name="uploadFile">
      <br>
      언어 선택 :
      <select name="language" id="language">
        <option value="">언어 선택</option>
        <option value="Kor">한국어</option>
        <option value="Jpn">일본어</option>
        <option value="Eng">영어</option>
        <option value="Chn">중국어</option>
      </select>
      <input type="submit" value="결과 확인">
    </form>
    <br><br>
    <!-- 객체와 좌표 값 출력 -->
    STT 결과 : <div id="resultDiv"></div>
    <br><br>
    <div><audio preload="auto" controls></audio></div>

    <a href="/">index 페이지로 이동</a>
  </body>
</html>
$(function () {
    // submit 했을 때 처리
    $('#sttForm').on('submit', function (event) {
        event.preventDefault();
        var formData = new FormData($('#sttForm')[0]);
        var fileName = $('#uploadFile').val().split("\\").pop();
        $('audio').prop("src", '/voice/' + fileName);
        $.ajax({
            type : "post",
            enctype : "multipart/form-data",
            url : "stt2",
            data : formData,
            processData : false, // 필수
            contentType : false, // 필수
            success:function (result) {
                $('#resultDiv').text(result);
            },
            error:function (e) {
                alert("오류 발생" + e);
            }
        });
    })
})
728x90
Comments