forked from 77media/video-flow
240 lines
7.5 KiB
TypeScript
240 lines
7.5 KiB
TypeScript
'use client';
|
|
|
|
import { useState, useEffect, useRef, useCallback } from 'react';
|
|
|
|
const MOCK_SKETCH_URLS = [
|
|
'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-1.jpg',
|
|
'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-2.jpg',
|
|
'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-3.jpg',
|
|
'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-4.jpg',
|
|
];
|
|
|
|
const MOCK_SKETCH_SCRIPT = [
|
|
'script-123',
|
|
'script-123',
|
|
'script-123',
|
|
'script-123',
|
|
];
|
|
|
|
const MOCK_VIDEO_URLS = [
|
|
'https://cdn.qikongjian.com/videos/1750385931_99a8fb42-af89-4ae9-841a-a49869f026bd_text_to_video_0.mp4',
|
|
'https://cdn.qikongjian.com/videos/1750389908_37d4fffa-8516-43a3-a423-fc0274f40e8a_text_to_video_0.mp4',
|
|
'https://cdn.qikongjian.com/videos/1750384661_d8e30b79-828e-48cd-9025-ab62a996717c_text_to_video_0.mp4',
|
|
'https://cdn.qikongjian.com/videos/1750320040_4b47996e-7c70-490e-8433-80c7df990fdd_text_to_video_0.mp4',
|
|
];
|
|
|
|
const MOCK_SKETCH_COUNT = 8;
|
|
|
|
export function useWorkflowData() {
|
|
const [taskObject, setTaskObject] = useState<any>(null);
|
|
const [taskSketch, setTaskSketch] = useState<any[]>([]);
|
|
const [taskVideos, setTaskVideos] = useState<any[]>([]);
|
|
const [sketchCount, setSketchCount] = useState(0);
|
|
const [isLoading, setIsLoading] = useState(true);
|
|
const [currentStep, setCurrentStep] = useState('0');
|
|
const [currentSketchIndex, setCurrentSketchIndex] = useState(0);
|
|
const [isGeneratingSketch, setIsGeneratingSketch] = useState(false);
|
|
const [isGeneratingVideo, setIsGeneratingVideo] = useState(false);
|
|
const [currentLoadingText, setCurrentLoadingText] = useState('加载中...');
|
|
|
|
// 模拟接口请求 获取任务详情
|
|
const getTaskDetail = async (taskId: string) => {
|
|
const data = {
|
|
projectId: 'projectId-123',
|
|
projectName: "Project 1",
|
|
taskId: taskId,
|
|
taskName: "Task 1",
|
|
taskDescription: "Task 1 Description",
|
|
taskStatus: "1",
|
|
taskProgress: 0,
|
|
mode: 'auto',
|
|
resolution: '1080p',
|
|
};
|
|
return data;
|
|
};
|
|
|
|
// 模拟接口请求 每次获取一个分镜草图 轮询获取
|
|
const getTaskSketch = async (taskId: string) => {
|
|
if (isGeneratingSketch || taskSketch.length > 0) return;
|
|
|
|
setIsGeneratingSketch(true);
|
|
setTaskSketch([]);
|
|
|
|
// 模拟分批获取分镜草图
|
|
for (let i = 0; i < MOCK_SKETCH_COUNT; i++) {
|
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
|
|
const newSketch = {
|
|
id: `sketch-${i}`,
|
|
url: MOCK_SKETCH_URLS[i % MOCK_SKETCH_URLS.length],
|
|
script: MOCK_SKETCH_SCRIPT[i % MOCK_SKETCH_SCRIPT.length],
|
|
status: 'done'
|
|
};
|
|
|
|
setTaskSketch(prev => {
|
|
if (prev.find(sketch => sketch.id === newSketch.id)) {
|
|
return prev;
|
|
}
|
|
return [...prev, newSketch];
|
|
});
|
|
setCurrentSketchIndex(i);
|
|
setSketchCount(i + 1);
|
|
}
|
|
|
|
setIsGeneratingSketch(false);
|
|
};
|
|
|
|
// 模拟接口请求 每次获取一个角色 轮询获取
|
|
const getTaskRole = async (taskId: string) => {
|
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
};
|
|
|
|
// 模拟接口请求 获取背景音
|
|
const getTaskBackgroundAudio = async (taskId: string) => {
|
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
};
|
|
|
|
// 模拟接口请求 获取最终成品
|
|
const getTaskFinalProduct = async (taskId: string) => {
|
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
};
|
|
|
|
// 模拟接口请求 每次获取一个分镜视频 轮询获取
|
|
const getTaskVideo = async (taskId: string) => {
|
|
setIsGeneratingVideo(true);
|
|
setTaskVideos([]);
|
|
|
|
// 模拟分批获取分镜视频
|
|
for (let i = 0; i < MOCK_SKETCH_COUNT; i++) {
|
|
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
|
|
const newVideo = {
|
|
id: `video-${i}`,
|
|
url: MOCK_VIDEO_URLS[i % MOCK_VIDEO_URLS.length],
|
|
script: MOCK_SKETCH_SCRIPT[i % MOCK_SKETCH_SCRIPT.length],
|
|
status: 'done'
|
|
};
|
|
|
|
setTaskVideos(prev => {
|
|
if (prev.find(video => video.id === newVideo.id)) {
|
|
return prev;
|
|
}
|
|
return [...prev, newVideo];
|
|
});
|
|
setCurrentSketchIndex(i);
|
|
}
|
|
|
|
setIsGeneratingVideo(false);
|
|
};
|
|
|
|
// 更新加载文字
|
|
useEffect(() => {
|
|
if (isLoading) {
|
|
setCurrentLoadingText('正在加载任务信息...');
|
|
return;
|
|
}
|
|
|
|
if (currentStep === '1') {
|
|
if (isGeneratingSketch) {
|
|
setCurrentLoadingText(`正在生成分镜草图 ${sketchCount + 1}/${MOCK_SKETCH_COUNT}...`);
|
|
} else {
|
|
setCurrentLoadingText('分镜草图生成完成');
|
|
}
|
|
} else if (currentStep === '2') {
|
|
setCurrentLoadingText('正在绘制角色...');
|
|
} else if (currentStep === '3') {
|
|
if (isGeneratingVideo) {
|
|
setCurrentLoadingText(`正在生成分镜视频 ${taskVideos.length + 1}/${taskSketch.length}...`);
|
|
} else {
|
|
setCurrentLoadingText('分镜视频生成完成');
|
|
}
|
|
} else if (currentStep === '4') {
|
|
setCurrentLoadingText('正在生成背景音...');
|
|
} else if (currentStep === '5') {
|
|
setCurrentLoadingText('正在生成最终成品...');
|
|
} else {
|
|
setCurrentLoadingText('任务完成');
|
|
}
|
|
}, [isLoading, currentStep, isGeneratingSketch, sketchCount, isGeneratingVideo, taskVideos.length, taskSketch.length]);
|
|
|
|
// 初始化数据
|
|
useEffect(() => {
|
|
const taskId = localStorage.getItem("taskId") || "taskId-123";
|
|
getTaskDetail(taskId).then(async (data) => {
|
|
setTaskObject(data);
|
|
setIsLoading(false);
|
|
setCurrentStep('1');
|
|
|
|
// 只在任务详情加载完成后获取分镜草图
|
|
await getTaskSketch(taskId);
|
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
|
|
// 修改 taskObject 下的 taskStatus 为 '2'
|
|
setTaskObject((prev: any) => ({
|
|
...prev,
|
|
taskStatus: '2'
|
|
}));
|
|
setCurrentStep('2');
|
|
|
|
// 获取分镜草图后,开始绘制角色
|
|
await getTaskRole(taskId);
|
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
|
|
// 修改 taskObject 下的 taskStatus 为 '3'
|
|
setTaskObject((prev: any) => ({
|
|
...prev,
|
|
taskStatus: '3'
|
|
}));
|
|
setCurrentStep('3');
|
|
|
|
// 获取绘制角色后,开始获取分镜视频
|
|
await getTaskVideo(taskId);
|
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
|
|
// 修改 taskObject 下的 taskStatus 为 '4'
|
|
setTaskObject((prev: any) => ({
|
|
...prev,
|
|
taskStatus: '4'
|
|
}));
|
|
setCurrentStep('4');
|
|
|
|
// 获取分镜视频后,开始获取背景音
|
|
await getTaskBackgroundAudio(taskId);
|
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
|
|
// 修改 taskObject 下的 taskStatus 为 '5'
|
|
setTaskObject((prev: any) => ({
|
|
...prev,
|
|
taskStatus: '5'
|
|
}));
|
|
setCurrentStep('5');
|
|
|
|
// 获取背景音后,开始获取最终成品
|
|
await getTaskFinalProduct(taskId);
|
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
|
|
// 修改 taskObject 下的 taskStatus 为 '6'
|
|
setTaskObject((prev: any) => ({
|
|
...prev,
|
|
taskStatus: '6'
|
|
}));
|
|
setCurrentStep('6');
|
|
});
|
|
}, []);
|
|
|
|
return {
|
|
// 状态数据
|
|
taskObject,
|
|
taskSketch,
|
|
taskVideos,
|
|
sketchCount,
|
|
isLoading,
|
|
currentStep,
|
|
currentSketchIndex,
|
|
isGeneratingSketch,
|
|
isGeneratingVideo,
|
|
currentLoadingText,
|
|
// 操作方法
|
|
setCurrentSketchIndex,
|
|
};
|
|
}
|