from flask import Flask, request, jsonify, send_file
import edge_tts
import asyncio
import tempfile
import os
app = Flask(__name__)
# ---------------------------
# Async helpers
# ---------------------------
async def get_voices_async():
voices = await edge_tts.list_voices()
return [
{
"short_name": v["ShortName"],
"locale": v["Locale"],
"gender": v["Gender"],
"display": f"{v['ShortName']} - {v['Locale']} ({v['Gender']})"
}
for v in voices
]
async def tts_async(text, voice, rate, pitch):
rate_str = f"{rate:+d}%"
pitch_str = f"{pitch:+d}Hz"
communicate = edge_tts.Communicate(
text=text,
voice=voice,
rate=rate_str,
pitch=pitch_str
)
tmp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3")
tmp_path = tmp_file.name
tmp_file.close()
await communicate.save(tmp_path)
return tmp_path
# ---------------------------
# Routes
# ---------------------------
@app.route("/", methods=["GET"])
def hello():
return """
Edge TTS Voices
🎙 Edge TTS Voices
"""
@app.route("/voices", methods=["GET"])
def voices():
voices = asyncio.run(get_voices_async())
grouped = {
"Male": {
"count": 0,
"voices": []
},
"Female": {
"count": 0,
"voices": []
}
}
for v in voices:
gender = v["gender"].lower()
if gender == "male":
grouped["Male"]["voices"].append(v)
grouped["Male"]["count"] += 1
elif gender == "female":
grouped["Female"]["voices"].append(v)
grouped["Female"]["count"] += 1
return jsonify(grouped)
@app.route("/tts", methods=["POST"])
def tts():
data = request.json
text = data.get("text", "").strip()
voice = data.get("voice")
rate = int(data.get("rate", 0))
pitch = int(data.get("pitch", 0))
if not text:
return jsonify({"error": "Text is required"}), 400
if not voice:
return jsonify({"error": "Voice is required"}), 400
try:
audio_path = asyncio.run(tts_async(text, voice, rate, pitch))
return send_file(
audio_path,
mimetype="audio/mpeg",
as_attachment=True,
download_name="tts.mp3"
)
except Exception as e:
return jsonify({"error": str(e)}), 500
# ---------------------------
# Run server
# ---------------------------
if __name__ == "__main__":
app.run(
host="0.0.0.0",
port=7860,
debug=False
)