Files
miapia-backend-final/a2f_api.py
George Kasparyants 7591784e34 first commit
2024-06-14 00:47:32 +03:00

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