from flask import Flask, request, jsonify, send_file import subprocess import os import logging import uuid from dotenv import load_dotenv # .envファイルを読み込む load_dotenv() app = Flask(__name__) # 環境変数から基本設定を取得 VOICEPEAK_PATH = os.getenv('VOICEPEAK_PATH') PROJECT_PATH = os.getenv('PROJECT_PATH') 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': 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) @app.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(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 if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)