Go에서 오프라인 텍스트 음성 변환
Go 표준 라이브러리에는 음성 합성이 없고, 흔한 해법은 글자 수로 요금을 받는 클라우드 SDK나 운영체제의 로봇 같은 목소리를 감싼 래퍼입니다. 서비스, 봇, 명령줄 도구에는 둘 다 단점이 있습니다. 텍스트가 컴퓨터 밖으로 나가거나, 목소리가 시스템마다 바뀝니다.
이 가이드에서는 무료 SuperClonica 엔진을 로컬 HTTP 서버로 띄워 Go에서 호출하는 방법을 소개합니다. 자연스러운 목소리, 내 손에 남는 WAV 파일, 어떤 플랫폼에서든 평범한 net/http로.
Go에서 말하는 방법
자주 말하는 서비스라면 자체 음성 서버가 더 저렴하고 개인정보도 지킬 수 있습니다.
- 클라우드 SDK: 자연스러운 목소리지만 계정, 키, 글자 수 요금, 그리고 텍스트가 남의 서버로.
- 운영체제 목소리 래퍼: 오프라인이지만 로봇 같고 플랫폼마다 다름.
- SuperClonica: 자연스러운 목소리, 캐릭터·맞춤 목소리를 쓰는 로컬 HTTP 서버. Docker가 돌아가는 곳이면 오프라인으로.
- 31개 언어를 말합니다. 중국어는 아직 지원하지 않습니다.
목소리를 무료로 들어 보기
코드를 쓰기 전에 아무 목소리 페이지에서 30~100자 문장을 입력하고 언어를 고른 뒤 생성 버튼을 누르세요. 몇 초 만에 앱이 가질 수 있는 목소리를 들을 수 있습니다. 계정은 필요 없습니다.
음성 서버 시작
NVIDIA 그래픽 카드가 있으면 cuda 이미지로 더 빨라지지만, 필수는 아닙니다.
- 어떤 CPU에서든 서버 시작: docker run -d -p 8000:8000 -v superclonica-models:/models superclonica/superclonica:cpu.
- 첫 실행 때 Supertonic 3 모델(약 385MB)을 볼륨에 내려받습니다. 준비 여부는 GET /health로 확인합니다.
- POST /synthesize는 text, voice, lang, seed, normalize가 담긴 JSON을 받아 16비트 모노 WAV로 답합니다.
- voice는 기본 이름 M1~M5, F1~F5이거나 목소리 파일의 JSON 내용입니다.
Go에서 호출
표준 라이브러리의 bytes, io, net/http, os를 쓰면 요청은 몇 줄이면 됩니다: voice, _ := os.ReadFile("voice.json"); body := append([]byte(`{"text": "Go에서 안녕하세요!", "lang": "ko", "seed": 7, "voice": `), append(voice, '}')...); res, _ := http.Post("http://localhost:8000/synthesize", "application/json", bytes.NewReader(body)); defer res.Body.Close(); out, _ := os.Create("hello.wav"); defer out.Close(); io.Copy(out, res.Body) 실제 코드에서는 오류를 버리지 말고 처리하세요. 기본 목소리라면 파일 대신 "voice": "F1"을 보내세요. 같은 텍스트, 목소리, seed면 항상 같은 소리가 나므로 반복되는 문구의 파일은 캐시하세요.
운영 환경 습관
http.Client는 적절한 타임아웃을 둔 하나를 재사용하세요. 포트 8000을 그대로 인터넷에 열지 마세요. SUPERCLONICA_API_KEY를 설정해 Bearer 토큰으로 보내거나, 사설 네트워크 안에 두세요. 동시 요청이 많다면 SUPERCLONICA_LANES로 모델 사본을 늘리고, 내 하드웨어에서 측정하세요. 우리 테스트에서 짧은 문장은 RTX 5070 Ti에서 0.12초, CPU 4스레드에서 0.43초 걸렸습니다.