가끔 안방에서 거실에 있는 아이들이나 아내를 부를 때 말로는 잘 안 들릴때가 있습니다. 특히, 문이 닫혀 있는 상황에서는 크게 고함을 쳐도 잘 전달되지 않을 때가 많습니다. 그런 경우 결국은 일어나서 문을 열고 가서 직접 얘기를 해야하죠. 귀차니즘으로 전화를 걸 때도 있는데, 집에서 모두가 계속 전화기를 들고 있지는 않으므로 휴대전화도 유용하지는 않습니다. 마땅한 방법이 없을까 생각하다, 마침 놀고있는 라즈베리파이(3b 모델)가 있길래 방치된 스피커를 하나 찾아서 웹앱을 하나 만들기로 했습니다.
웹앱의 기능은 처음에는 TTS(Text To Speech) 기능을 생각했습니다. 웹페이지에서 텍스트를 입력하면 이를 TTS 기능으로 음성파일로 변환하고 그 파일을 플레이하여 연결된 스피커로 출력하는 것입니다. 예를 들어 뭐좀 가져다 달라고 하고 싶으면, 브라우저로 웹앱 접속하고, '누구야, 뭐 좀 가져다 줘'라고 입력하면 이를 TTS 기능을 통해 라즈베리파이에 연결된 스피커로 출력하는 것입니다.
TTS
처음에는 espeak라는 프로그램을 사용하려고 했습니다. 라즈베리파이에 설치하고 테스트를 해 보니 기능은 잘 동작하나 변환된 음성이 알아들을 수 없을 정도로 이상했습니다. 아무래도 요즘 주로 쓰이는 딥러닝에 의한 방법이 아닌 예전의 알고리즘적 방법은 한계가 있는 듯 보였습니다. 그래서, 구글, 카카오, 네이버 등 오픈 API를 제공하는 곳에서 혹시 제공하는 데가 없나 검색을 해 봤는데 유료밖에 존재하지 않았습니다.
안타까워하며 검색을 더 해 보던 중에 gTTS라는 파이썬 라이브러리를 찾게 됐습니다. 소스코드를 좀 살펴보니, 이 라이브러리는 구글 번역 홈페이지에서 제공하는 구글 TTS 기능을 (프로그램적으로) 브라우저가 접근하듯이 사용하여 텍스트를 mp3 파일로 반환해 주는 라이브러리였습니다. 바로 테스트를 해 봤는데 (당연한 얘기지만) 정말 자연스럽게 텍스트를 읽어줬습니다. 구글 번역 사이트에서 듣기 버튼 눌렀을 때 나오는 목소리와 같은 것입니다.
TTS 기능을 사용할 수 있게 됐으니, 이제 앱의 전체적인 구성 및 개발을 진행했습니다.
전체 구성
- 하드웨어
- 라즈베리파이 3B: 웹앱 구동 및 스피커를 통한 출력 담당
- 라이언 블루투스 스피커: 블루투스 스피커지만 출력을 유선으로 라즈베리파이와 연결
- 소프트웨어
- python
- summer: FastAPI 기반의 프로젝트 템플릿입니다. 개인적으로 사용하려고 만들어 둔 것입니다.
화면
STS (Speech To Speech)
TTS 기능을 만들고 나니, 제 음성을 그대로 보내서 스피커로 내 보내는 기능도 추가하고 싶어졌습니다. 처음부터 프론트엔드는 간단한 웹페이지로만 만들려고 했기때문에 브라우저에서 녹음 및 전송 기능을 제공해야만 가능한 기능이었습니다. 이번에는 ChatGPT를 활용한 코딩 테스트도 할 겸 ChatGPT에 물었습니다.
프롬프트를 어렵게 하지 않고, 단순히 했습니다. 먼저, 리액트도 간만에 다뤄볼까해서,
write a mobile web page using React. it has one textarea and a submit button.
라고 입력했습니다. 결과는 비교적 잘 나온거 같은데 결과를 보니 아무래도 번들러 설정등을 해야할 거 같아 귀찮아서 리액트는 포기하고 다시 정말 단순하게 다음과 같이 물었습니다.
음성을 녹음해서 서버로 전송하는 프로그램을 작성해 줘.
기능 테스트 정도에는 문제 없이 바로 쓸 수 있는 수준으로 꽤 쓸만한 결과를 응답해줬고 이를 기반으로 작업을 했습니다. 다만, 지금 시간이 좀 지나서 정확히 기억은 나지 않는데 뭔가 이가 안 맞는 부분이 있었고 이를 해결하는데 시간이 좀 걸리기는 했습니다.
이렇게 해서 웹페이지에서 음성을 녹음해서 서버로 전송하는 것은 구현을 잘 했는데, 한가지 문제가 발생했습니다. 크롬 브라우저에서 MediaRecorder로 음성을 녹음하면 WebM 형식이 사용됩니다. wav라면 aplay라는 기본적으로 설치돼 있는 프로그램으로 플레이할 수 있지만, WebM은 라즈베리파이(리눅스 환경)에 FFMpeg을 설치해야만 플레이가 가능합니다. 그런데, 라즈베리파이에 ffmpeg 설치가 또 만만치 않은 일이라 다른 방법이 없을지 좀 고민과 검색을 했습니다. recorder.js라는 것이 웹페이지에서 녹음할 때 많이 언급되는데, github 페이지에 보니 지원 중단됐다고 하여 제외시켜 놓고 있었는데, 결국 recorder.js의 기능을 통해 wav 형식으로 변환하여 보낼 수 있게 됐습니다. 이 게 적고나니 두, 세줄 정도인데 이 부분에서 시간을 좀 많이 허비했습니다.
음성 파일 형식과 관련하여 부가적으로 좀 더 얘기해 보면, WebM은 비디오와 오디오 데이터를 담을 수 있는 컨테이너 형식이고, 이 컨테이너에 어떤 코덱을 사용해서 담았는지도 중요합니다. 보통 오디오만 저장하는 경우 코덱은 vorbis나 opus가 사용됩니다. 크롬 브라우저가 WebM에 대해서 PCM 코덱을 지원한다면(실제 지원합니다. 전체 목록은 여기에서 확인 가능합니다), wav 형식이 PCM 데이터를 무손실, 무압축으로 저장하는 형식이기 때문에 WebM -> Wav 변환이 (이론적으로) 비교적 쉽게 가능할 수 있습니다. 이론적으로요. ^^
이런 과정을 거쳐 STS 기능도 추가했습니다. 이제 제 목소리를 스피커로 출력할 수 있게 된거죠
STT to TTS
STS 기능을 만들고 나니, 이제는 출력은 TTS 목소리로 하는데 입력은 귀찮게 텍스트 입력하지 않고 음성으로 바로 녹음한 것을 사용하고 싶어졌습니다. 쉽게 얘기해 말로 입력한 텍스트를 음성으로 변환해 출력하는 거죠.
STT API를 제공하는 곳을 찾아봤고, 고맙게도 ETRI에서 (일 사용수 제한은 있지만) 무상으로 제공하는 AI API/DATA 사이트를 찾을 수 있었습니다.
앞서 TTS와 STS 기능을 만들었으니, 구현은 쉽게 진행할 수 있었습니다.
STS -> 음성 녹음 파일을 STT API로 전송 -> 돌려받은 결과(음성 to Text)를 TTS 기능으로 스피커로 출력
인공지능 스피커로 진화?
실제로 별거 아니기도 하고, 심심해서 만들기 시작한 것이기는 한데 만들다 보니 재미가 들려서 이번에는 ChatGPT와 연동해서 궁금한거 있을때 말로 물어보고 ChatGPT 결과를 TTS를 통해 음성으로 들려주는 걸 만들어 보기로 했습니다.
STS -> 음성 녹음 파일을 STT API로 전송 -> 돌려받은 결과(음성 to Text)를 ChatGPT류 API로 전송 -> 돌려받은 결과를 TTS 기능으로 스피커로 출력
그런데, ChatGPT에 접속해서 확인해 보니 가입할 때 제공됐던 API 사용 비용이 기간 만료로 0원이 됐더군요. 이게 계속 쓸거도 아니고 재미로 하던거라 굳이 유료로 해서 해볼 필요는 없어서 그만 두려고 하다가 이런 저런 검색을 통해 어떤 분이 구글의 Bard(지금은 Gemini로 이름이 변경됐죠)를 사용할 수 있게 파이썬 라이브러리를 만들어 놓은 Bard-API 라는 것을 찾을 수 있었습니다. 그래서, 이를 사용해서 간단히 구현을 했습니다. 이 라이브러리가 Bard에서 정식으로 제공하는 API를 사용하는 것이 아니고(유료건 무료건 해당 시점에 Bard는 API를 제공하지 않고 있었습니다), 브라우저가 접근하듯이 하는 방식을 쓰는 방식이어서 인증 관련된 토큰 값을 입력해 주어야 하는데 이게 자주 인증이 풀리는 문제가 있어서 계속 사용하는 것은 무리가 있어 보였습니다.
이 기능은 추가하고 나서 한동안 재밌게 사용하기는 했습니다.
마무리
한동안 재밌게 코딩을 했기 때문에 여세를 몰아서 가전 기기들과의 연계까지도 생각을 해 봤습니다. 저희집 대부분의 가전제품이 엘지 제품인데 엘지는 ThinQ라고해서 모바일 앱을 통해 가전기기들을 제어할 수 있게 해 줍니다. 그래서, 그게 가능하다면 API도 제공하지 않을까 찾아봤습니다. 그런데, 공식적으로는 B to B로만 제공하고 개인에게는 제공하지 않고 있더군요. 이런 글도 찾기는 했는데, 손이 많이 가 보여서 더 이상 진행은 하지 않았습니다. 다만, 해당 글을 보다가 Homebridge라는 것을 알게 됐습니다. 가정에서 기기들과 연계된 웹 사이트를 원하시는 분들은 한 번 살펴보셔도 좋을 거 같습니다. 간단히 한 번 설치해서 실행해 봤는데, 완성도도 매우 높고 괜찮아 보였습니다.
ChatGPT를 활용한 코딩
이번에 시범 삼아 ChatGPT를 코딩에 활용해 봤습니다. 나름 만족스러웠고 충분히 보조재로서 사용 가능하다고 느꼈습니다. 다만, 알려주는 결과가 제대로 동작하지 않을 때가 문제인데 이런 경우에 코딩 초보라면 쉽지 않겠다는 생각이 들었습니다.
프로토타입이나 전체적인 윤곽을 잡을 때 굉장히 좋지 않을까 생각되며 계속적으로 더 발전할테니 앞으로가 더 기대됩니다.
현재 Voiceto(이름을 이렇게 붙였습니다 ^^)는 거실에 설치해 두고 필요할 때마다 잘 사용하고 있습니다.
PS.
소스코드는 github에 올리고 공개하려고 했는데, 개발하다 중단한 부분이나, 외부에 노출하면 안되는 API 키 같은 것을 아직 정리 못해 공개하지 못했습니다. 추후 정리가 되면 공개해 보겠습니다.
'생활코딩' 카테고리의 다른 글
라즈베리파이 - Docker Registry 서버 설치 (0) | 2024.10.22 |
---|---|
라즈베리파이 - nginx - ModSecurity 설치 (3) | 2024.10.20 |
라즈베리파이 - Git 서버 설치하기 (Gitea) (2) | 2024.10.17 |
라즈베리파이 JDK 설치 (0) | 2024.10.14 |
라즈베리파이 MySQL 설치 (2) | 2024.09.30 |