소개
시도하고자 했던 것과 그 이유를 알려주세요.
파이썬에서 제공하는 대표적인 TTS 툴을 파악
진행 방법
어떤 도구를 사용했고, 어떻게 활용하셨나요?
퍼플렉시티와 클로드를 통해 파이썬이 제공하는 대표적인 TTS를 검색
Tip: 사용한 프롬프트 전문을 꼭 포함하고, 내용을 짧게 소개해 주세요.
Tip: 활용 이미지나 캡처 화면을 꼭 남겨주세요.
gTTS는 구글에서 제공하는 라이브러리로 가장 대표적인 서비스
코드는 사용하기 간단하나,
영어, 한국어 음성이 각각 1개,
영어 음성은 좋은 편이나
한국어 음질 부자연스러운게 단점
pyttsx3는 고품질 wav 파일을 지원
영어 음성은 보통 수준이고
한국어 음성이 좀 많이 부족한 편
EdgeTTS는 마이크로소프트사의 서비스로
고급 음성 기술을 기본으로 자연스러운 목소리가 특징
영어는 남녀 다양한 음성을 제공하며
한국어 음성도 품질 좋은편이나, 2개의 목소리만 제공하는 점이 다소 아쉬움
Coqui는 오늘 처음 발견
고급 음성인 WAV 파일을 제공하고
영어 음성도 고품질, 자연스럽다고 하여 기대
음질 확인 결과 영어 한글 둘다 수준에 못 미침
(내용 입력)
결과와 배운 점
2가지 이상의 검색 툴을 통해 TTS를 찾아야 한다는 점
EdgeTTS는 검색에서 처음 발견했는데 고품질 음성
과정 중에 어떤 시행착오를 겪었나요?
무료 및 유로 서비스에서 대표적인 것을 비교 분석 필요
앞으로의 계획이 있다면 들려주세요.
CoquiTTS도 처음 봤는데 좋은 서비스라하니 검증 필요
유료 서비스 비교 : API 사용
네이버, 구글, 아마존 등 클라우드 유료 서비스
대표적인 AI 음성 서비스 Elevenlaps
https://youtu.be/upooEg7AvCc(일레븐랩스 TTS)
일레븐랩스는 다양한 음성, 자신 목소리 합성 등 기능이 좋은데,
한번 해본 결과, 실시간 스트리밍에서 딜레이 문제 발생, 오류 개선 필요
도움 받은 글 (옵션)
참고한 지피터스 글이나 외부 사례를 알려주세요.
EdgeTTS 영어 단어장 코드(파이썬)
# 기본 패키지
edge-tts==6.1.9
openpyxl==3.1.2
Pillow==10.1.0
numpy==1.26.2
moviepy==1.0.3
opencv-python==4.8.1.78
pygame==2.5.2
pydub==0.25.1
soundfile==0.12.1
playsound==1.3.0
# 오디오 처리
torch==2.1.1
주요 패키지 설명:
edge-tts: Microsoft Edge TTS 음성 합성
openpyxl: 엑셀 파일 처리
Pillow: 이미지 처리
numpy: 수치 연산
moviepy: 비디오 생성 및 편집
opencv-python: 이미지/비디오 처리
pygame: 오디오 재생
pydub: 오디오 파일 변환
soundfile: 오디오 파일 처리
playsound: 오디오 재생
torch: 딥러닝 프레임워크
import asyncio import edge_tts from edge_tts import list_voices import wave import os from pathlib import Path import openpyxl import time from datetime import datetime async def main(): try: # 음성 설정 eng_voice = "en-US-SteffanNeural" # 영어 음성 kor_voice = "ko-KR-SunHiNeural" # 한글 음성 eng_speed = 1.2 # 영어 1.2배속 kor_speed = 1.2 # 한국어 1.2배속 # 사용 가능한 음성 목록 출력 voices = await list_voices() print("\n사용 가능한 음성:") print("\n영어 음성:") english_voices = [voice for voice in voices if voice["Locale"].startswith("en")] for voice in english_voices: print(f"- {voice['ShortName']}: {voice['FriendlyName']}") print("\n한국어 음성:") korean_voices = [voice for voice in voices if voice["Locale"].startswith("ko")] for voice in korean_voices: print(f"- {voice['ShortName']}: {voice['FriendlyName']}") print("\n현재 설정:") print(f"영어 음성: {eng_voice}") print(f"한글 음성: {kor_voice}") print(f"재생 속도: 영어 {eng_speed}배속, 한국어 {kor_speed}배속") # 스크립트 파일의 디렉토리 경로 가져오기 script_dir = Path(os.path.dirname(os.path.abspath(__file__))) excel_path = script_dir / 'words.xlsx' # 스크립트와 같은 디렉토리의 엑셀 파일 if not os.path.exists(excel_path): raise FileNotFoundError(f"엑셀 파일을 찾을 수 없습니다: {excel_path}") workbook = openpyxl.load_workbook(excel_path) sheet = workbook.active # A2:B11 범위의 데이터 읽기 words = [] for row in range(2, 12): # 2부터 11까지 english = sheet[f'A{row}'].value korean = sheet[f'B{row}'].value if english and korean: # None 값 체크 # 한글 띄어쓰기 정리 korean = korean.replace(" ", "") # 모든 공백 제거 korean = korean.strip() # 앞뒤 공백 제거 words.append((english, korean)) if not words: raise ValueError("엑셀 파일에서 단어를 읽어올 수 없습니다.") print("\n읽어온 단어 목록:") print("\n번호 영어 한글 시간") print("-" * 60) # TTS 설정 for i, (english, korean) in enumerate(words, 1): # 영어 음성 생성 (영어 음성으로) communicate = edge_tts.Communicate( text=english, voice=eng_voice, # 영어 음성 rate=f"+{int((eng_speed-1)*100)}%" # 영어 속도 조절 ) # 영어 WAV 파일 생성 eng_file = script_dir / f"output_eng_{i}.wav" if os.path.exists(eng_file): os.remove(eng_file) await communicate.save(str(eng_file)) # 한글 음성 생성 (한글 음성으로) communicate = edge_tts.Communicate( text=korean, voice=kor_voice, # 한글 음성 rate=f"+{int((kor_speed-1)*100)}%" # 한글 속도 조절 ) # 한글 WAV 파일 생성 kor_file = script_dir / f"output_kor_{i}.wav" if os.path.exists(kor_file): os.remove(kor_file) await communicate.save(str(kor_file)) # 한글 문자열의 실제 표시 길이 계산 (한글은 2칸, 영문/숫자는 1칸 차지) korean_display_length = sum(2 if ord(c) > 127 else 1 for c in korean) padding = 40 - (28 + korean_display_length) # 28은 고정된 부분의 길이 (번호4 + 공백2 + 영단어20 + 공백2) padding = max(padding, 1) # 최소 1칸의 공백 보장 # 로그 출력 및 재생 current_time = datetime.now().strftime("%H:%M:%S.%f")[:-3] # 밀리초까지 표시 print(f"{i:4d} {english:20} {korean}{' ' * padding}{current_time}") os.system(f"afplay {eng_file}") os.system(f"afplay {kor_file}") # 임시 파일 삭제 os.remove(eng_file) os.remove(kor_file) except FileNotFoundError as e: print(f"\n파일 오류: {e}") print("스크립트 위치:", script_dir) except Exception as e: print(f"\n에러가 발생했습니다: {str(e)}") # 임시 파일 정리 for f in ['eng_file', 'kor_file']: if f in locals() and os.path.exists(locals()[f]): os.remove(locals()[f]) if __name__ == "__main__": asyncio.run(main())