first commit
This commit is contained in:
216
a2f_api.py
Normal file
216
a2f_api.py
Normal file
@@ -0,0 +1,216 @@
|
||||
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
|
||||
Reference in New Issue
Block a user