Java에서 오프라인 텍스트 음성 변환
Java 표준 라이브러리에는 끝내 음성 합성이 들어가지 않아서, 프로젝트들은 FreeTTS나 MaryTTS 같은 오래된 엔진(신경망 목소리 옆에서는 로봇처럼 들림)이나, 글자 수로 요금을 받고 모든 텍스트를 보는 클라우드 SDK에 기대 왔습니다.
이 가이드는 현대적인 대안을 보여 줍니다. 무료 SuperClonica 엔진을 로컬 HTTP 서버로 띄우고, Java 11 이상에 내장된 HttpClient로 호출합니다. 어떤 플랫폼에서든 자연스러운 목소리, 내 손에 남는 WAV 파일, 요청당 요금 없음.
Java에서 말하는 방법
엔진은 JVM 안에서 돌지 않습니다. Java 코드는 다른 서비스처럼 HTTP로 통신합니다.
- FreeTTS와 MaryTTS: 순수 Java에 오프라인이지만 신경망 목소리에 비하면 로봇 같음.
- 클라우드 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 내용입니다.
Java에서 호출
java.net.http, java.net.URI, java.nio.file을 쓰면 Java 11 이상에서 요청은 몇 줄이면 됩니다: var voice = Files.readString(Path.of("voice.json")); var json = "{\"text\": \"Java에서 안녕하세요!\", \"lang\": \"ko\", \"seed\": 7, \"voice\": " + voice + "}"; var request = HttpRequest.newBuilder(URI.create("http://localhost:8000/synthesize")).header("Content-Type", "application/json").POST(HttpRequest.BodyPublishers.ofString(json)).build(); HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofFile(Path.of("hello.wav"))); 응답은 곧바로 WAV 파일에 저장됩니다. 기본 목소리라면 파일 내용 대신 "voice": "F1"을 보내세요. 같은 텍스트, 목소리, seed면 항상 같은 소리가 나므로 반복되는 문구의 파일은 캐시하세요. 큰 프로젝트에서는 Jackson 같은 JSON 라이브러리로 요청을 깔끔하게 만드세요.
운영 환경 습관
HttpClient는 하나를 재사용하고 요청에 타임아웃을 두세요. 포트 8000을 그대로 인터넷에 열지 마세요. SUPERCLONICA_API_KEY를 설정해 Bearer 토큰으로 보내거나, 사설 네트워크 안에 두세요. 동시 요청이 많다면 SUPERCLONICA_LANES로 모델 사본을 늘리고, 내 하드웨어에서 측정하세요. 우리 테스트에서 짧은 문장은 RTX 5070 Ti에서 0.12초, CPU 4스레드에서 0.43초 걸렸습니다.