top of page

InputFieldのエコーバックを試す

執筆者の写真: snackvirtualsnackvirtual

更新日:2024年2月2日

現在検討中のシステムでは

 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からの返信と共に音声を出力する

グローバル変数設定とかで苦しむが、なんとか完成


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より以下のように教わった


  1. Flask-Corsをインストールします。pip install flask-cors

  2. Flaskアプリケーションのインスタンスを作成します。

Python

from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

AI で生成されたコード。ご確認のうえ、慎重にご使用ください。FAQ で詳細を確認

  1. 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を実行する前に起動させておくこと

なんと、一発完動!


あとはモーションシンクの口パクだけだ


閲覧数:1回0件のコメント

最新記事

すべて表示

Comments


bottom of page