네이버의 클로바 노트의 stt와 요약 기능을 직접 만들어보았다.
음성 파일을 입력받아 요약본을 만들어 주는 간단한 웹사이트를 만들었다.
음성 파일을 텍스트로 변환하고, 변환한 텍스트를 기반으로 요약본을 만들어야 하므로
STT API와 요약 기능을 제공하는 API가 필요하다.
이번 포스트에서는 STT API만 다룰 예정이다.
STT API
클로바와, 구글 stt, 그리고 VITO의 음성인식 api가 인식률이 높은 것으로 알고 있다.
나는 VITO api를 사용하기로 했는데, 세 가지 중에 무료 제공량이 가장 많았다. (월 100시간)
인식률도 좋았고, 동시 접속 채널과 화자 분리 등 지원하는 기능도 많았다.
위 사이트에서 Api 연동에 필요한 id, secret key를 발급받을 수 있고 상세한 API 문서도 참고 가능하다.
개발가이드의 참고사항을 보면, Web 또는 App에서 직접적으로 api를 호출하는 것보다 서버에서 호출하는 것을 권장하지만,
나는 배포하지 않을 거라 클라이언트에서 호출해서 사용했다.
인증 (토큰 받기)
export async function authenticate() {
const CLIENT_ID = "*****";
const CLIENT_SECRET = "*****";
const url = "https://openapi.vito.ai/v1/authenticate";
const formData = new URLSearchParams();
formData.append("client_id", CLIENT_ID);
formData.append("client_secret", CLIENT_SECRET);
try {
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: formData,
});
if (!response.ok) {
throw new Error("Network response was not ok");
}
const data = await response.json();
localStorage.setItem("accessToken", data.access_token);
return data;
} catch (error) {
throw new Error(error.message);
}
}
콘솔에서 발급받은 클라이언트 ID와 시크릿키로 요청하여 토큰을 발급받을 수 있다.
음성 파일 변환
export async function transcribeAudio(file) {
const apiUrl = "https://openapi.vito.ai/v1/transcribe";
const token = localStorage.getItem("accessToken");
const corsProxyUrl = "http://localhost:8080/"; // cors-anywhere 프록시 URL
// API 호출을 위한 요청 설정
const headers = new Headers();
headers.append("Authorization", `bearer ${token}`);
const formData = new FormData();
formData.append(
"config",
JSON.stringify({
use_disfluency_filter: true,
})
);
formData.append("file", file);
const requestOptions = {
method: "POST",
mode: "cors",
headers: headers,
body: formData,
};
// cors-anywhere 프록시를 통한 API 호출
try {
const response = await fetch(corsProxyUrl + apiUrl, requestOptions);
const data = await response.json();
return data.id; // 변환된 객체의 id 반환
} catch (error) {
console.error("API 호출 오류:", error);
return null; // 오류 발생 시 null 반환
}
}
음성 파일을 parameter로 받아 text로 변환을 실행한다. 이때 응답은 변환된 text를 포함한 객체의 id이고, 조회하여 원하는 결과를 얻을 수 있다.
여기서 이제 서버를 통해 api를 호출하지 않아서인지, cors 에러가 발생했다. (토큰 발급은 문제 없었는데)
하지만 나는 서버 구축을 하기 싫어서 cors-anywhere를 사용해서 우회하는 방법을 선택했다.
https://cors-anywhere.herokuapp.com/corsdemo
위 사이트에서 데모 버튼을 누르고, 엔드포인트에 위 링크를 삽입하여 호출하는 방식으로 간단하게 우회할 수 있었다.
그런데 이 방법은 요청 횟수가 제한적이었고 불안정해서, cors-anywhere의 프록시 서버를 구축하였다.
자세히는 모르지만,
레포지토리 clone -> npm start -> 8080 port의 localhost 주소를 위 데모 주소 대신 사용하면 끝이다. (fork로 하는 방법도 있음)
변환된 object 조회
export async function getConvertedText(id) {
console.log(`받은 id : ${id}`);
const apiUrl = `https://openapi.vito.ai/v1/transcribe/${id}`;
const token = localStorage.getItem("accessToken");
const corsProxyUrl = "http://localhost:8080/"; // cors-anywhere 프록시 URL
// API 호출을 위한 요청 설정
const headers = new Headers();
headers.append("Authorization", `bearer ${token}`);
const requestOptions = {
method: "GET",
mode: "cors",
headers: headers,
};
// cors-anywhere 프록시를 통한 API 호출
try {
const response = await fetch(corsProxyUrl + apiUrl, requestOptions);
const data = await response.json();
console.log(data);
return data; // 변환된 object 반환
} catch (error) {
console.error("API 호출 오류:", error);
return null; // 오류 발생 시 null 반환
}
}
id 조회해서 text만을 뽑거나, 발화 시간 등 다양한 속성을 참조할 수 있다. (개발가이드 참고)
const transcribedText = transcribedJSON.results.utterances[0].msg;
텍스트 추출
테스트
성공적으로 잘 변환된다.
'Web > JavaScript' 카테고리의 다른 글
[CLOVA Summary / JS] 클로바 API로 텍스트 요약하기 (1) | 2023.07.29 |
---|