elve / tts_script.py
Niansuh's picture
Update tts_script.py
68876da verified
raw
history blame
2.94 kB
import time
import requests
import pathlib
from io import BytesIO
from flask import Flask, request, jsonify, send_file
from concurrent.futures import ThreadPoolExecutor, as_completed
# Flask App Setup
app = Flask(__name__)
# ElevenLabs API Configuration
ELEVENLABS_API_URL = "https://api.elevenlabs.io/v1/text-to-speech"
HEADERS = {"User-Agent": "TTSApp"}
# Change cache directory to a writable location
CACHE_DIR = pathlib.Path("/tmp/audio_cache")
CACHE_DIR.mkdir(parents=True, exist_ok=True)
# Available Voices
ALL_VOICES = {
"Brian": "nPczCjzI2devNBz1zQrb",
"Alice": "Xb7hH8MSUJpSbSDYk0k2",
"Will": "bIHbv24MWmeRgasZH58o",
}
# Split text into sentences (Basic)
def split_sentences(text):
return text.split(". ")
# Generate TTS
def generate_audio(text, voice):
if voice not in ALL_VOICES:
return {"error": f"Invalid voice '{voice}'"}
filename = CACHE_DIR / f"{int(time.time())}.mp3"
sentences = split_sentences(text)
def fetch_audio(sentence, part_number):
try:
response = requests.post(
f"{ELEVENLABS_API_URL}/{ALL_VOICES[voice]}",
headers=HEADERS,
json={"text": sentence, "model_id": "eleven_multilingual_v2"},
timeout=20
)
response.raise_for_status()
return part_number, response.content
except requests.RequestException:
return part_number, None
audio_chunks = {}
with ThreadPoolExecutor() as executor:
futures = {executor.submit(fetch_audio, sentence.strip(), i): i for i, sentence in enumerate(sentences)}
for future in as_completed(futures):
part_number, audio_data = future.result()
if audio_data:
audio_chunks[part_number] = audio_data
combined_audio = BytesIO()
for part_number in sorted(audio_chunks.keys()):
combined_audio.write(audio_chunks[part_number])
with open(filename, "wb") as f:
f.write(combined_audio.getvalue())
return filename.as_posix()
# Flask Routes
@app.route("/")
def home():
return '''
<h1>Text-to-Speech API</h1>
<form action="/tts" method="post">
<label>Text:</label>
<input type="text" name="text" required>
<label>Voice:</label>
<select name="voice">
<option value="Brian">Brian</option>
<option value="Alice">Alice</option>
<option value="Will">Will</option>
</select>
<button type="submit">Generate</button>
</form>
'''
@app.route("/tts", methods=["POST"])
def tts():
text = request.form.get("text")
voice = request.form.get("voice", "Brian")
if not text:
return jsonify({"error": "Text is required!"})
audio_file = generate_audio(text, voice)
return send_file(audio_file, as_attachment=True)
if __name__ == "__main__":
app.run(debug=True, host="0.0.0.0", port=5000)