본문 바로가기

컴퓨터/프로젝트

TTS (text-to-speech)을 이용한 간단한 웹

1. 소개

아래 주소에 있는 사이트에 흥미가 생겨 클론 코딩을 해보았다. 글과 사진이 있는 목록을 생성하고 그것들을 클릭하면 해당하는 언어의 목소리가 컴퓨터에서 출력되도록 만들어보았다. 그리고 입력한 텍스트를 말로 변환을 시켜준다.

아이디어 출처: vanillawebprojects.com/projects/speech-text-reader/
해당 깃허브: github.com/bradtraversy/vanillawebprojects

2. 구현 기능

  • 사진 및 글 목록 생성
  • 소리 출력

이렇게 두 개의 기능만 구현했다.

3. 구현 방식

- 사진 및 글 목록 생성

const data = [
  ["img/water.jpg", "목말라", "我渴了", "喉が渇いた", "I'm THIRSTY"], ["img/hungry.jpg", "배고프다", "我饿了", "お腹が空きました", "I'M HUNGRY"],
  ["img/tired.jpg", "피곤해", "我累了", "つかれた", "I'M TIRED"], ["img/hurt.jpg", "상처받았어", "我受伤了", "傷ついた", "I'M HURT"],
  ["img/happy.jpg", "행복해", "我很快乐", "満足しています", "I'M HAPPY"], ["img/angry.jpg", "화났어", "我生气了", "怒っている", "I'M ANGRY"],
  ["img/sad.jpg", "슬퍼", "我很难过", "悲しいです", "I'M SAD"], ["img/scared.jpg", "무서워", "我好害怕", "怖いです", "I'M SCARED"],
  ["img/outside.jpg", "밖에 나가고 싶어", "我想出去", "外に出たい", "I WANT TO GO OUTSIDE"], ["img/home.jpg", "집에 가고 싶어", "我想回家", "家に帰りたい", "I WANT TO GO HOME"],
  ["img/school.jpg", "학교에 가고 싶어", "我想上学", "学校に行きたい", "I WANT TO GO TO SCHOOL"], ["img/grandma.jpg", "할머니를 만나고 싶어", "我想见见奶奶。", "おばあちゃんに会いたい。", "I WANT TO GO TO GRANDMAS"]
];

위 코드처럼 먼저 출력하고자 하는 데이터들을 글 목록으로 묶어서 저장을 했는데 사진의 주소, 한국어, 중국어, 일본어, 영어 순으로 작성해놓았다.

/* 사진 및 글 목록 12개 생성 */
window.onload = function () {
  for (let i = 0; i < 12; i++) {
    create(i);
  }
}

웹 페이지가 로드가 되면 12번 create라는 함수가 실행이 되는데 create 함수는 사진 및 글을 생성하는 함수이다.

참고그림

위 참고그림을 토대로 사진 및 글 목록을 생성할 것이다. main을 글과 사진을 감싸는 이유는 사진과 글을 클릭했을 때 소리가 나오도록 할 것인데 글과 사진에 event를 만드는 것보다 글과 사진을 묶는 하나의 객체에 event를 만든 게 더 좋을 것 같아서 이렇게 계획했다.

/* main이 사진과 글을 감싸는 형태 */
let main = document.createElement("div")
main.className = "main";
main.onclick = function () {
    speak(data[i][select.selectedIndex + 1], select.value);     //미리 만들어 둔 data를 이용하여 선택
}

우선 div를 생성을 하는데 이 div를 main이라고 칭하겠다. 그리고 onclick 이벤트를 해주는데 데이터의 정보에서 선택한 언어에 따라 값을 원하는 텍스트를 고를 수 있게 한다.

let image = new Image();
image.src = data[i][0];         //미리 만들어 둔 주소를 이용하여 선택

그리고 이미지를 생성하는데 미리 만들어 둔 데이터를 이용하여 사진의 주소를 가져온다.

let comment = document.createElement("p");
comment.className = "comment";
comment.append(data[i][4]);

그리고 태그 p를 생성한 뒤 해당하는 내용은 이미지와 마찬가지 미리 생성한 데이터를 통해 가져온다.

main.appendChild(image);
main.appendChild(comment);

document.getElementById("container").appendChild(main);

그리고 난 뒤 main에 이러한 요소들을 전부 포함시켜주면 끝이다.

-소리 출력

const select = document.getElementById("lang")    //select 정보
const text = document.getElementById("text")      //input 정보

소리를 출력하는 것은 의외로 간단했다. 위 코드를 보면 lang이라고 되어있는 id값의 정보를 받아오는데 이것은 select 태그에 부여된 id이다. 그러므로 select의 정보를 가져오고 text라는 id는 input 태그에 부여되었고, btn은 button에 부여되어 각각의 정보를 가져온다.

window.speechSynthesis.cancel(); // 초기화

그리고 speechSynthesis를 초기화를 시켜준다. 왜냐하면 소리를 여러 개 출력 요청을 하면 마치 입력 버퍼에 내용이 전부 빠지지 않아 렉 걸린 것처럼 부자연스럽게 계속해서 나오기에 이것을 미연에 방지하고자 초기화를 시켜준다.

/* input이 비어있다면 */
  if(!text)
  {
    text = "Please fill in the blank";
  }

만약 text의 내용에 어떠한 내용도 없다면 빈칸을 채워달라는 내용으로 text를 채워준다.

const speechMsg = new SpeechSynthesisUtterance();
speechMsg.lang = language;      //언어 설정
speechMsg.text = text;          //글 설정

window.speechSynthesis.speak(speechMsg);   //소리 출력

SpeechSynthesisUtterance라는 객체를 생성하고 이것을 이용해서 우리는 소리를 낼 수 있게 되는데 .lang을 이용하여 언어를 설정해주고 .text를 이용하여 text의 내용을 입력해준다. 그리고 .speak를 해주면 소리가 성공적으로 출력이 된다.

4. 코드 및 구현

아래 condepen에 사진이 없는 이유는 사진은 컴퓨터 내부에 저장되어있는데 따로 네트워크에 연결시키지 않았기 때문이다.

<!DOCTYPE html>
<html>
<head>
<title>Speech Text</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class = "top">
<h1>Speech Text</h1>
<select id="lang">
<option value="ko-KR">Korean</option>
<option value="zh">Chinese</option>
<option value="ja-JP">Japanese</option>
<option value="en-US" selected>English</option>
</select>
<input id="text" onkeypress="enter(event)"></input>
<button id="btn" class="fas fa-volume-up"></button>
</div>
<div id = "container"></div>
<script type="text/javascript" src="script.js"></script>
<script src="https://kit.fontawesome.com/f1fb370a81.js" crossorigin="anonymous"></script>
</body>
</html>
view raw index.html hosted with ❤ by GitHub
body{
padding: 10px;
}
body, button:hover{
background-color: rgb(98, 211, 255);
color: white;
}
.top{
padding-bottom: 20px;
}
.top, p{
text-align: center;
}
h1{
font-size: 50px;
}
button{
border: none;
font-size: 23px;
padding: 12px;
border-radius: 20px;
background-color: white;
color: rgb(98, 211, 255);
transition: 0.5s;
}
button:hover{
border: 2px solid;
}
input{
font-size: 20px;
width: 50%;
padding: 10px;
border-radius: 30px;
}
select{
font-size: 20px;
padding: 10px;
border-radius: 30px;
}
button, select, .main{
cursor: pointer;
}
#container{
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 13px;
}
img{
height: 360px;
width: 100%;
object-fit: cover;
}
p{
font-size: 20px;
font-weight: bold;
}
.main{
background-color: rgb(40, 182, 238);
}
img, .main{
border-radius: 15px;
}
@media (max-width: 1200px) {
#container {
grid-template-columns: repeat(3, 1fr);
}
}
@media (max-width: 830px) {
#container {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 700px) {
#container {
grid-template-columns: 1fr;
}
}
view raw style.css hosted with ❤ by GitHub

깃허브 주소: github.com/fdoom/toy/tree/main/speech_text

 

fdoom/toy

toy_project. Contribute to fdoom/toy development by creating an account on GitHub.

github.com

 

'컴퓨터 > 프로젝트' 카테고리의 다른 글

Calculator  (0) 2021.01.27
계산기 웹 만들기(Calculator)  (0) 2021.01.27
무한 스크롤(Infinite Scrolling)  (0) 2021.01.01
To Do List  (0) 2020.12.25
To Do List(HTML, CSS, JavaScript) 만들기  (0) 2020.12.25