voicepeak_api/app.py

88 lines
2.7 KiB
Python
Raw Normal View History

2024-08-03 11:12:30 +00:00
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)