fbx to gltf working

This commit is contained in:
BFlat committed 2024-01-30 12:55:54 +07:00
1 parent 39598c8080
commit c76b40ede4
4 files changed
+153 -82

No files matched your search

+7 -3
View File
@@ -492,10 +492,14 @@ class ApiConfig {
}
// =============== Motion Capture / mocap ===============
enqueueVideoMotionCapture(): string{
return `${this.getApiOrigin()}/v1/mocap/mocapnet/create`
enqueueVideoMotionCapture(): string {
return `${this.getApiOrigin()}/v1/mocap/mocapnet/create`;
}
// =============== Convert FBX to glTF ===============
enqueueFbxToGltf(): string {
return `${this.getApiOrigin()}/v1/conversion/enqueue_fbx_to_gltf`;
}
// =============== Generic Model Downloads ===============
@@ -615,4 +619,4 @@ class ApiConfig {
}
}
export { ApiConfig };
export { ApiConfig };
@@ -0,0 +1,49 @@
import { ApiConfig } from "../ApiConfig";
export interface EnqueueFbxToGltfRequest {
media_file_token: string;
uuid_idempotency_token: string;
}
export interface EnqueueFbxToGltfResponse {
success: boolean;
inference_job_token?: string;
}
const EnqueueFbxToGltfIsSuccess = (response: EnqueueFbxToGltfResponse) =>
response.inference_job_token;
const EnqueueFbxToGltfIsError = (response: EnqueueFbxToGltfResponse) =>
!response.inference_job_token;
export { EnqueueFbxToGltfIsSuccess, EnqueueFbxToGltfIsError };
export async function EnqueueFbxToGltf(
request: EnqueueFbxToGltfRequest
): Promise<EnqueueFbxToGltfResponse> {
const endpoint = new ApiConfig().enqueueFbxToGltf();
return await fetch(endpoint, {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
credentials: "include",
body: JSON.stringify(request),
})
.then(res => res.json())
.then(res => {
if (!res) {
return { success: false };
}
if (res && "success" in res) {
return res;
} else {
return { success: false };
}
})
.catch(e => {
return { success: false };
});
}
+31 -33
View File
@@ -60,10 +60,7 @@ import { VoiceConversionModelUploadJob } from "@storyteller/components/src/jobs/
import { VoiceConversionModelListItem } from "@storyteller/components/src/api/voice_conversion/ListVoiceConversionModels";
import HttpBackend from "i18next-http-backend";
import {
InferenceJobs,
SessionProvider,
} from "components/providers";
import { InferenceJobs, SessionProvider } from "components/providers";
// NB: We're transitioning over to this instance of i18n-next that loads translations over HTTP from Json Files.
// The old i18n-next instance (see below) bakes in translations into the compiled javascript blob.
@@ -207,6 +204,7 @@ function initInferenceJobsByCategoryMap(): Map<
);
inferenceJobsByCategory.set(FrontendInferenceJobType.VoiceDesignerTts, []);
inferenceJobsByCategory.set(FrontendInferenceJobType.VideoMotionCapture, []);
inferenceJobsByCategory.set(FrontendInferenceJobType.ConvertFbxtoGltf, []);
return inferenceJobsByCategory;
}
@@ -404,11 +402,11 @@ class App extends React.Component<Props, State> {
Accept: "application/json",
},
})
.then((_raw_response) => {
.then(_raw_response => {
this.querySession();
this.querySessionSubscriptions();
})
.catch((e) => {
.catch(e => {
/* Ignore. */
});
};
@@ -451,7 +449,7 @@ class App extends React.Component<Props, State> {
if (GetModelInferenceJobStatusIsOk(lookupResult)) {
let updatedJobs: Array<InferenceJob> = [];
this.state.inferenceJobs.forEach((existingJob) => {
this.state.inferenceJobs.forEach(existingJob => {
if (
existingJob.jobToken !== lookupResult.state!.job_token ||
!jobStateCanChange(existingJob.jobState)
@@ -511,8 +509,8 @@ class App extends React.Component<Props, State> {
Accept: "application/json",
},
})
.then((res) => res.json())
.then((response) => {
.then(res => res.json())
.then(response => {
const jobResponse: TtsInferenceJobStateResponsePayload = response;
if (jobResponse === undefined || jobResponse.state === undefined) {
@@ -521,7 +519,7 @@ class App extends React.Component<Props, State> {
let updatedJobs: Array<TtsInferenceJob> = [];
this.state.ttsInferenceJobs.forEach((existingJob) => {
this.state.ttsInferenceJobs.forEach(existingJob => {
if (
existingJob.jobToken !== jobResponse.state!.job_token ||
!jobStateCanChange(existingJob.jobState)
@@ -538,7 +536,7 @@ class App extends React.Component<Props, State> {
ttsInferenceJobs: updatedJobs,
});
})
.catch((e) => {
.catch(e => {
/* Ignore. */
});
};
@@ -563,8 +561,8 @@ class App extends React.Component<Props, State> {
Accept: "application/json",
},
})
.then((res) => res.json())
.then((response) => {
.then(res => res.json())
.then(response => {
const jobResponse: TtsModelUploadJobStateResponsePayload = response;
if (jobResponse === undefined || jobResponse.state === undefined) {
@@ -572,7 +570,7 @@ class App extends React.Component<Props, State> {
}
let updatedJobs: Array<TtsModelUploadJob> = [];
this.state.ttsModelUploadJobs.forEach((existingJob) => {
this.state.ttsModelUploadJobs.forEach(existingJob => {
if (
existingJob.jobToken !== jobResponse.state!.job_token ||
!jobStateCanChange(existingJob.jobState)
@@ -589,7 +587,7 @@ class App extends React.Component<Props, State> {
ttsModelUploadJobs: updatedJobs,
});
})
.catch((e) => {
.catch(e => {
/* Ignore. */
});
};
@@ -614,8 +612,8 @@ class App extends React.Component<Props, State> {
Accept: "application/json",
},
})
.then((res) => res.json())
.then((response) => {
.then(res => res.json())
.then(response => {
const jobResponse: W2lInferenceJobStateResponsePayload = response;
if (jobResponse === undefined || jobResponse.state === undefined) {
@@ -623,7 +621,7 @@ class App extends React.Component<Props, State> {
}
let updatedJobs: Array<W2lInferenceJob> = [];
this.state.w2lInferenceJobs.forEach((existingJob) => {
this.state.w2lInferenceJobs.forEach(existingJob => {
if (
existingJob.jobToken !== jobResponse.state!.job_token ||
!jobStateCanChange(existingJob.jobState)
@@ -640,7 +638,7 @@ class App extends React.Component<Props, State> {
w2lInferenceJobs: updatedJobs,
});
})
.catch((e) => {
.catch(e => {
/* Ignore. */
});
};
@@ -665,8 +663,8 @@ class App extends React.Component<Props, State> {
Accept: "application/json",
},
})
.then((res) => res.json())
.then((response) => {
.then(res => res.json())
.then(response => {
const jobResponse: W2lTemplateUploadJobStateResponsePayload = response;
if (jobResponse === undefined || jobResponse.state === undefined) {
@@ -675,7 +673,7 @@ class App extends React.Component<Props, State> {
let updatedJobs: Array<W2lTemplateUploadJob> = [];
this.state.w2lTemplateUploadJobs.forEach((existingJob) => {
this.state.w2lTemplateUploadJobs.forEach(existingJob => {
if (
existingJob.jobToken !== jobResponse.state!.job_token ||
!jobStateCanChange(existingJob.jobState)
@@ -694,7 +692,7 @@ class App extends React.Component<Props, State> {
w2lTemplateUploadJobs: updatedJobs,
});
})
.catch((e) => {
.catch(e => {
/* Ignore. */
});
};
@@ -714,7 +712,7 @@ class App extends React.Component<Props, State> {
if (GetRemoteDownloadJobStatusIsOk(lookupResult)) {
let updatedJobs: Array<VocoderUploadJob> = [];
this.state.vocoderUploadJobs.forEach((existingJob) => {
this.state.vocoderUploadJobs.forEach(existingJob => {
if (
existingJob.jobToken !== lookupResult.state!.job_token ||
!jobStateCanChange(existingJob.jobState)
@@ -748,7 +746,7 @@ class App extends React.Component<Props, State> {
if (GetRemoteDownloadJobStatusIsOk(lookupResult)) {
let updatedJobs: Array<VocoderUploadJob> = [];
this.state.voiceConversionModelUploadJobs.forEach((existingJob) => {
this.state.voiceConversionModelUploadJobs.forEach(existingJob => {
if (
existingJob.jobToken !== lookupResult.state!.job_token ||
!jobStateCanChange(existingJob.jobState)
@@ -770,37 +768,37 @@ class App extends React.Component<Props, State> {
};
pollJobs = () => {
this.state.inferenceJobs.forEach((job) => {
this.state.inferenceJobs.forEach(job => {
if (jobStateCanChange(job.jobState)) {
this.checkInferenceJob(job.jobToken);
}
});
this.state.ttsInferenceJobs.forEach((job) => {
this.state.ttsInferenceJobs.forEach(job => {
if (jobStateCanChange(job.jobState)) {
this.checkTtsJob(job.jobToken);
}
});
this.state.w2lInferenceJobs.forEach((job) => {
this.state.w2lInferenceJobs.forEach(job => {
if (jobStateCanChange(job.jobState)) {
this.checkW2lJob(job.jobToken);
}
});
this.state.ttsModelUploadJobs.forEach((job) => {
this.state.ttsModelUploadJobs.forEach(job => {
if (jobStateCanChange(job.jobState)) {
this.checkTtsModelUploadJob(job.jobToken);
}
});
this.state.w2lTemplateUploadJobs.forEach((job) => {
this.state.w2lTemplateUploadJobs.forEach(job => {
if (jobStateCanChange(job.jobState)) {
this.checkW2lTemplateUploadJob(job.jobToken);
}
});
this.state.vocoderUploadJobs.forEach((job) => {
this.state.vocoderUploadJobs.forEach(job => {
if (jobStateCanChange(job.jobState)) {
this.checkVocoderUploadJob(job.jobToken);
}
});
this.state.voiceConversionModelUploadJobs.forEach((job) => {
this.state.voiceConversionModelUploadJobs.forEach(job => {
if (jobStateCanChange(job.jobState)) {
this.checkVoiceConversionModelUploadJob(job.jobToken);
}
@@ -843,7 +841,7 @@ class App extends React.Component<Props, State> {
querySession: this.querySession,
querySubscriptions: this.querySessionSubscriptions,
sessionWrapper: this.state.sessionWrapper,
sessionFetched: this.state.sessionFetched
sessionFetched: this.state.sessionFetched,
}}
>
<Switch>
@@ -14,6 +14,11 @@ import { v4 as uuidv4 } from "uuid";
import { UploadMedia } from "@storyteller/components/src/api/media_files/UploadMedia";
import { FrontendInferenceJobType } from "@storyteller/components/src/jobs/InferenceJob";
import FbxToGltfJobList from "./components/FbxToGltfJobList";
import {
EnqueueFbxToGltf,
EnqueueFbxToGltfIsSuccess,
EnqueueFbxToGltfIsError,
} from "@storyteller/components/src/api/file_conversion/EnqueueFbxToGltf";
interface FbxToGltfPageProps {
enqueueInferenceJob: (
@@ -32,12 +37,16 @@ export default function FbxToGltfPage({
mediaToken: mediaToken ?? undefined,
});
const fileProps = useFile({});
const [isSubmitting, setIsSubmitting] = useState(false);
const [isWorking, setIsWorking] = useState(false);
const { inferenceJobs } = useInferenceJobs(
FrontendInferenceJobType.VideoMotionCapture
FrontendInferenceJobType.ConvertFbxtoGltf
);
const hasConversionJobs = inferenceJobs && inferenceJobs.length > 0;
console.log("inferenceJobs", inferenceJobs);
useEffect(() => {
// If there's a mediaToken, automatically prepare the file for conversion
if (mediaToken && presetFile) {
@@ -50,14 +59,6 @@ export default function FbxToGltfPage({
history.push("/fbx-to-gltf");
};
async function EnqueueFbxToGltf(file: any) {
return new Promise(resolve => {
setTimeout(() => {
console.log("EnqueueFbxToGltf", file);
}, 1000);
});
}
const makeFBXUploadRequest = () => ({
uuid_idempotency_token: uuidv4(),
file: fileProps.file,
@@ -69,57 +70,75 @@ export default function FbxToGltfPage({
try {
const res = await UploadMedia(makeFBXUploadRequest());
if (res.success && res.media_file_token) {
return { upload_token: res.upload_token };
return { upload_token: res.media_file_token };
}
// Handle failure scenario - perhaps throw an error or return a specific result
console.error("Upload failed:", res);
return null;
} catch (error) {
console.error("Error in upload:", error);
// Handle the error appropriately
return null;
}
};
const EnqueueConvert = async (params: any) => {
let request: any = {
uuid_idempotency_token: uuidv4(),
file_source: undefined,
upload_token: params.upload_token,
};
const response = await EnqueueFbxToGltf(request);
console.log("Response: ", response);
// if (response.inference_job_token) {
// enqueueInferenceJob(
// response.inference_job_token,
// FrontendInferenceJobType.ConvertFbxtoGltf
// );
// }
};
const uploadAndConvert = async () => {
const submit = async () => {
if (isSubmitting) return;
setIsSubmitting(true);
setIsWorking(true);
try {
const uploadResponse = await handleUploadFBX();
if (uploadResponse && uploadResponse.upload_token) {
await EnqueueConvert({
upload_token: uploadResponse.upload_token,
});
let uploadToken = mediaToken;
// If no media token, upload the file first
if (!mediaToken && fileProps.file) {
const uploadResponse = await handleUploadFBX();
if (uploadResponse && uploadResponse.upload_token) {
uploadToken = uploadResponse.upload_token;
} else {
console.error("Failed to upload file. Response:", uploadResponse);
throw new Error("File upload failed");
}
}
// Enqueue the conversion job
if (uploadToken) {
await EnqueueConvert({ upload_token: uploadToken });
} else {
console.error("No upload token available for conversion");
}
} catch (error) {
console.error("Error uploading file: ", error);
// Handle upload error
console.error("Error in submit process: ", error);
} finally {
setIsWorking(false);
setIsSubmitting(false);
}
};
const submit = async () => {
if (mediaToken && presetFile) {
EnqueueConvert({ upload_token: mediaToken });
} else if (fileProps.file) {
await uploadAndConvert();
} else {
const EnqueueConvert = async ({ upload_token }: any) => {
if (!upload_token) return false;
try {
let request = {
uuid_idempotency_token: uuidv4(),
file_source: undefined,
media_file_token: upload_token,
};
const response = await EnqueueFbxToGltf(request);
if (EnqueueFbxToGltfIsSuccess(response)) {
console.log("Enqueue successful");
if (response && response.inference_job_token) {
enqueueInferenceJob(
response.inference_job_token,
FrontendInferenceJobType.ConvertFbxtoGltf
);
}
return true;
} else if (EnqueueFbxToGltfIsError(response)) {
throw new Error("Enqueue failed");
}
} catch (error) {
console.error("Error in enqueueing conversion: ", error);
return false;
}
};
@@ -179,7 +198,8 @@ export default function FbxToGltfPage({
icon={faArrowRightArrowLeft}
label="Convert to glTF"
onClick={submit}
disabled={!fileProps.file}
disabled={!mediaToken && !fileProps.file}
isLoading={isWorking}
/>
</div>
</div>