/// <summary> Build a async request for a one-shot clip. This request handles creation, downloading, notifications and deletion. </summary> public static AsyncRequest Make(string body, string voice, string savePath) { //Build request AsyncRequest request = new AsyncRequest(); request.status = Status.BuildRequest; request.saveDirectory = Path.GetDirectoryName(savePath); request.fileName = Path.GetFileName(savePath); request.deleteClipAtEnd = true; request.requestName = "OneShot > " + request.fileName.Remove(request.fileName.Length - 4); //Generate placeholder request.status = Status.GeneratePlaceHolder; request.GeneratePlaceHolder(); //Send request request.status = Status.SendDataToAPI; ClipPatch.Data data = new ClipPatch.Data(GetTemporaryName(), body, voice); request.currentTask = APIBridge.CreateClip(data, false, (ClipStatus status, Error error) => { request.clipUUID = status.id; RegisterRequestToPool(request); }); //Add request to the pending pool Resources.instance.requests.Add(request); EditorUtility.SetDirty(Resources.instance); Resemble_Window.RefreshPoolList(); //Return the request return(request); }
public static void Show(Rect rect, Speech speech, ValidateCallback callback) { //Close window if already open if (window != null) { Hide(); return; } //Open window ClipPopup.callback = callback; ClipPopup.voiceUUID = speech.voiceUUID; clips = null; error = Error.None; window = CreateInstance <ClipPopup>(); window.ShowPopup(); window.minSize = rect.size; window.titleContent = new GUIContent("Voices"); window.position = rect; //Request clips List <string> existingClips = speech.clips.Select(x => x.uuid).ToList(); APIBridge.GetClips((ResembleClip[] clips, Error error) => { ClipPopup.clips = clips.Where(x => x.voice == voiceUUID && !existingClips.Contains(x.uuid)).ToArray(); ClipPopup.error = error; window.Repaint(); }); }
private static void ExecuteRequest(double time, AsyncRequest request) { //Do nothing if request is waiting for API response if (request.status == Status.WaitClipStatusRequest) { return; } //The next steps are only used to send status request if (request.status != Status.NeedNewClipStatusRequest) { return; } //Force a delay in requests to avoid flooding the api double delta = time - request.lastCheckTime; if (delta < 0.0f || delta > checkCooldown) { request.lastCheckTime = time; } else { return; } //Send GetClip request request.currentTask = APIBridge.GetClip(request.clipUUID, (ResembleClip clip, Error error) => { //Error if (error) { request.SetError(error); } //Receive an response else { //Clip is ready - Start downloading if (clip.finished) { DownloadClip(request, clip.link); //Get phonemes if (request.phonemeCallback != null) { request.phonemeCallback.Invoke(clip.phonemesRaw); } } //Clip is not ready - Mark to create a request next time else { request.status = Status.NeedNewClipStatusRequest; } } }); request.status = Status.WaitClipStatusRequest; }
private static void OnDownloaded(AsyncRequest request, byte[] data, Error error) { //Handle error if (error) { request.SetError(error); return; } //Download completed else { request.status = Status.WritingAsset; } //Write file string savePath = request.saveDirectory + "/" + request.fileName; File.WriteAllBytes(savePath, data); //Import asset savePath = Utils.LocalPath(savePath); AssetDatabase.ImportAsset(savePath, ImportAssetOptions.ForceUpdate); if (request.notificationLink == null) { request.notificationLink = AssetDatabase.LoadAssetAtPath <AudioClip>(savePath); } //Send notification NotificationsPopup.Add("Download completed\n" + request.requestName, MessageType.Info, request.notificationLink); //Delete clip if needed if (!request.deleteClipAtEnd) { request.status = Status.Completed; } else { request.status = Status.SendRequestDeletion; request.currentTask = APIBridge.DeleteClip(request.clipUUID, (string content, Error deleteError) => { if (deleteError) { request.SetError(deleteError); } else { request.status = Status.Completed; } }); } }
/// <summary> Delete a clip from speech. </summary> public void DeleteClip(Clip clip, bool deleteOnAPI, bool deleteAudioClip) { //Delete audioclip if needed if (deleteAudioClip && clip.clip != null) { AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(clip.clip)); } //Delete on APIif needed if (deleteOnAPI) { APIBridge.DeleteClip(clip.uuid); } //Delete clip from speech AssetDatabase.RemoveObjectFromAsset(clip); speech.clips.Remove(clip); //Refresh speech AssetDatabase.ImportAsset(AssetDatabase.GetAssetOrScenePath(speech), ImportAssetOptions.ForceSynchronousImport); }
public void CreateClip(string name) { if (!string.IsNullOrEmpty(name)) { APIBridge.CreateClip(new ClipPatch.Data(name, "", speech.voiceUUID), false, (ClipStatus status, Error error) => { if (error) { error.Log(); } else { if (status.status == "OK") { AddClip(name, status.id); } else { Debug.LogError("Cannot create the clip, please try again later."); } } }); } }
public void UpdateFromAPI() { if (!EditorUtility.DisplayDialog("Update from API", "This operation will overwrite existing " + "information with information from the Resemble.ai website.", "Ok", "Cancel")) { return; } APIBridge.GetClip(clip.uuid, (ResembleClip clip, Error error) => { if (error) { error.Log(); } else { this.clip.text.ParseResembleString(clip.body); this.clip.clipName = clip.title; this.clip.name = clip.uuid + "-" + clip.title; drawer.Refresh(); Repaint(); } }); }
private static void DownloadClip(AsyncRequest request, string url) { request.status = Status.Downloading; request.currentTask = APIBridge.DownloadClip(url, (byte[] data, Error error) => { OnDownloaded(request, data, error); }); }
/// <summary> Build a async request for a clip. This request handles patching, downloading and notifications. </summary> public static AsyncRequest Make(Clip clip) { //Build request AsyncRequest request = new AsyncRequest(); request.status = Status.BuildRequest; string savePath = clip.GetSavePath(); request.saveDirectory = Path.GetDirectoryName(savePath); request.fileName = Path.GetFileName(savePath); request.requestName = clip.speech.name + " > " + clip.clipName; request.clipUUID = clip.uuid; request.notificationLink = clip; //Generate place holder request.status = Status.GeneratePlaceHolder; clip.clip = request.GeneratePlaceHolder(); //Phonemes stuff bool includePhonemes = clip.speech.includePhonemes; string voiceUUID = clip.speech.voiceUUID; if (includePhonemes) { request.phonemeCallback = clip.SetPhonemesRaw; } //No UUID - Create new clip request.status = Status.SendDataToAPI; if (string.IsNullOrEmpty(request.clipUUID)) { //Create new clip ClipPatch.Data data = new ClipPatch.Data(clip.clipName, clip.text.BuildResembleString(), voiceUUID); request.currentTask = APIBridge.CreateClip(data, includePhonemes, (ClipStatus status, Error error) => { request.clipUUID = clip.uuid = status.id; RegisterRequestToPool(request); }); } else { ClipPatch patch = new ClipPatch(clip.clipName, clip.text.BuildResembleString(), voiceUUID, clip.speech.includePhonemes); //Bypass the api check for similarities. if (Settings.forceGeneration) { //Patch clip request.currentTask = APIBridge.UpdateClip(request.clipUUID, patch, (string content, Error patchError) => { RegisterRequestToPool(request); }); } //Check the api for similarities else { //Get existing clip APIBridge.GetClip(clip.uuid, (ResembleClip apiClip, Error error) => { //Handle error if (error) { request.SetError(error); } else { //No changes - Download existing clip if (apiClip.finished && patch.CompareContent(apiClip)) { APIBridge.DownloadClip(apiClip.link, (byte[] data, Error downloadError) => { OnDownloaded(request, data, downloadError); RegisterRequestToPool(request); }); } //Changes - Patch existing clip else { request.currentTask = APIBridge.UpdateClip(request.clipUUID, patch, (string content, Error patchError) => { RegisterRequestToPool(request); }); } } }); } } //Return the request return(request); }
public override void Init(ITorchBase torchBase) { bridge = new APIBridge(8081); }