Edge-TTS 한국어 음성 생성 시 발음 오류와 자막 싱크 문제 해결 방법
유튜브 쇼츠 자동화 시스템을 구축하면서 TTS 엔진 선택이 생각보다 큰 고민이었다.
ElevenLabs는 품질이 좋지만 비용이 발생한다. OpenAI TTS도 마찬가지다. 무료로 쓸 수 있으면서 한국어 품질이 괜찮은 걸 찾다가 Edge-TTS를 선택했다. Microsoft Edge 브라우저의 음성 합성 기술을 무료로 사용할 수 있는 라이브러리다.
실제로 써보니 한국어 품질은 생각보다 훨씬 좋았다. 다만 두 가지 문제가 있었다. 영문 혼재 시 발음 오류, 그리고 자막 싱크 불일치다. 이 글에서는 UGREEN DXP4800PLUS NAS Docker 환경에서 Edge-TTS를 설치하고, 실제로 겪은 문제와 해결 방법을 정리한다.
왜 Edge-TTS를 선택했는가
TTS 엔진 선택 기준은 세 가지였다.
- 무료 또는 저비용
- 한국어 품질
- Python 연동 가능
비교 결과:
| TTS | 비용 | 한국어 품질 |
|---|---|---|
| ElevenLabs | 유료 | 최상 |
| OpenAI TTS | 유료 | 상 |
| Clova | 유료 | 상 |
| Edge-TTS | 무료 | 중상 |
| gTTS | 무료 | 중 |
Edge-TTS는 무료이면서 한국어 품질이 실용적인 수준이었다. 특히 ko-KR-SunHiNeural 목소리는 자연스러운 억양으로 쇼츠 자동화에 충분히 사용 가능했다.
실제로 생성한 음성을 유튜브 쇼츠 테스트 영상에 적용해 보니 TTS 특유의 기계음이 완전히 사라진 것은 아니었지만, 무료 서비스라는 점을 고려하면 충분히 실사용 가능한 수준이었다.
특히 30~40초 길이의 AI 자동화 관련 쇼츠에서는 시청자들이 TTS라는 사실을 거의 인지하지 못했다.
NAS Docker 환경에서 Edge-TTS 설치
UGREEN DXP4800PLUS NAS에 SSH로 접속한 후 설치한다.
pip3 install edge-tts --break-system-packages설치 확인:
edge-tts --version
# edge-tts 7.2.8사용 가능한 한국어 목소리 확인:
bash
edge-tts --list-voices | grep ko-KR주요 한국어 목소리:
ko-KR-SunHiNeural(여성, 자연스러운 억양)ko-KR-InJoonNeural(남성, 안정적인 톤)
기본 음성 생성
Python에서 사용하는 기본 방법이다.
import asyncio
import edge_tts
async def generate_tts(text: str, output_path: str):
tts = edge_tts.Communicate(text, "ko-KR-SunHiNeural")
await tts.save(output_path)
asyncio.run(generate_tts("안녕하세요. 테스트입니다.", "/tmp/test.mp3"))명령줄에서 바로 생성하는 방법:
edge-tts \
--voice "ko-KR-SunHiNeural" \
--text "안녕하세요 테스트입니다" \
--write-media /tmp/test.mp3실제로 겪은 문제 ① 영문 혼재 시 발음 오류
쇼츠 자동화 대본에는 영문이 자주 섞인다.
"ChatGPT vs Claude 비교"
"YouTube Data API 쿼터 절약"
"n8n으로 자동화하기"이걸 그대로 TTS에 넣으면 발음이 어색해진다.
vs → "브이에스" 또는 "브스"
API → "에이피아이" 또는 이상한 발음
GPT → "지피티" 또는 "그피트"
n8n → 읽지 못함
% → 무시하거나 "퍼센트"
$ → 무시하거나 "달러"해결 방법: TTS 전처리 규칙 적용
def preprocess_for_tts(text: str) -> str:
replacements = {
" vs ": " 대 ",
" VS ": " 대 ",
"ChatGPT": "챗지피티",
"GPT": "지피티",
"API": "에이피아이",
"n8n": "엔에잇엔",
"NAS": "나스",
"Docker": "도커",
"FastAPI": "패스트에이피아이",
"%": "퍼센트",
"$": "달러",
"#": "",
}
for old, new in replacements.items():
text = text.replace(old, new)
return text전처리 후 TTS 생성:
raw_text = "ChatGPT vs Claude 비교, API 쿼터는 10,000유닛"
clean_text = preprocess_for_tts(raw_text)
# "챗지피티 대 Claude 비교, 에이피아이 쿼터는 10,000유닛"
await generate_tts(clean_text, "/tmp/output.mp3")실제로 겪은 문제 ② 자막 싱크 불일치
처음에는 텍스트를 줄 수로 균등 분할해서 SRT 자막을 만들었다.
# 초기 방식 - 문제 있음
sentences = text.split("\n")
per = total_duration / len(sentences)
# 각 문장에 균등하게 시간 배분
문제는 문장 길이가 달라도 같은 시간이 배분된다는 것이었다.
"안녕" → 0.5초면 충분한데 5초 배분
"정말 길고 복잡한 문장입니다" → 5초가 필요한데 0.5초 배분결과적으로 음성과 자막이 전혀 맞지 않았다.
해결 방법: Edge-TTS --write-subtitle 옵션 사용
Edge-TTS는 음성 생성 시 정확한 타임스탬프가 포함된 자막 파일을 함께 생성할 수 있다.
edge-tts \
--voice "ko-KR-SunHiNeural" \
--text "안녕하세요 테스트입니다" \
--write-media /tmp/output.mp3 \
--write-subtitle /tmp/output.vttWEBVTT
00:00:00.000 --> 00:00:01.250
안녕하세요
00:00:01.250 --> 00:00:02.800
테스트입니다
실제 발화 타이밍 그대로 자막이 생성된다. 균등 분할 방식과 비교하면 싱크 정확도가 완전히 다르다.
Python에서 사용하는 방법:
import asyncio
import edge_tts
async def generate_tts_with_subtitle(text: str, audio_path: str, subtitle_path: str):
tts = edge_tts.Communicate(text, "ko-KR-SunHiNeural")
with open(audio_path, "wb") as audio_file, \
open(subtitle_path, "w", encoding="utf-8") as sub_file:
async for chunk in tts.stream():
if chunk["type"] == "audio":
audio_file.write(chunk["data"])
elif chunk["type"] == "WordBoundary":
# 단어별 타임스탬프 활용 가능
pass
await tts.save(audio_path)
asyncio.run(generate_tts_with_subtitle(
"안녕하세요 테스트입니다",
"/tmp/output.mp3",
"/tmp/output.vtt"
))쇼츠 자동화 파이프라인 적용
현재 운영 중인 유튜브 쇼츠 자동화 파이프라인에서 Edge-TTS는 이 위치에 있다.
YouTube API 트렌드 수집
↓
AI 언어 모델 대본 생성
↓
TTS 전처리 (발음 오류 수정)
↓
Edge-TTS 음성 생성 + VTT 자막
↓
FFmpeg 영상 합성
↓
drafts 폴더 저장실제 운영 코드 구조:
async def generate_video(trend_data: dict):
# 1. 대본 전처리
raw_script = trend_data["full_text"]
clean_script = preprocess_for_tts(raw_script)
# 2. TTS + 자막 생성
await generate_tts_with_subtitle(
clean_script,
"/tmp/output.mp3",
"/tmp/output.vtt"
)
# 3. FFmpeg 합성
compose_video("/tmp/output.mp3", "/tmp/output.vtt")마무리
Edge-TTS는 무료 TTS 중에서 한국어 품질이 가장 실용적인 수준이다. 다만 두 가지는 반드시 고려해야 한다.
첫째, 영문 혼재 시 전처리 규칙이 필요하다. vs, API, GPT 같은 용어는 미리 한국어로 변환해야 자연스러운 발음이 나온다.
둘째, 자막 싱크는 균등 분할 방식이 아니라 --write-subtitle 옵션으로 실제 발화 타이밍 기반으로 생성해야 한다.
이 두 가지만 해결하면 쇼츠 자동화에 충분히 사용 가능한 품질이 나온다.

댓글
댓글 쓰기