졸업 프로젝트로, Google TTS API를 사용하여 사용자만의 가상 보이스를 생성하고 재생하는 것을 주요 내용으로 하는 프로젝트를 진행하게 되었다.
따라서 아래 두 가지 기능을 구현해야했다.
1) 나만의 가상 보이스를 생성한 뒤 "들어보기" 버튼 클릭시 생성된 가상 보이스 들려주기
2) 게시글에 작성된 댓글을 보이스 형태로 들려주기
이를 구현하기 위해서 백에서는 GoogleTTS api를 이용해 음성파일을 만들고, 프론트에서는 백으로부터 받은 음성파일을 사용자에게 들려주도록 해야했다.
이번 포스팅에서는 프론트 부분만 다뤄볼 것이다!
백에서 음성 객체,즉 HttpResponse 형태로 음성파일을 보내준 경우 프론트에서 이를 재생하는 방법을 알아보자😀
상황 : 백에서 tts이용해 음성파일을 생성한 후, HttpResponse 형태로 보내주었다 (음성 객체를 보내줌!)
# 음성 파일을 HttpResponse 객체로 반환
return HttpResponse(response.audio_content, content_type="audio/wav")
-> 백엔드 코드 (장고 이용)
이렇게 서버로부터 받은 음성 데이터를 웹에서 재생하려면?
-> 아래 세 단계를 거쳐야 한다
1) 서버 response로부터 음성 데이터를 "blob 형태"로 받기
음성 데이터는 아날로그 신호를 디지털 형태로 변환한 "바이너리 데이터"이기에 "문자 코드"로 저장되는 텍스트와 다르게 처리해야 한다
-> axios 로부터 response를 받을 때 responseType을 blob으로 설정해주기
이렇게 설정해주면 응답으로 오는 데이터를 blob 객체로 직접 받을 수 있다
* Blob이란?
-> Binary Large Object의 약자로, 이미지, 사운드 파일, 비디오 같은 멀티미디어 데이터를 다룰 때 사용되는 대용량 바이너리 데이터
try {
const response = await client.get(
`/posts/tts/?text=${text}&speed=${speed}&pitch=${pitch}&type=${type}`,
{ responseType: "blob" }
);
const blob = new Blob([response.data], { type: "audio/wav" });
2) blob 객체를 매개변수로 받아 임시 URL을 생성
이렇게 받은 데이터인 blob 객체는 바로 재생할 수 없다
-> 'blob'은 단순히 데이터의 컨테이너 역할을 하며, 데이터의 구조나 포맷을 해석하지 않기 때문에
-> 따라서 blob 객체를 가리키는 URL을 생성하여, 웹 브라우저가 Blob에 저장된 데이터를 웹 페이지의 HTML 요소와 직접 연동하여 사용할 수 있도록 해야한다
-> Blob URL 생성하기 위해 URL.createObjectURL() 메서드를 사용하기!
: 이 메서드는Blob 객체를 매개변수로 받아 브라우저 메모리 상에 임시 URL을 생성하며 이는 Blob 데이터를 가리키는 고유한 주소 역할을 하게 된다.
const blobUrl = URL.createObjectURL(blob);
3) Audio 객체 생성 및 재생
2) 과정에 의해 반환된 URL을 <audio> 태그의 src 속성이나 자바스크립트 Audio 객체에서 사용하면 끝!
이 URL을 사용하여 음성 데이터를 웹 페이지에 임베드하고, 사용자가 재생할 수 있게 한다
new Audio(blobUrl).play();
<전체 코드>
최종적인 음성 재생 메서드( playVoice ) 구현 (api.js에 작성)
// 생성한 음성 재생
export const playVoice = async (text, speed, pitch, type) => {
try {
// blob 형태로 음성 데이터 response 받기
const response = await client.get(
`/posts/tts/?text=${text}&speed=${speed}&pitch=${pitch}&type=${type}`,
{ responseType: "blob" }
);
const blob = new Blob([response.data], { type: "audio/wav" });
// Blob URL 생성
const blobUrl = URL.createObjectURL(blob);
// Audio 객체 생성 및 재생
new Audio(blobUrl).play();
} catch (error) {
console.error("음성 재생 중 오류 발생:", error);
}
};
원하는 페이지에서 playVoice 메서드 호출하면 특정 이미지/버튼 클릭 시 음성이 나오게 할 수 있다
1) 가상보이스 생성 페이지 (MyVoice.jsx)
const listenVoice = async () => {
try {
await playVoice(text, speed, pitch, type);
} catch (error) {
("목소리 재생 실패");
}
};
<img className="play_button"
src="/assets/play.png"
alt="play icon"
onClick={listenVoice}
/>
</div>
-> 재생버튼을 누르면 음성이 나오게 된다. 생성된 가상 보이스를 바탕으로 "가상보이스 생성 완료" 음성 출력
2) 상세 페이지에서 댓글 재생
<api.js>에 작성
export const forumPlayInfo = async (content, speed, pitch, type) => {
try {
await playVoice(content, speed, pitch, type);
} catch (error) {
console.error("게시글 음성 재생 중 오류 발생:", error);
}
};
-> 위에서 구현한 playVoice에 댓글 데이터에 저장되어 있는 content, speed, pitch, type 정보들 넘겨주는 메소드 생성하기
<comment.jsx>에 작성
const handleCommentPlay = async (content, speed, pitch, type) => {
await forumPlayInfo(content, speed, pitch, type);
};
<div key={comment.id} className="comment">
<img
src="/assets/commentPlay.png"
onClick={() =>
handleCommentPlay(
comment.content,
comment.voice_speed,
comment.voice_pitch,
comment.voice_type)
}
alt="commentPlay"
className="commentPlay"></img>
-> comment.id를 통해 댓글을 구분하며 해당id 댓글에 저장되어 있는 content, speed, pitch, type 정보들을 handleCommentPlay메소드에 넘겨준다. 그러면 이 정보들을 최종적으로 platVoice 메소드에 넘겨주게 되고, 이 보이스 정보들을 바탕으로 생성된 보이스의 음성이 재생되게 된다.
-> 재생 버튼을 클릭하면, 텍스트로 된 댓글이 각 유저의 가상 보이스를 이용하여 음성 댓글로 변환되어 재생된다.
'졸업프로젝트' 카테고리의 다른 글
프론트 배포 (aws s3+CloudFront+ github actions) (0) | 2024.05.08 |
---|---|
토큰을 통한 정보 추출 (0) | 2024.04.30 |
댓글 좋아요 및 추천 기능 (0) | 2024.04.30 |
VITS2 모델 논문 & React 설치 및 실행 (0) | 2023.11.24 |