tts-piper/stt_piper.py

91 lines
2.7 KiB
Python

from flask import Flask, request, Response
import subprocess
import os
import time
import random
from datetime import datetime
app = Flask(__name__)
# Ensure storage directories exist
os.makedirs('texts', exist_ok=True)
os.makedirs('audio', exist_ok=True)
def generate_filename():
"""Generate timestamp + random number filename"""
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
random_num = random.randint(1000, 9999)
return f"{timestamp}_{random_num}"
@app.route('/tts', methods=['POST'])
def tts():
# Validate input
if not request.is_json:
return {"error": "Request must be JSON"}, 400
text = request.json.get('text', '').strip()
if not text:
return {"error": "No text provided"}, 400
if len(text) > 1000:
return {"error": "Text too long (max 1000 characters)"}, 400
# Generate unique filename
base_filename = generate_filename()
text_filename = f"data/texts/{base_filename}.txt"
wav_filename = f"data/audio/{base_filename}.wav"
try:
# Save the input text
with open(text_filename, 'w') as f:
f.write(text)
# Generate WAV audio with Piper - directly to file first
piper_cmd = [
'echo', f'"{text}"', '|',
'./piper/piper',
'--model', './model/en_US-amy-medium.onnx',
'--output_file', wav_filename
]
# Run the command
process = subprocess.run(
' '.join(piper_cmd),
shell=True,
check=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
# Verify the output file was created
if not os.path.exists(wav_filename):
raise Exception("Piper failed to create audio file")
# Get file size for logging
file_size = os.path.getsize(wav_filename)
# Read the generated audio
with open(wav_filename, 'rb') as f:
audio_data = f.read()
# Log the successful generation
print(f"Generated TTS: {len(text)} chars -> {file_size} bytes audio")
# Return WAV audio directly
return Response(
audio_data,
mimetype='audio/wav',
headers={'Content-Disposition': f'attachment; filename={base_filename}.wav'}
)
except subprocess.CalledProcessError as e:
error_msg = f"Piper TTS failed: {e.stderr.decode().strip()}"
print(error_msg)
return {"error": "TTS generation failed", "details": error_msg}, 500
except Exception as e:
error_msg = f"Unexpected error: {str(e)}"
print(error_msg)
return {"error": "TTS processing failed", "details": error_msg}, 500
if __name__ == '__main__':
app.run(host='0.0.0.0', port=4005, debug=True)