한줄요약: gemini-3.1-flash-tts-preview는 200개 이상의 인라인 오디오 태그로 문장 중간에 감정·속도·톤을 즉시 전환할 수 있는 구글 최초의 표현형 TTS 모델로, 30개 프리빌트 보이스와 70개 이상 언어를 지원합니다.
기존 TTS와 뭐가 다른가요?
기존 TTS 모델은 SSML(XML 태그 기반)로 속도나 쉼표 정도만 조절할 수 있었고, 감정 표현은 사실상 불가능했습니다. ElevenLabs 같은 서비스가 비싼 값에 팔던 "연기하는 목소리"를 API 한 줄로 만들 수 있게 된 게 이 모델의 핵심입니다.
기존 SSML 방식
<speak><prosody rate="slow">천천히 말합니다</prosody></speak>
gemini-3.1-flash-tts 방식
[sad] 오늘은 정말 힘든 하루였어요. [pause=1.0] [whispering] 그래도 괜찮아질 거야.
XML 없이 자연어 태그로 감정을 직접 쓰는 방식입니다.
핵심 스펙:
모델 ID gemini-3.1-flash-tts-preview
출력 포맷 PCM 24kHz / 16-bit mono
지원 언어 70개+ (한국어 포함, 자동 감지)
프리빌트 보이스 30개 (천문학적 명칭 — Kore, Despina 등)
오디오 태그 200개+ 인라인 태그 지원
멀티스피커 최대 2명 동시 지원
컨텍스트 윈도우 32K 토큰
SynthID 워터마크 모든 출력에 자동 적용
가격 인풋 $1.00/1M 토큰 · 아웃풋 $20.00/1M 토큰 (약 $0.03/분)
설치 및 기본 단일 화자 생성
pip install google-genai
export GEMINI_API_KEY="your-api-key"
import wave
from google import genai
from google.genai import types
def save_wave(filename, pcm, channels=1, rate=24000, sample_width=2):
with wave.open(filename, "wb") as wf:
wf.setnchannels(channels)
wf.setsampwidth(sample_width)
wf.setframerate(rate)
wf.writeframes(pcm)
client = genai.Client()
response = client.models.generate_content(
model="gemini-3.1-flash-tts-preview",
contents="Say cheerfully: 안녕하세요, 오늘도 좋은 하루 되세요!",
config=types.GenerateContentConfig(
response_modalities=["AUDIO"],
speech_config=types.SpeechConfig(
voice_config=types.VoiceConfig(
prebuilt_voice_config=types.PrebuiltVoiceConfig(
voice_name="Kore", # 프리빌트 보이스 지정
)
)
),
)
)
audio_data = response.candidates[0].content.parts[0].inline_data.data
save_wave("output.wav", audio_data)
print("저장 완료: output.wav")
오디오 태그 — 감정을 텍스트에 직접 심는 법
이 모델의 핵심 기능입니다. 대괄호 안에 감정·행동·페이싱을 쓰면 해당 지점에서 음성 스타일이 바뀝니다.
태그 카테고리별 예시:
감정 표현
[happy] [sad] [angry] [excited]
[nervous] [bored] [surprised] [confused]
[disappointed] [proud] [scared] [relieved]
전달 방식
[whispering] [shouting] [laughing] [crying]
[sighing] [singing] [asmr] [dramatic]
페이싱·리듬
[pause=0.5] [pause=1.0] [slowly] [quickly]
[emphasizing] [monotone] [breathless]
자유 형식 (자연어 그대로)
[like a TV announcer]
[reluctantly]
[with a sigh of relief]
[excitedly, like just won a prize]
실전 코드 — 오디오 태그 적용:
script = """
[excited] 드디어 출시됐습니다! [pause=0.5]
[slowly] 오늘 소개해드릴 건 Gemini 3.1 Flash TTS입니다.
[whispering] 사실 이 기능, 저도 처음 봤을 때 깜짝 놀랐어요.
[pause=1.0]
[dramatically] 200개 이상의 오디오 태그. [pause=0.5] 70개 이상의 언어. [pause=0.5] 단일 API 엔드포인트.
[cheerful] 지금 바로 써보세요!
"""
response = client.models.generate_content(
model="gemini-3.1-flash-tts-preview",
contents=script,
config=types.GenerateContentConfig(
response_modalities=["AUDIO"],
speech_config=types.SpeechConfig(
voice_config=types.VoiceConfig(
prebuilt_voice_config=types.PrebuiltVoiceConfig(
voice_name="Charon", # 남성 보이스
)
)
),
)
)
audio_data = response.candidates[0].content.parts[0].inline_data.data
save_wave("tagged_output.wav", audio_data)
태그 사용 팁:
→ 태그는 문장 앞에 놓을 때 가장 일관성 있게 적용됨
→ [pause=N] 은 초 단위 (0.1 ~ 3.0 범위 권장)
→ 창의적인 자유 형식 태그 ([like dracula] 등)는 프로덕션 전에 반드시 테스트
→ 태그가 텍스트로 읽힐 수 있으므로 배포 전 샘플 확인 필수
→ 스타일 프롬프트, 본문 내용, 태그 방향을 일치시킬수록 품질이 높아짐
멀티스피커 — 두 화자가 대화하는 오디오
팟캐스트, 대화 예시 음성, 인터뷰 형식 콘텐츠에 쓸 수 있습니다. 스피커 이름을 프롬프트에 명시하고 MultiSpeakerVoiceConfig로 각 화자에 목소리를 매핑합니다.
dialogue = """
진행자: [excited] 오늘 게스트는 정말 특별하신 분입니다!
게스트: [laughing] 과찬이세요. [pause=0.3] 저도 이 자리가 정말 기대됐어요.
진행자: [curious] 최근 프로젝트에 대해 좀 더 이야기해주시겠어요?
게스트: [slowly, thoughtfully] 네, 사실 처음엔 반신반의했는데요. [pause=0.5] [excited] 결과가 정말 놀라웠습니다.
"""
response = client.models.generate_content(
model="gemini-3.1-flash-tts-preview",
contents=dialogue,
config=types.GenerateContentConfig(
response_modalities=["AUDIO"],
speech_config=types.SpeechConfig(
multi_speaker_voice_config=types.MultiSpeakerVoiceConfig(
speaker_voice_configs=[
types.SpeakerVoiceConfig(
speaker="진행자",
voice_config=types.VoiceConfig(
prebuilt_voice_config=types.PrebuiltVoiceConfig(
voice_name="Kore" # 여성 보이스
)
)
),
types.SpeakerVoiceConfig(
speaker="게스트",
voice_config=types.VoiceConfig(
prebuilt_voice_config=types.PrebuiltVoiceConfig(
voice_name="Charon" # 남성 보이스
)
)
),
]
)
),
)
)
audio_data = response.candidates[0].content.parts[0].inline_data.data
save_wave("dialogue_output.wav", audio_data)
주의: speaker 이름은 프롬프트에 쓴 이름과 정확히 일치해야 합니다. 대소문자도 구분됩니다.
스타일 프롬프트 — 전체 톤을 한 번에 설정
태그 없이 앞에 프롬프트만 붙여서 전체 배달 스타일을 지정하는 방법입니다.
# "Say cheerfully:" 형식
response = client.models.generate_content(
model="gemini-3.1-flash-tts-preview",
contents="Narrate dramatically, like a documentary: 2026년, AI는 인간의 목소리를 갖기 시작했습니다.",
config=types.GenerateContentConfig(
response_modalities=["AUDIO"],
speech_config=types.SpeechConfig(
voice_config=types.VoiceConfig(
prebuilt_voice_config=types.PrebuiltVoiceConfig(
voice_name="Fenrir"
)
)
),
)
)
오디오 태그와 스타일 프롬프트를 동시에 쓸 수 있습니다. 스타일 프롬프트로 전체 톤을 잡고, 태그로 특정 지점만 전환하는 방식이 가장 효과적입니다.
PCM → WAV / MP3 변환
출력이 PCM 전용이라 그대로 재생은 안 됩니다. WAV로 저장하거나 MP3로 변환해야 합니다.
import wave
import subprocess
# WAV 저장 (wave 내장 모듈)
def save_wave(filename, pcm, rate=24000):
with wave.open(filename, "wb") as wf:
wf.setnchannels(1) # mono
wf.setsampwidth(2) # 16-bit
wf.setframerate(rate)
wf.writeframes(pcm)
# MP3 변환 (ffmpeg 필요)
def pcm_to_mp3(pcm_data, output_path, rate=24000):
save_wave("temp.wav", pcm_data, rate)
subprocess.run([
"ffmpeg", "-y",
"-i", "temp.wav",
"-codec:a", "libmp3lame",
"-qscale:a", "2", # 고품질
output_path
], check=True)
import os
os.remove("temp.wav")
# 사용
audio_data = response.candidates[0].content.parts[0].inline_data.data
pcm_to_mp3(audio_data, "output.mp3")
주요 보이스 목록 (추천)
보이스명 특징
──────────────────────────────────────
Kore 차분한 여성, 내레이션·안내 음성에 적합
Despina 밝은 여성, 서비스·안내 멘트에 적합
Charon 낮은 남성, 다큐멘터리·권위 있는 발표
Fenrir 강한 남성, 드라마틱한 연출
Aoede 따뜻한 여성, 스토리텔링·오디오북
Leda 젊은 여성, 소셜 콘텐츠·캐주얼 대화
30개 전체 목록은 Google AI Studio에서 직접 미리 들어보고 고르는 걸 추천합니다.
⚠️ 현재 제약사항
→ Preview 상태 — GA 전 API 스펙 변경 가능
→ PCM 전용 출력 — MP3/OGG 직접 반환 없음, 후처리 필요
→ 최대 2명 화자 제한 (MultiSpeaker)
→ 스트리밍 미지원 — 실시간 음성 대화는 Live API 사용
→ 일부 자유형 태그는 텍스트로 읽힐 수 있음 → 배포 전 테스트 필수
→ SLA 보장 없음 (Preview 특성)
언제 Flash TTS vs Live API를 써야 하나요?
gemini-3.1-flash-tts-preview 사용
→ 스크립트가 정해진 나레이션, 오디오북, 팟캐스트
→ 감정 표현이 필요한 교육 콘텐츠
→ 2인 대화 형식 샘플 음성
→ 70개 이상 언어 지원이 필요한 현지화 프로젝트
Live API 사용
→ 실시간 음성 대화 (챗봇, 음성 어시스턴트)
→ 스트리밍이 필수인 인터랙티브 앱
→ 멀티모달 입력(마이크+화면)이 필요한 경우
✅ 오디오 태그는 쓸수록 품질이 달라집니다. 특히 [pause=N]과 감정 태그를 함께 쓰면 자연스러운 호흡이 생깁니다. Google AI Studio 플레이그라운드에서 먼저 태그 조합을 테스트하고 API로 넘어가는 게 시간을 아끼는 방법입니다.
❌ 프로덕션에 바로 붙이기엔 아직 Preview 상태입니다. 특히 자유형 태그([like dracula] 등)는 가끔 텍스트로 읽혀버리는 케이스가 있으니 출력 검증 로직을 꼭 넣어두세요.
'Gemini' 카테고리의 다른 글
| Gemini Omni Flash vs Veo 3.1 — 영상 생성 AI 어떤 걸 써야 하는지 헷갈리신다면 (0) | 2026.06.12 |
|---|---|
| 로봇, Physical AI — Gemini Robotics-ER 1.6 공간추론·기기판독 개발 가이드 (0) | 2026.06.12 |
| Deep Research API 실전 가이드 — Collaborative Planning, MCP, File Search 완전 연동 (0) | 2026.06.12 |
| RAG 파이프라인에 이미지·영상·오디오를 넣는 시대 — gemini-embedding-2 GA 완전 가이드 (0) | 2026.06.12 |
| 6월 18일이면 gemini 명령어가 멈춥니다 — Antigravity CLI 마이그레이션 실전 가이드 (0) | 2026.06.12 |