AivisSpeech-engineをVPSで立ち上げてみた(2)
以下の記事で、AivisSpeech-engineの立ち上げまでを実行しました。
サンプルコードでもわかるように、音声合成のためには、2回のAPIリクエストが必要になります。
少々使い勝手が悪いので、一度で実行できるようにします。
ついでに、テキストだけでなくSpeaker IDも指定できるようにしたいと思います。
音声合成のコード
前回のサンプルプログラムを修正してFlaskのコードにしました。
AivisSpeech-Engineと同一サーバに配置する予定なので、接続先をlocalhostとしています。
from flask import Flask, request, send_file
from flask_cors import CORS
import io
import json
import soundfile
import requests
from werkzeug.exceptions import BadRequest
app = Flask(__name__)
CORS(app)
class AivisAdapter:
def __init__(self, default_speaker: int = 888753760):
# 同じDocker network内のサービス名で接続
self.URL = "http://localhost:10101"
self.default_speaker = default_speaker
def generate_voice(self, text: str, speaker_id: int = None) -> tuple:
speaker = speaker_id if speaker_id is not None else self.default_speaker
params = {"text": text, "speaker": speaker}
query_response = requests.post(f"{self.URL}/audio_query", params=params).json()
audio_response = requests.post(
f"{self.URL}/synthesis",
params={"speaker": speaker},
headers={"accept": "audio/wav", "Content-Type": "application/json"},
data=json.dumps(query_response),
)
with io.BytesIO(audio_response.content) as audio_stream:
data, rate = soundfile.read(audio_stream)
return data, rate
@app.route('/generate', methods=['POST'])
def generate_voice():
try:
text = request.form.get('text')
speaker_id = request.form.get('speaker_id')
if not text:
raise BadRequest("Text is required")
speaker_id = int(speaker_id) if speaker_id else None
adapter = AivisAdapter()
data, rate = adapter.generate_voice(text, speaker_id)
# メモリ上で音声ファイルを作成
audio_buffer = io.BytesIO()
soundfile.write(audio_buffer, data, rate, format='WAV')
audio_buffer.seek(0)
return send_file(
audio_buffer,
mimetype='audio/wav',
as_attachment=True,
download_name='output.wav'
)
except Exception as e:
return {'error': str(e)}, 400
if __name__ == '__main__':
app.run(host='0.0.0.0', port=80)
dockerで起動するために、以下のファイルを追加します。
flask
flask-cors
requests
soundfile
FROM python:3.9-slim
WORKDIR /app
# システムの依存関係をインストール
RUN apt-get update && apt-get install -y \
libsndfile1 \
&& rm -rf /var/lib/apt/lists/*
COPY app/requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app/ .
CMD ["python", "main.py"]
全体の構造は、以下のとおりです。
project/
├── app/
│ ├── main.py
│ └── requirements.txt
├── Dockerfile
docker コマンドを使って、flaskアプリを立ち上げます。
sudo docker build -t tts-web-app .
sudo docker run -d --restart unless-stopped --name tts-web --network host tts-web-app
うまく動いているか、サーバ内の端末から以下を叩いて確認します。
curl -X POST -F "text=こんにちは" -F "speaker_id=888753760" http://localhost/generate -o output.wav
音声ファイルが生成されれば完成です。
ちなみに、pythonだと、こんな感じです。Google Colabでも実行できます。
import requests
url = 'http://164.70.118.24/generate'
data = {
'text': 'なんか面白いこと話してよ',
'speaker_id': '888753760'
}
files = {}
response = requests.post(url, data=data, files=files)
if response.status_code == 200:
with open('test.wav', 'wb') as f:
f.write(response.content)
print('ファイルを保存しました')
else:
print('エラー:', response.status_code)