現在検討中のシステムでは
InputField入力(Unity WebGL)
→ScriptでHTTP通信して、ポート8080に送信
→処理をして返信
→Unity WebGLが受け取ってTextに展開
となる
これをテストしよう
デバッグが楽なので、まずはGETで
Flask側 test.pyを以下に書き換えた
from flask import Flask, send_from_directory,request
app = Flask(__name__)
@app.route('/')
def get():
recievedata = request.args.get('SendData')
print(recievedata)
return 'Fee曰く {}'.format(recievedata)
@app.route('/sub')
def fnc_1():
return "subページです"
@app.route("/music/<path:filename>")
def play(filename):
return send_from_directory("music", filename)
if __name__ == '__main__':
app.run(debug=True, host="0.0.0.0", port=8080)
ブラウザで
と打つとGETできることを確認
次にUnity側だ
InputFieldManagerのスクリプトの中に通信をまぜた
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;
using TMPro;
public class InputFieldManager : MonoBehaviour
{
TMP_InputField inputField;
TMP_Text text;
void Start()
{
inputField = GameObject.Find("InputField (TMP)").GetComponent<TMP_InputField>();
text = GameObject.Find("Text (TMP)").GetComponent<TMP_Text>();
}
public void OnEndEdit()
{
Debug.Log("InputField : " + inputField.text);
StartCoroutine(SendData(inputField.text));
inputField.text = "";
}
IEnumerator SendData(string data)
{
string url = "http://127.0.0.1:8080/";
UnityWebRequest request = UnityWebRequest.Get(url + "?SendData=" + data);
yield return request.SendWebRequest();
if (request.result != UnityWebRequest.Result.Success)
{
Debug.Log(request.error);
}
else
{
text.text = request.downloadHandler.text;
Debug.Log("Data sent successfully!");
Debug.Log("Response: " + request.downloadHandler.text);
}
}
}
これでUnityのウインドウからは動作OK!
CeVIO AIの初期化が…
PythonのmainにCeVIO_init()を入れるとユーザーが単一ではないと言われてエラーになる
訳が分からんので、とりあえずCeVIO AIの起動は手動にし、そのほかの初期化の項目は通信のたびにすることにした
CeVIO_control.pyには合成された音声をwavファイルで書き出すAPIを追加し、これを起動して音声ファイルを生成する
またwavファイルを書き出す時間を1秒として、Waitを持たせた
from flask import Flask, send_from_directory,request
import CeVIO_control
import time
app = Flask(__name__)
recievedata = ""
senddata = ""
# GET受信設定と返信
@app.route('/')
def get():
recievedata = request.args.get('SendData')
print("Client input : " + recievedata)
senddata = recievedata + " ですね"
CeVIO_control.CeVIO_init()
CeVIO_control.CeVIO_wav_file_output(senddata)
time.sleep(1)
return senddata
# wavファイルをアクセスできるように設定
@app.route("/Fee_voice/<path:filename>")
def play(filename):
return send_from_directory("Fee_voice", filename)
if __name__ == '__main__':
app.run(debug=True, host="0.0.0.0", port=8080)
# 注意:CeVIO AIはPythonを実行する前に起動させておくこと
CeVIO_control.py
import win32com.client
service_control = win32com.client.Dispatch("CeVIO.Talk.RemoteService2.ServiceControl2V40")
talker2 = win32com.client.Dispatch("CeVIO.Talk.RemoteService2.Talker2V40")
def CeVIO_init():
service_control.StartHost(False)
#キャストを確認する
string_array = talker2.AvailableCasts
print([string_array.At(i) for i in range(string_array.Length)])
#キャストを設定する
talker2.Cast = "夏色花梨"
#ボリュームを設定する
talker2.Volume = 5
#速度を設定する
talker2.speed = 45
#感情を確認する
component_array = talker2.Components
print([component_array.At(i).Name for i in range(component_array.Length)])
CeVIO_emotion_set(100,0,0,0,0)
return
def CeVIO_emotion_set(ureshii,futsuu,ikari,kanashimi,ochitsuki):
#感情を設定する
component_array = talker2.Components
component_array.ByName("嬉しい").Value = ureshii
component_array.ByName("普通").Value = futsuu
component_array.ByName("怒り").Value = ikari
component_array.ByName("哀しみ").Value = kanashimi
component_array.ByName("落ち着き").Value = ochitsuki
# Feeの言葉をwavファイルに出力する
def CeVIO_wav_file_output(text):
talker2.OutputWaveToFile(text, "C:\Snack_Virtual_2\Flask_Python\Fee_voice\Fee_voice.wav")
print("Fee voice : " + text )
return
Feeからの返信と共に音声を出力する
グローバル変数設定とかで苦しむが、なんとか完成
![](https://static.wixstatic.com/media/d6e266_dd57fab8393f4c9e91973faa835751f1~mv2.png/v1/fill/w_980,h_441,al_c,q_90,usm_0.66_1.00_0.01,enc_auto/d6e266_dd57fab8393f4c9e91973faa835751f1~mv2.png)
InputFieldManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;
using TMPro;
public class InputFieldManager : MonoBehaviour
{
TMP_InputField inputField;
TMP_Text text;
string text0,text1,text2,text3;
void TextWindowinput(string inputtext)
{
text3 = text2;
text2 = text1;
text1 = text0;
text0 = inputtext;
text.text = text0 + "\r\n" + text1 + "\r\n" + text2 + "\r\n" + text3;
}
void Start()
{
inputField = GameObject.Find("InputField (TMP)").GetComponent<TMP_InputField>();
text = GameObject.Find("Text (TMP)").GetComponent<TMP_Text>();
inputField.ActivateInputField();
inputField.Select();
}
void Update()
{
if (!inputField.isFocused)
{
inputField.ActivateInputField();
inputField.Select();
}
}
public void OnEndEdit()
{
Debug.Log("InputField : " + inputField.text);
TextWindowinput("Client : " + inputField.text);
StartCoroutine(SendData(inputField.text));
inputField.text = "";
}
IEnumerator SendData(string data)
{
string url = "http://127.0.0.1:8080/";
UnityWebRequest request = UnityWebRequest.Get(url + "?SendData=" + data);
yield return request.SendWebRequest();
if (request.result != UnityWebRequest.Result.Success)
{
Debug.Log(request.error);
}
else
{
TextWindowinput("Fee : " + request.downloadHandler.text);
Debug.Log("Data sent successfully!");
Debug.Log("Response: " + request.downloadHandler.text);
AudioPlayer.PlaybackFlag = true;
}
}
}
TextWindowinput(string inputtext)で4行でスクロールするようにしたのと
InputFieldに常にフォーカスされるようにした
最終行のAudioPlayer.PlaybackFlagが再生フラグである
AudioPlayer.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
public class AudioPlayer : MonoBehaviour
{
public string url = "http://127.0.0.1:8080/Fee_voice/Fee_voice.wav";
public static bool PlaybackFlag = false;
public int FrameCount;
void Start()
{
}
void Update()
{
if (PlaybackFlag){
PlaybackFlag = false;
Debug.Log("Playback");
StartCoroutine(Playback());
}
}
IEnumerator Playback()
{
using (var uwr = UnityWebRequestMultimedia.GetAudioClip(url, AudioType.WAV))
{
yield return uwr.SendWebRequest();
if (uwr.result == UnityWebRequest.Result.ConnectionError || uwr.result == UnityWebRequest.Result.ProtocolError)
{
Debug.LogError(uwr.error);
}
else
{
var audioClip = DownloadHandlerAudioClip.GetContent(uwr);
var audioSource = GetComponent<AudioSource>();
audioSource.clip = audioClip;
audioSource.Play();
}
}
}
}
残るは口パクとCORSかな
FlaskのCORS対応
Bingより以下のように教わった
Flaskで作ったサーバーをCORS対応にするには、Flask-Corsという拡張機能を使用するのが一般的です1。以下の手順でCORS対応を行うことができます。
Flask-Corsをインストールします。pip install flask-cors
Flaskアプリケーションのインスタンスを作成します。
Python
from flask import Flask
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
AI で生成されたコード。ご確認のうえ、慎重にご使用ください。FAQ で詳細を確認。
CORSを有効にするエンドポイントを指定します。
Python
from flask import Flask
from flask_cors import CORS
app = Flask(__name__)
CORS(app, resources={r"/*": {"origins": "*"}})
とのことなので、そのとおりにやってみる
from flask import Flask, send_from_directory,request
from flask_cors import CORS
import CeVIO_control
import time
app = Flask(__name__)
CORS(app, resources={r"/*": {"origins": "*"}})
recievedata = ""
senddata = ""
# GET受信設定と返信
@app.route('/')
def get():
recievedata = request.args.get('SendData')
print("Client input : " + recievedata)
senddata = recievedata + " ですね"
CeVIO_control.CeVIO_init()
CeVIO_control.CeVIO_wav_file_output(senddata)
time.sleep(1)
return senddata
# wavファイルをアクセスできるように設定
@app.route("/Fee_voice/<path:filename>")
def play(filename):
return send_from_directory("Fee_voice", filename)
if __name__ == '__main__':
app.run(debug=True, host="0.0.0.0", port=8080)
# 注意:CeVIO AIはPythonを実行する前に起動させておくこと
なんと、一発完動!
![](https://static.wixstatic.com/media/d6e266_a71ed0063fa244f18a4fde868921a6b4~mv2.png/v1/fill/w_980,h_444,al_c,q_90,usm_0.66_1.00_0.01,enc_auto/d6e266_a71ed0063fa244f18a4fde868921a6b4~mv2.png)
あとはモーションシンクの口パクだけだ
Comments