From 1438ed7b930387dc490e4513e2ba0390e892670b Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Fri, 15 Sep 2023 07:27:40 -0400 Subject: [PATCH 1/2] test page for sad talker inference works --- packages/components/src/jobs/InferenceJob.ts | 1 + packages/fakeyou.com/src/App.tsx | 1 + .../fakeyou.com/src/v2/view/PageContainer.tsx | 3 + .../view/pages/testing/TestPageResultList.tsx | 219 ++++++++++++++++++ .../src/v2/view/pages/testing/TestingPage.tsx | 32 ++- 5 files changed, 255 insertions(+), 1 deletion(-) create mode 100644 packages/fakeyou.com/src/v2/view/pages/testing/TestPageResultList.tsx diff --git a/packages/components/src/jobs/InferenceJob.ts b/packages/components/src/jobs/InferenceJob.ts index 4700206e3c..586126aa83 100644 --- a/packages/components/src/jobs/InferenceJob.ts +++ b/packages/components/src/jobs/InferenceJob.ts @@ -3,6 +3,7 @@ import { JobState, jobStateFromString } from "./JobStates"; // Type of inference job (specified by the frontend, not backend) export enum FrontendInferenceJobType { + FaceAnimation, TextToSpeech, VoiceConversion, } diff --git a/packages/fakeyou.com/src/App.tsx b/packages/fakeyou.com/src/App.tsx index a76c1c5a84..7f5cb8c26b 100644 --- a/packages/fakeyou.com/src/App.tsx +++ b/packages/fakeyou.com/src/App.tsx @@ -180,6 +180,7 @@ function newVocodes() { function initInferenceJobsByCategoryMap() : Map { let inferenceJobsByCategory = new Map(); + inferenceJobsByCategory.set(FrontendInferenceJobType.FaceAnimation, []); inferenceJobsByCategory.set(FrontendInferenceJobType.TextToSpeech, []); inferenceJobsByCategory.set(FrontendInferenceJobType.VoiceConversion, []); return inferenceJobsByCategory; diff --git a/packages/fakeyou.com/src/v2/view/PageContainer.tsx b/packages/fakeyou.com/src/v2/view/PageContainer.tsx index facacb3aef..5f5c50c7bf 100644 --- a/packages/fakeyou.com/src/v2/view/PageContainer.tsx +++ b/packages/fakeyou.com/src/v2/view/PageContainer.tsx @@ -533,6 +533,9 @@ class PageContainer extends React.Component { ; + sessionSubscriptionsWrapper: SessionSubscriptionsWrapper; +} + +// TODO: This is duplicated in SessionTtsInferenceResultsList ! +// Default to querying every 15 seconds, but make it configurable serverside +const DEFAULT_QUEUE_REFRESH_INTERVAL_MILLIS = 15000; + +function TestPageResultList(props: Props) { + const [pendingTtsJobs, setPendingTtsJobs] = + useState({ + success: true, + pending_job_count: 0, + cache_time: new Date(0), // NB: Epoch is used for vector clock's initial state + refresh_interval_millis: DEFAULT_QUEUE_REFRESH_INTERVAL_MILLIS, + }); + + useEffect(() => { + const fetch = async () => { + const response = await GetPendingTtsJobCount(); + if (GetPendingTtsJobCountIsOk(response)) { + if ( + response.cache_time.getTime() > pendingTtsJobs.cache_time.getTime() + ) { + setPendingTtsJobs(response); + } + } + }; + // TODO: We're having an outage and need to lower this. + //const interval = setInterval(async () => fetch(), 15000); + const refreshInterval = Math.max( + DEFAULT_QUEUE_REFRESH_INTERVAL_MILLIS, + pendingTtsJobs.refresh_interval_millis + ); + const interval = setInterval(async () => fetch(), refreshInterval); + fetch(); + return () => clearInterval(interval); + }, [pendingTtsJobs]); + + let results: Array = []; + + // TODO(bt,2023-04-08): Clean this utter garbage duplication up. + + // ============================= GENERIC INFERENCE ============================= + + props.inferenceJobs.forEach((job) => { + if (!job.maybeResultToken) { + let cssStyle = "alert alert-secondary mb-0"; + let stateDescription = "Pending..."; + + switch (job.jobState) { + case JobState.PENDING: + case JobState.UNKNOWN: + stateDescription = + job.maybeExtraStatusDescription == null + ? t("common.SessionTtsInferenceResults.progress.pending") + : job.maybeExtraStatusDescription; + break; + case JobState.STARTED: + cssStyle = "alert alert-success mb-0"; + stateDescription = + job.maybeExtraStatusDescription == null + ? t("common.SessionTtsInferenceResults.progress.started") + : job.maybeExtraStatusDescription; + break; + case JobState.ATTEMPT_FAILED: + cssStyle = "alert alert-danger mb-0"; + stateDescription = `Failed ${job.attemptCount} attempt(s). Will retry...`; + break; + case JobState.COMPLETE_FAILURE: + case JobState.DEAD: + cssStyle = "alert alert-danger mb-0"; + // TODO(bt,2023-01-23): Translate when I can test it + stateDescription = t( + "common.SessionTtsInferenceResults.progress.dead" + ); + break; + case JobState.COMPLETE_SUCCESS: + cssStyle = "message is-success mb-0"; + // Not sure why we're here instead of other branch! + stateDescription = t( + "common.SessionTtsInferenceResults.progress.success" + ); + break; + } + + results.push( +
+
+
+
{stateDescription}
+
+
+
+ ); + } else { + let audioLink = new BucketConfig().getGcsUrl( + job.maybeResultPublicBucketMediaPath + ); + //let ttsPermalink = `/tts/result/${job.maybeResultToken}`; + + //let wavesurfers = ; + let wavesurfers : string[] = []; + + let audioDownloadFilename = `fakeyou-${job.jobToken}.wav`; + + results.push( +
+ {/*
+

{job.title}

+ +
*/} +
+
+
+
{job.maybeModelTitle}
+

{job.maybeRawInferenceText}

+
+ + {/* */} + + {wavesurfers} + +
+ {/* { + Analytics.ttsClickResultLink(); + }} + className="fw-semibold" + > + + {t("common.SessionTtsInferenceResults.result.shareDownload")} + */} + + { + Analytics.voiceConversionClickDownload(); + }} + download={audioDownloadFilename} + > + + Download File{" "} + +
+
+
+
+ ); + } + }); + + let noResultsSection = ( +
+
+ +
+ {t("common.SessionTtsInferenceResults.noResults.title")} +
+

{t("common.SessionTtsInferenceResults.noResults.subtitle")}

+
+
+ ); + + if (results.length === 0) { + return <>{noResultsSection}; + } + + // Users have requested reverse chronological results + results.reverse(); + + return ( +
+
+
+
{results}
+
+
+
+ ); +} + +export { TestPageResultList }; diff --git a/packages/fakeyou.com/src/v2/view/pages/testing/TestingPage.tsx b/packages/fakeyou.com/src/v2/view/pages/testing/TestingPage.tsx index ef9e307f4b..2d30e30415 100644 --- a/packages/fakeyou.com/src/v2/view/pages/testing/TestingPage.tsx +++ b/packages/fakeyou.com/src/v2/view/pages/testing/TestingPage.tsx @@ -10,8 +10,13 @@ import { import { v4 as uuidv4 } from "uuid"; import { FrontendInferenceJobType, InferenceJob } from "@storyteller/components/src/jobs/InferenceJob"; import TestUploadComponent from "./TestUploadComponent"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faBarsStaggered } from "@fortawesome/free-solid-svg-icons"; +import { TestPageResultList } from "./TestPageResultList"; +import { SessionSubscriptionsWrapper } from "@storyteller/components/src/session/SessionSubscriptionsWrapper"; interface Props { + sessionSubscriptionsWrapper: SessionSubscriptionsWrapper; enqueueInferenceJob: ( jobToken: string, frontendInferenceJobType: FrontendInferenceJobType @@ -46,7 +51,7 @@ function TestingPage(props: Props) { if (EnqueueFaceAnimationIsSuccess(result)) { props.enqueueInferenceJob( result.inference_job_token, - FrontendInferenceJobType.VoiceConversion + FrontendInferenceJobType.FaceAnimation ); } }; @@ -113,6 +118,31 @@ function TestingPage(props: Props) { onClick={() => doTest()}> Test the thing + +
+
+ +

+ + Session Results +

+
+ +
+ + ); From 3c8d0dace2857c50f9fcd58aa007376580b139d5 Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Fri, 15 Sep 2023 07:36:07 -0400 Subject: [PATCH 2/2] fix build errors --- .../src/v2/view/pages/testing/TestPageResultList.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/fakeyou.com/src/v2/view/pages/testing/TestPageResultList.tsx b/packages/fakeyou.com/src/v2/view/pages/testing/TestPageResultList.tsx index 4a1807b406..1105918c72 100644 --- a/packages/fakeyou.com/src/v2/view/pages/testing/TestPageResultList.tsx +++ b/packages/fakeyou.com/src/v2/view/pages/testing/TestPageResultList.tsx @@ -1,19 +1,15 @@ import React, { useEffect, useState } from "react"; import { t } from "i18next"; -import { Trans } from "react-i18next"; -import { Link } from "react-router-dom"; import { BucketConfig } from "@storyteller/components/src/api/BucketConfig"; import { JobState } from "@storyteller/components/src/jobs/JobStates"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { - faClock, faHeadphonesSimple, faDownload, } from "@fortawesome/free-solid-svg-icons"; import { SessionSubscriptionsWrapper } from "@storyteller/components/src/session/SessionSubscriptionsWrapper"; import { Analytics } from "../../../../common/Analytics"; -import { WebUrl } from "../../../../common/WebUrl"; import { GetPendingTtsJobCount, GetPendingTtsJobCountIsOk,