from flask import Blueprint, request, jsonify, send_file import subprocess import os import logging import uuid from flask import current_app bp = Blueprint('main', __name__) def _build_command_args(args): return [ args['voicepeak_path'], "-s", args['script'], "-n", args['narrator'], "-o", args['output_path'], "-e", args['emotions'], "--pitch", str(args['pitch']), ] def _synthesize_with_voicepeak(script, narrator, emotions, pitch, output_path, retries=3): args = { 'voicepeak_path': current_app.config['VOICEPEAK_PATH'], 'script': script, 'narrator': narrator, 'output_path': output_path, 'emotions': emotions, 'pitch': pitch, } command_args = _build_command_args(args) for attempt in range(retries): try: subprocess.run(command_args, check=True) if os.path.exists(output_path): return output_path except subprocess.CalledProcessError as e: error_message = f"VoicePeak synthesis failed on attempt {attempt + 1}: {e}" logging.error(error_message) if attempt < retries - 1: logging.info(f"Retrying... ({attempt + 2}/{retries})") else: raise RuntimeError(error_message) from e error_message = f"Expected audio file not found after {retries} attempts: {output_path}" logging.error(error_message) raise FileNotFoundError(error_message) @bp.route('/generate_voice', methods=['POST']) def generate_voice(): try: data = request.json text = data.get('text') narrator = data.get('narrator', '1') emotion_happy = data.get('emotion_happy', '0') emotion_sad = data.get('emotion_sad', '0') emotion_angry = data.get('emotion_angry', '0') emotion_fun = data.get('emotion_fun', '0') pitch = data.get('pitch', '1') if not text: return jsonify({'error': 'Text is required'}), 400 emotions = f"happy={emotion_happy},sad={emotion_sad},angry={emotion_angry},fun={emotion_fun}" unique_id = str(uuid.uuid4()) output_file = os.path.join(current_app.config['PROJECT_PATH'], f'{unique_id}.wav') _synthesize_with_voicepeak(text, narrator, emotions, pitch, output_file) response = send_file(output_file, mimetype='audio/wav') os.remove(output_file) return response except Exception as e: return jsonify({'error': str(e)}), 500