Microsoft Edgeμ κ°λ ₯ν Text-to-Speech μμ§μ νμ©ν μΉ κΈ°λ° μμ± ν©μ± μλΉμ€μ λλ€.
- 75κ° μ΄μμ μΈμ΄ μ§μ
- 450κ° μ΄μμ κ³ νμ§ μμ± μ 곡
- μλ μΈμ΄ κ°μ§ κΈ°λ₯
- μ±λ³λ³ μμ± μ ν (κΈ°λ³Έ: μ¬μ± μμ±)
- μλ μ‘°μ : -50% ~ +200%
- μμ‘° μ‘°μ : -50Hz ~ +50Hz
- λ³Όλ₯¨ μ‘°μ : -50% ~ +200%
- μ€μκ° μμ± μν μ¬μ
- μΌλ° ν μ€νΈ μμ± ν©μ± (μ΅λ 5,000μ)
- κΈ΄ ν μ€νΈ μ²ν¬ λΆν μ²λ¦¬
- SSML μ§μμΌλ‘ κ³ κΈ μμ± μ μ΄
- μλ ν μ€νΈ μ 리 λ° μ΅μ ν
- μμ± ν©μ± νμ€ν 리 κ΄λ¦¬
- μ¬μ© ν΅κ³ λ° λΆμ
- ν μ€νΈ μ¬μ¬μ© κΈ°λ₯
- λ°μν λͺ¨λ UI
βββββββββββββββ ββββββββββββββββ βββββββββββββββ
β React β β Nginx β β FastAPI β
β Frontend βββββΊβ Proxy βββββΊβ Backend β
β (Vite) β β (/edge-api)β β (Port 3701) β
βββββββββββββββ ββββββββββββββββ βββββββββββββββ
β
βΌ
βββββββββββββββββββ
β Microsoft β
β Edge TTS API β
βββββββββββββββββββ
- Python 3.8+
- FastAPI - κ³ μ±λ₯ API μλ²
- edge-tts 6.1.12 - Microsoft Edge TTS λΌμ΄λΈλ¬λ¦¬
- Uvicorn - ASGI μλ²
- Pydantic - λ°μ΄ν° κ²μ¦
- React 18 - μ¬μ©μ μΈν°νμ΄μ€
- Vite - λΉλ λꡬ
- Axios - HTTP ν΄λΌμ΄μΈνΈ
- CSS3 - λͺ¨λ μ€νμΌλ§
- Nginx - 리λ²μ€ νλ‘μ & μ μ νμΌ μλΉ
- Systemd - μλΉμ€ κ΄λ¦¬
- Ubuntu Linux - μλ² νκ²½
git clone https://github.com/purestory/edgetts.git
cd edgetts# Python κ°μνκ²½ μμ± python3 -m venv .venv source .venv/bin/activate # μμ‘΄μ± μ€μΉ pip install -r requirements.txt
cd frontend
npm install
npm run build# EdgeTTS μλΉμ€ νμΌ λ³΅μ¬ sudo cp edgetts.service /etc/systemd/system/ sudo systemctl daemon-reload sudo systemctl enable edgetts.service sudo systemctl start edgetts.service
# /etc/nginx/sites-available/your-domain location = /edgetts { return 301 /edgetts/; } location ^~ /edgetts/ { alias /path/to/edgetts/frontend/dist/; index index.html; try_files $uri $uri/ /edgetts/index.html; location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ { expires 1y; add_header Cache-Control "public, immutable"; } } location ^~ /edge-api/ { rewrite ^/edge-api/(.*)$ /1γγ« break; proxy_pass http://localhost:3701; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_buffering off; client_max_body_size 50G; }
- λΈλΌμ°μ μμ
http://your-domain/edgetts/μ μ - ν μ€νΈ μ λ ₯ μμμ ν©μ±ν ν μ€νΈ μ λ ₯
- μνλ μΈμ΄μ μμ± μ ν
- μλ, μμ‘°, λ³Όλ₯¨ μ‘°μ (μ νμ¬ν)
- "μμ± ν©μ±" λ²νΌ ν΄λ¦
- μμ±λ μμ± μ¬μ λ° λ€μ΄λ‘λ
curl -X POST "http://your-domain/edge-api/synthesize" \ -H "Content-Type: application/json" \ -d '{ "text": "μλ νμΈμ! EdgeTTSμ λλ€.", "voice": "ko-KR-SunHiNeural", "rate": "+0%", "pitch": "+0Hz", "volume": "+0%" }' \ --output audio.mp3
curl "http://your-domain/edge-api/languages"curl "http://your-domain/edge-api/voices/language/ko"edgetts/
βββ backend/ # FastAPI λ°±μλ
β βββ app.py # λ©μΈ μ ν리μΌμ΄μ
β βββ ...
βββ frontend/ # React νλ‘ νΈμλ
β βββ src/
β β βββ App.jsx # λ©μΈ μ»΄ν¬λνΈ
β β βββ main.jsx # μνΈλ¦¬ ν¬μΈνΈ
β β βββ index.css # μ€νμΌ
β βββ dist/ # λΉλλ νμΌ
β βββ package.json
β βββ vite.config.js
βββ samples/ # μμ± μν νμΌ
βββ tmp/ # μμ νμΌ
βββ .venv/ # Python κ°μνκ²½
βββ requirements.txt # Python μμ‘΄μ±
βββ edgetts.service # Systemd μλΉμ€ νμΌ
βββ generate_samples.py # μν μμ± μ€ν¬λ¦½νΈ
βββ README.md
POST /synthesize- μΌλ° ν μ€νΈ μμ± ν©μ±POST /synthesize-long- κΈ΄ ν μ€νΈ μ²ν¬ λΆν μ²λ¦¬POST /voice-sample/{voice_name}- μμ± μν μμ±
GET /languages- μ§μ μΈμ΄ λͺ©λ‘GET /voices- μ 체 μμ± λͺ©λ‘GET /voices/language/{code}- νΉμ μΈμ΄ μμ± λͺ©λ‘POST /detect-language- ν μ€νΈ μΈμ΄ μλ κ°μ§
GET /health- μλΉμ€ μν νμΈDELETE /cleanup- μμ νμΌ μ 리GET /samples/stats- μν νμΌ ν΅κ³
μ λ ₯λ ν μ€νΈλ₯Ό λΆμνμ¬ μΈμ΄λ₯Ό μλμΌλ‘ κ°μ§νκ³ μ μ ν μμ±μ μΆμ²ν©λλ€.
κΈ΄ ν μ€νΈλ₯Ό μλμΌλ‘ μ μ ν ν¬κΈ°λ‘ λΆν νμ¬ μ²λ¦¬νκ³ νλμ μ€λμ€ νμΌλ‘ κ²°ν©ν©λλ€.
Blob URL μμ±κ³Ό ν΄μ λ₯Ό μ μ ν κ΄λ¦¬νμ¬ λ©λͺ¨λ¦¬ λμλ₯Ό λ°©μ§ν©λλ€.
μμ± λͺ©λ‘κ³Ό μν νμΌμ μΊμνμ¬ λΉ λ₯Έ μλ΅ μλλ₯Ό μ 곡ν©λλ€.
# ν¬νΈ μ€μ (κΈ°λ³Έ: 3701) export PORT=3701 # μμ νμΌ λλ ν 리 export TEMP_DIR="/home/purestory/edgetts/tmp" # μν νμΌ λλ ν 리 export SAMPLE_DIR="/home/purestory/edgetts/samples"
MAX_GENERATED_FILES: μ΅λ μμ± νμΌ μ (κΈ°λ³Έ: 100κ°)KEEP_GENERATED_FILES: μ 리 μ μ μ§ν νμΌ μ (κΈ°λ³Έ: 50κ°)
1. Blob URL μλ¬
// λΈλΌμ°μ μ½μμμ μ€ν localStorage.removeItem('edgetts_history'); localStorage.removeItem('edgetts_stats'); location.reload();
2. μμ± ν©μ± μ€ν¨
- μλΉμ€ μν νμΈ:
sudo systemctl status edgetts.service - λ‘κ·Έ νμΈ:
sudo journalctl -u edgetts.service -f
3. Nginx μ€μ λ¬Έμ
- μ€μ ν
μ€νΈ:
sudo nginx -t - μλΉμ€ μ¬μμ:
sudo systemctl reload nginx
- CPU: 2μ½μ΄ μ΄μ
- RAM: 4GB μ΄μ
- μ μ₯곡κ°: 10GB μ΄μ (μν νμΌ ν¬ν¨)
- λ€νΈμν¬: 1Mbps μ΄μ
- μμ± μν μ¬μ μμ±μΌλ‘ μλ΅ μλ ν₯μ
- Nginx μμΆ λ° μΊμ μ€μ
- μ κΈ°μ μΈ μμ νμΌ μ 리
- νλ‘μΈμ€ λͺ¨λν°λ§ λ° μλ μ¬μμ
- Fork νλ‘μ νΈ
- Feature λΈλμΉ μμ± (
git checkout -b feature/AmazingFeature) - λ³κ²½μ¬ν μ»€λ° (
git commit -m 'Add some AmazingFeature') - λΈλμΉμ Push (
git push origin feature/AmazingFeature) - Pull Request μμ±
μ΄ νλ‘μ νΈλ MIT λΌμ΄μ μ€ νμ λ°°ν¬λ©λλ€. μμΈν λ΄μ©μ LICENSE νμΌμ μ°Έμ‘°νμΈμ.
- Microsoft Edge TTS - ν΅μ¬ μμ± ν©μ± μμ§
- FastAPI - κ³ μ±λ₯ API νλ μμν¬
- React - μ¬μ©μ μΈν°νμ΄μ€ λΌμ΄λΈλ¬λ¦¬
- μ΄μ 리ν¬ν : GitHub Issues
- κΈ°λ₯ μμ²: GitHub Discussions
β μ΄ νλ‘μ νΈκ° λμμ΄ λμ ¨λ€λ©΄ Starλ₯Ό λλ¬μ£ΌμΈμ!