Spaces:
Sleeping
Sleeping
| from flask import Flask, send_file, request, render_template_string | |
| import subprocess | |
| import os | |
| import uuid | |
| app = Flask(__name__) | |
| AUDIO_DIR = "/tmp/tts_audio" | |
| os.makedirs(AUDIO_DIR, exist_ok=True) | |
| def home(): | |
| return render_template_string(''' | |
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <title>eSpeak NG TTS API</title> | |
| <style> | |
| body { font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px; } | |
| code { background: #f4f4f4; padding: 2px 5px; } | |
| </style> | |
| </head> | |
| <body> | |
| <h1>eSpeak NG Text-to-Speech API</h1> | |
| <p>Use the endpoint below to generate speech:</p> | |
| <code>GET /speak?input=Your+Text+Here</code> | |
| <p>Example:</p> | |
| <a href="/speak?input=Hello+World" target="_blank">/speak?input=Hello+World</a> | |
| <p>Returns: Raw MP3 audio.</p> | |
| </body> | |
| </html> | |
| ''') | |
| def speak(): | |
| text = request.args.get('input', '') | |
| voice = request.args.get('voice', 'mb-en1') # Default: MBROLA English | |
| if not text: | |
| return "Error: Add ?input=Your+Text to the URL", 400 | |
| wav_path = os.path.join(AUDIO_DIR, f"{uuid.uuid4()}.wav") | |
| mp3_path = wav_path.replace('.wav', '.mp3') | |
| # Generate speech with MBROLA voice | |
| subprocess.run([ | |
| 'espeak-ng', | |
| '-v', voice, | |
| '-s', '150', | |
| '-w', wav_path, | |
| text | |
| ], check=True) | |
| # Convert to MP3 | |
| subprocess.run([ | |
| 'ffmpeg', | |
| '-i', wav_path, | |
| '-vn', | |
| '-ar', '44100', | |
| '-ac', '2', | |
| '-b:a', '192k', | |
| mp3_path | |
| ], check=True) | |
| return send_file(mp3_path, mimetype="audio/mpeg") | |
| if __name__ == '__main__': | |
| app.run(host='0.0.0.0', port=7860) |