217 lines
7.2 KiB
Python
217 lines
7.2 KiB
Python
import math
|
|
import os
|
|
import requests
|
|
from pprint import pprint
|
|
import argparse
|
|
import soundfile
|
|
|
|
|
|
class A2F(object):
|
|
ROOT_PATH = "/home/ubuntu/results"
|
|
|
|
BASE_PATH = os.path.expanduser("~/.local/share/ov/pkg/audio2face-2023.2.0/")
|
|
ASSETS_PATH = os.path.join(BASE_PATH, "exts/omni.audio2face.tool/deps/audio2face-assets")
|
|
CLAIRE_PATH = os.path.join(ASSETS_PATH, "claire/mesh/claire_fullface_model.usd")
|
|
MARK_PATH = os.path.join(ASSETS_PATH, "mark/mesh/mark_fullface_model.usd")
|
|
|
|
PLAYER_NAME = "/World/audio2face/Player"
|
|
FULLFACE_MODEL_NAME = "/World/audio2face/CoreFullface"
|
|
|
|
def __init__(self, url="http://localhost:8011/"):
|
|
self.url = url
|
|
|
|
def status(self):
|
|
resp = requests.get(f"{self.url}status")
|
|
return resp.json()
|
|
|
|
def get_emotion_names(self):
|
|
resp = requests.get(f"{self.url}A2F/A2E/GetEmotionNames")
|
|
return resp.json().get('result', [])
|
|
|
|
def get_scene_objects(self):
|
|
resp = requests.get(f"{self.url}A2F/GetInstances")
|
|
return resp.json().get('result', {})
|
|
|
|
def get_players(self):
|
|
resp = requests.get(f"{self.url}A2F/Player/GetInstances")
|
|
return resp.json().get('result', {})
|
|
|
|
def load_usd(self, usd_path):
|
|
resp = requests.post(f"{self.url}A2F/USD/Load",
|
|
json={
|
|
"file_name": usd_path,
|
|
})
|
|
return resp.json()
|
|
|
|
def load_claire(self):
|
|
print("Claire path: ", self.CLAIRE_PATH)
|
|
return self.load_usd(self.CLAIRE_PATH)
|
|
|
|
def load_mark(self):
|
|
print("Mark path: ", self.MARK_PATH)
|
|
return self.load_usd(self.MARK_PATH)
|
|
|
|
def openapi(self):
|
|
resp = requests.get(f"{self.url}openapi.json")
|
|
return resp.json()
|
|
|
|
def get_frame(self):
|
|
pass
|
|
|
|
def get_settings(self):
|
|
resp = requests.post(f"{self.url}A2F/GetSettings", json={
|
|
"a2f_instance": "",
|
|
})
|
|
return resp.json()
|
|
|
|
def get_player_root(self):
|
|
resp = requests.post(f"{self.url}A2F/Player/GetRootPath", json={
|
|
"a2f_player": self.PLAYER_NAME,
|
|
})
|
|
return resp.json()
|
|
|
|
def set_player_root(self, new_path):
|
|
resp = requests.post(f"{self.url}A2F/Player/SetRootPath", json={
|
|
"a2f_player": self.PLAYER_NAME,
|
|
"dir_path": new_path,
|
|
})
|
|
return resp.json()
|
|
|
|
def set_audio(self, audio_path):
|
|
duration = soundfile.info(audio_path).duration
|
|
print("Audio duration: ", duration)
|
|
resp = requests.post(f"{self.url}A2F/Player/SetTrack", json={
|
|
"a2f_player": self.PLAYER_NAME,
|
|
"file_name": audio_path,
|
|
"time_range": [
|
|
0,
|
|
duration
|
|
]
|
|
})
|
|
data = [resp.json()]
|
|
resp = requests.post(f"{self.url}A2F/Player/SetRange", json={
|
|
"a2f_player": self.PLAYER_NAME,
|
|
"start": 0,
|
|
"end": duration
|
|
})
|
|
data.append(resp.json())
|
|
|
|
resp = requests.post(f"{self.url}A2F/Player/GetTracks", json={
|
|
"a2f_player": self.PLAYER_NAME,
|
|
})
|
|
data.append(resp.json())
|
|
|
|
resp = requests.post(f"{self.url}A2F/Player/GetCurrentTrack", json={
|
|
"a2f_player": self.PLAYER_NAME,
|
|
})
|
|
data.append(resp.json())
|
|
return data
|
|
|
|
def get_audio_range(self):
|
|
resp = requests.post(f"{self.url}A2F/Player/GetRange", json={
|
|
"a2f_player": self.PLAYER_NAME,
|
|
})
|
|
return resp.json()
|
|
|
|
def run(self):
|
|
resp = requests.post(f"{self.url}A2F/A2E/GenerateKeys", json={
|
|
"a2f_instance": self.FULLFACE_MODEL_NAME,
|
|
})
|
|
return resp.json()
|
|
|
|
def get_number_of_keys(self):
|
|
resp = requests.post(f"{self.url}A2F/A2E/NumKeys", json={
|
|
"a2f_instance": self.FULLFACE_MODEL_NAME,
|
|
})
|
|
return resp.json()
|
|
|
|
def get_generated_keys(self):
|
|
resp = requests.post(f"{self.url}A2F/A2E/GetKeyData", json={
|
|
"a2f_instance": self.FULLFACE_MODEL_NAME,
|
|
})
|
|
return resp.json()
|
|
|
|
def get_a2e_settings(self):
|
|
resp = requests.post(f"{self.url}A2F/A2E/GetSettings", json={
|
|
"a2f_instance": self.FULLFACE_MODEL_NAME,
|
|
})
|
|
return resp.json()
|
|
|
|
def get_blendshape_solvers(self):
|
|
resp = requests.get(f"{self.url}A2F/Exporter/GetBlendShapeSolvers")
|
|
return resp.json()
|
|
|
|
def get_pre_settings(self):
|
|
resp = requests.post(f"{self.url}A2F/PRE/SetSettings", json={
|
|
"a2f_instance": self.FULLFACE_MODEL_NAME,
|
|
"prediction_delay": 0.01,
|
|
})
|
|
resp = requests.post(f"{self.url}A2F/PRE/GetSettings", json={
|
|
"a2f_instance": self.FULLFACE_MODEL_NAME,
|
|
})
|
|
return resp.json()
|
|
|
|
def get_post_settings(self):
|
|
resp = requests.post(f"{self.url}A2F/POST/GetSettings", json={
|
|
"a2f_instance": self.FULLFACE_MODEL_NAME,
|
|
})
|
|
return resp.json()
|
|
|
|
def export(self, export_path, filename):
|
|
resp = requests.post(f"{self.url}A2F/Exporter/ExportGeometryCache", json={
|
|
"export_directory": export_path,
|
|
"cache_type": "usd",
|
|
"xform_keys": False,
|
|
"batch": False,
|
|
"file_name": filename,
|
|
"fps": 0
|
|
})
|
|
try:
|
|
return resp.json()
|
|
except:
|
|
print(resp.content)
|
|
|
|
def export_json(self, export_path, filename):
|
|
resp = requests.post(f"{self.url}A2F/Exporter/ExportBlendshapes", json={
|
|
"export_directory": export_path,
|
|
"format": "json",
|
|
"batch": False,
|
|
"file_name": filename,
|
|
"fps": 0
|
|
})
|
|
try:
|
|
return resp.json()
|
|
except:
|
|
print(resp.content)
|
|
|
|
def upload(self, audio_path):
|
|
audio_path = os.path.abspath(audio_path)
|
|
fname = os.path.basename(audio_path)
|
|
os.system(f"cd ./server && ./send_file_to_gui.sh {audio_path} ../results/{fname}")
|
|
return os.path.join("/home/ubuntu/results", fname)
|
|
|
|
def pull(self, fname):
|
|
export_fname = os.path.splitext(fname)[0] + '.usd'
|
|
os.system(f"cd ./server && ./send_file_from_gui.sh ../results/{export_fname} ../")
|
|
|
|
def apply(self, audio_path):
|
|
fname = os.path.basename(audio_path)
|
|
print("Status: ", self.status())
|
|
print("EmotionNames: ", self.get_emotion_names())
|
|
print("Scene Objects: ", self.get_scene_objects())
|
|
print("Scene Players: ", self.get_players())
|
|
print("Preprocessing settings: ", self.get_pre_settings())
|
|
print("Postprocessing settings: ", self.get_post_settings())
|
|
print("Setting player root: ", self.set_player_root("/home/ubuntu/results"))
|
|
print("Player root: ", self.get_player_root())
|
|
print("Setting audio: ", self.set_audio(os.path.basename(audio_path)))
|
|
print("Audio Range: ", self.get_audio_range())
|
|
print("Running: ", self.run())
|
|
print("NumKeys: ", self.get_number_of_keys())
|
|
print("Keys: ", self.get_generated_keys())
|
|
print("Exporting: ", self.export_json("/home/ubuntu/results",
|
|
filename=os.path.splitext(fname)[0]))
|
|
|
|
def apply_stream(self, audio_path):
|
|
pass
|