forked from 77media/video-flow
更新工作流组件,添加当前阶段状态管理,优化视频生成状态显示逻辑,确保在不同阶段下正确渲染缩略图和视频内容。
This commit is contained in:
parent
cafaf5102a
commit
25988af2c3
@ -54,7 +54,8 @@ const WorkFlow = React.memo(function WorkFlow() {
|
||||
setAnyAttribute,
|
||||
applyScript,
|
||||
fallbackToStep,
|
||||
originalText
|
||||
originalText,
|
||||
currentStage
|
||||
} = useWorkflowData();
|
||||
|
||||
const {
|
||||
@ -184,6 +185,7 @@ const WorkFlow = React.memo(function WorkFlow() {
|
||||
<div className="heroVideo-FIzuK1" style={{ aspectRatio: "16 / 9" }}>
|
||||
<ErrorBoundary>
|
||||
<MediaViewer
|
||||
currentStage={currentStage}
|
||||
scriptData={scriptData}
|
||||
currentStep={currentStep}
|
||||
currentSketchIndex={currentSketchIndex}
|
||||
@ -209,23 +211,27 @@ const WorkFlow = React.memo(function WorkFlow() {
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="imageGrid-ymZV9z hide-scrollbar" style={{ display: (currentStep === '6' || currentStep === '0') ? 'none' : 'block' }}>
|
||||
<ErrorBoundary>
|
||||
<ThumbnailGrid
|
||||
isLoading={isLoading}
|
||||
isPlaying={isPlaying}
|
||||
currentStep={currentStep}
|
||||
currentSketchIndex={currentSketchIndex}
|
||||
taskSketch={taskSketch}
|
||||
taskVideos={taskVideos}
|
||||
isGeneratingSketch={isGeneratingSketch}
|
||||
isGeneratingVideo={isGeneratingVideo}
|
||||
sketchCount={sketchCount}
|
||||
totalSketchCount={totalSketchCount}
|
||||
onSketchSelect={setCurrentSketchIndex}
|
||||
/>
|
||||
</ErrorBoundary>
|
||||
</div>
|
||||
{currentStage !== 'final_video' && currentStage !== 'script' && (
|
||||
<div className="imageGrid-ymZV9z hide-scrollbar">
|
||||
<ErrorBoundary>
|
||||
<ThumbnailGrid
|
||||
currentStage={currentStage}
|
||||
isLoading={isLoading}
|
||||
isPlaying={isPlaying}
|
||||
currentStep={currentStep}
|
||||
currentSketchIndex={currentSketchIndex}
|
||||
taskSketch={taskSketch}
|
||||
taskVideos={taskVideos}
|
||||
isGeneratingSketch={isGeneratingSketch}
|
||||
isGeneratingVideo={isGeneratingVideo}
|
||||
sketchCount={sketchCount}
|
||||
totalSketchCount={totalSketchCount}
|
||||
onSketchSelect={setCurrentSketchIndex}
|
||||
/>
|
||||
</ErrorBoundary>
|
||||
</div>
|
||||
)}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -233,7 +239,7 @@ const WorkFlow = React.memo(function WorkFlow() {
|
||||
|
||||
{/* 暂停/播放按钮 */}
|
||||
{
|
||||
(currentStep !== '6' && currentStep !== '0') && (
|
||||
(currentStage !== 'final_video' && currentStage !== 'script') && (
|
||||
<div className="absolute right-12 bottom-16 z-[49] flex gap-4">
|
||||
<GlassIconButton
|
||||
icon={isPauseWorkFlow ? Play : Pause}
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
import React, { useRef, useEffect, useState, SetStateAction, useMemo } from 'react';
|
||||
import { motion, AnimatePresence } from 'framer-motion';
|
||||
import { Edit3, Play, Pause, Volume2, VolumeX, Maximize, Minimize } from 'lucide-react';
|
||||
import { Edit3, Play, Pause, Volume2, VolumeX, Maximize, Minimize, Loader2, X } from 'lucide-react';
|
||||
import { ProgressiveReveal, presets } from '@/components/ui/progressive-reveal';
|
||||
import { GlassIconButton } from '@/components/ui/glass-icon-button';
|
||||
import { ScriptRenderer } from '@/components/script-renderer/ScriptRenderer';
|
||||
@ -30,6 +30,7 @@ interface MediaViewerProps {
|
||||
isPauseWorkFlow: boolean;
|
||||
applyScript: any;
|
||||
mode: string;
|
||||
currentStage: string;
|
||||
}
|
||||
|
||||
export const MediaViewer = React.memo(function MediaViewer({
|
||||
@ -52,7 +53,8 @@ export const MediaViewer = React.memo(function MediaViewer({
|
||||
setAnyAttribute,
|
||||
isPauseWorkFlow,
|
||||
applyScript,
|
||||
mode
|
||||
mode,
|
||||
currentStage
|
||||
}: MediaViewerProps) {
|
||||
const mainVideoRef = useRef<HTMLVideoElement>(null);
|
||||
const finalVideoRef = useRef<HTMLVideoElement>(null);
|
||||
@ -470,110 +472,56 @@ export const MediaViewer = React.memo(function MediaViewer({
|
||||
onMouseLeave={() => onControlsChange(false)}
|
||||
>
|
||||
{/* 只在生成过程中或没有视频时使用ProgressiveReveal */}
|
||||
{(isGeneratingVideo || !taskVideos[currentSketchIndex]) ? (
|
||||
taskVideos[currentSketchIndex] ? (
|
||||
<ProgressiveReveal
|
||||
key={`generte-video-${currentSketchIndex}`}
|
||||
className="w-full h-full rounded-lg"
|
||||
revealDuration={0.8}
|
||||
blurDuration={0.3}
|
||||
initialBlur={10}
|
||||
customVariants={{
|
||||
hidden: {
|
||||
opacity: 0,
|
||||
scale: 0.9,
|
||||
filter: "blur(30px)",
|
||||
clipPath: "inset(0 100% 0 0)"
|
||||
},
|
||||
visible: {
|
||||
opacity: 1,
|
||||
scale: 1,
|
||||
filter: "blur(0px)",
|
||||
clipPath: "inset(0 0% 0 0)",
|
||||
transition: {
|
||||
duration: 1.5,
|
||||
ease: [0.23, 1, 0.32, 1],
|
||||
opacity: { duration: 0.8, ease: "easeOut" },
|
||||
scale: { duration: 1.2, ease: "easeOut" },
|
||||
filter: { duration: 0.8, delay: 0.4, ease: "easeOut" },
|
||||
clipPath: { duration: 1, ease: "easeInOut" }
|
||||
}
|
||||
}
|
||||
}}
|
||||
loadingBgConfig={{
|
||||
fromColor: `from-[${bgColors[0]}]`,
|
||||
viaColor: `via-[${bgColors[1]}]`,
|
||||
toColor: `to-[${bgColors[2]}]`,
|
||||
glowOpacity: 0.8,
|
||||
duration: 4,
|
||||
}}
|
||||
>
|
||||
<div className="relative w-full h-full">
|
||||
{/* 背景模糊的图片 */}
|
||||
<div className="absolute inset-0 overflow-hidden">
|
||||
<img
|
||||
className="w-full h-full object-cover filter blur-lg scale-110 opacity-50"
|
||||
src={taskSketch[currentSketchIndex]?.url}
|
||||
alt="background"
|
||||
/>
|
||||
<div className="relative w-full h-full">
|
||||
{/* 背景模糊的图片 */}
|
||||
<div className="absolute inset-0 overflow-hidden" style={{background: `url(${taskSketch[currentSketchIndex]?.url}) no-repeat center center`}}>
|
||||
{/* 生成中 */}
|
||||
{taskVideos[currentSketchIndex].video_status === 0 && (
|
||||
<div className="absolute inset-0 bg-black/50 flex items-center justify-center">
|
||||
<div className="text-blue-500 text-2xl font-bold flex items-center gap-2">
|
||||
<Loader2 className="w-10 h-10 animate-spin" />
|
||||
<span>Generating...</span>
|
||||
</div>
|
||||
|
||||
{/* 视频 */}
|
||||
<motion.div
|
||||
initial={{ clipPath: "inset(0 100% 0 0)" }}
|
||||
animate={{ clipPath: "inset(0 0% 0 0)" }}
|
||||
transition={{ duration: 0.8, ease: [0.43, 0.13, 0.23, 0.96] }}
|
||||
className="relative z-10 w-full h-full"
|
||||
>
|
||||
<video
|
||||
ref={mainVideoRef}
|
||||
key={taskVideos[currentSketchIndex].url}
|
||||
className="w-full h-full rounded-lg object-cover object-center relative z-10"
|
||||
src={taskVideos[currentSketchIndex].url}
|
||||
autoPlay={isVideoPlaying}
|
||||
loop={true}
|
||||
playsInline
|
||||
onLoadedData={() => applyVolumeSettings(mainVideoRef.current!)}
|
||||
onEnded={() => {
|
||||
if (isVideoPlaying) {
|
||||
// 自动切换到下一个视频的逻辑在父组件处理
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</motion.div>
|
||||
</div>
|
||||
</ProgressiveReveal>
|
||||
) : (
|
||||
<div className="w-full h-full flex items-center justify-center rounded-lg overflow-hidden relative">
|
||||
<img
|
||||
className="absolute inset-0 w-full h-full object-cover"
|
||||
src={taskSketch[currentSketchIndex]?.url}
|
||||
alt={`Sketch ${currentSketchIndex + 1}`}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
) : (
|
||||
/* 生成完成后直接显示视频,不使用ProgressiveReveal */
|
||||
<div className="relative w-full h-full">
|
||||
|
||||
{/* 视频 修复播放没有声音 */}
|
||||
<video
|
||||
ref={mainVideoRef}
|
||||
key={taskVideos[currentSketchIndex].url}
|
||||
className="w-full h-full rounded-lg object-cover object-center relative z-10"
|
||||
src={taskVideos[currentSketchIndex].url}
|
||||
autoPlay={isVideoPlaying}
|
||||
loop={true}
|
||||
playsInline
|
||||
onLoadedData={() => applyVolumeSettings(mainVideoRef.current!)}
|
||||
onEnded={() => {
|
||||
if (isVideoPlaying) {
|
||||
// 自动切换到下一个视频的逻辑在父组件处理
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{/* 生成失败 */}
|
||||
{taskVideos[currentSketchIndex].video_status === 2 && (
|
||||
<div className="absolute inset-0 bg-red-500 flex items-center justify-center">
|
||||
<div className="text-red-500 text-2xl font-bold flex items-center gap-2">
|
||||
<X className="w-10 h-10" />
|
||||
<span>Failed</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 视频 多个 取第一个 */}
|
||||
{ taskVideos[currentSketchIndex].url && (
|
||||
<motion.div
|
||||
initial={{ clipPath: "inset(0 100% 0 0)" }}
|
||||
animate={{ clipPath: "inset(0 0% 0 0)" }}
|
||||
transition={{ duration: 0.8, ease: [0.43, 0.13, 0.23, 0.96] }}
|
||||
className="relative z-10 w-full h-full"
|
||||
>
|
||||
<video
|
||||
ref={mainVideoRef}
|
||||
key={taskVideos[currentSketchIndex].url[0]}
|
||||
className="w-full h-full rounded-lg object-cover object-center relative z-10"
|
||||
src={taskVideos[currentSketchIndex].url[0]}
|
||||
autoPlay={isVideoPlaying}
|
||||
loop={true}
|
||||
playsInline
|
||||
onLoadedData={() => applyVolumeSettings(mainVideoRef.current!)}
|
||||
onEnded={() => {
|
||||
if (isVideoPlaying) {
|
||||
// 自动切换到下一个视频的逻辑在父组件处理
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</motion.div>
|
||||
)}
|
||||
|
||||
</div>
|
||||
|
||||
{/* 操作按钮组 */}
|
||||
<AnimatePresence>
|
||||
@ -610,21 +558,6 @@ export const MediaViewer = React.memo(function MediaViewer({
|
||||
whileTap={{ scale: 0.9 }}
|
||||
className="relative"
|
||||
>
|
||||
{/* 播放时的发光效果 */}
|
||||
{isVideoPlaying && (
|
||||
<motion.div
|
||||
className="absolute inset-0 rounded-full blur-md"
|
||||
animate={{
|
||||
scale: [1, 1.2, 1],
|
||||
opacity: [0.5, 0.8, 0.5]
|
||||
}}
|
||||
transition={{
|
||||
duration: 2,
|
||||
repeat: Infinity,
|
||||
ease: "easeInOut"
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<GlassIconButton
|
||||
icon={isVideoPlaying ? Pause : Play}
|
||||
tooltip={isVideoPlaying ? "Pause video" : "Play video"}
|
||||
@ -857,16 +790,15 @@ export const MediaViewer = React.memo(function MediaViewer({
|
||||
};
|
||||
|
||||
// 根据当前步骤渲染对应内容
|
||||
if (Number(currentStep) === 6 || Number(currentStep) === 5.5) {
|
||||
console.log('1111111111111111', 1111111111111111)
|
||||
if (currentStage === 'final_video') {
|
||||
return renderFinalVideo(currentStep);
|
||||
}
|
||||
|
||||
if (Number(currentStep) > 2 && Number(currentStep) < 6) {
|
||||
if (currentStage === 'video') {
|
||||
return renderVideoContent();
|
||||
}
|
||||
|
||||
if (Number(currentStep) === 0) {
|
||||
if (currentStage === 'script') {
|
||||
return renderScriptContent();
|
||||
}
|
||||
|
||||
|
||||
@ -168,11 +168,11 @@ export function TaskInfo({
|
||||
setCurrentStage(2);
|
||||
|
||||
// 延迟8s 再次打开
|
||||
timerRef.current = setTimeout(() => {
|
||||
setIsScriptModalOpen(true);
|
||||
}, 8000);
|
||||
// timerRef.current = setTimeout(() => {
|
||||
// setIsScriptModalOpen(true);
|
||||
// }, 8000);
|
||||
} else {
|
||||
setIsScriptModalOpen(true);
|
||||
// setIsScriptModalOpen(true);
|
||||
setCurrentStage(2);
|
||||
}
|
||||
}
|
||||
@ -180,7 +180,7 @@ export function TaskInfo({
|
||||
if (isScriptModalOpen) {
|
||||
setIsScriptModalOpen(false);
|
||||
}
|
||||
setIsScriptModalOpen(true);
|
||||
// setIsScriptModalOpen(true);
|
||||
setCurrentStage(2);
|
||||
}
|
||||
if (currentLoadingText.includes('sketch')) {
|
||||
@ -190,11 +190,11 @@ export function TaskInfo({
|
||||
setCurrentStage(1);
|
||||
|
||||
// 延迟8s 再次打开
|
||||
timerRef.current = setTimeout(() => {
|
||||
setIsScriptModalOpen(true);
|
||||
}, 8000);
|
||||
// timerRef.current = setTimeout(() => {
|
||||
// setIsScriptModalOpen(true);
|
||||
// }, 8000);
|
||||
} else {
|
||||
setIsScriptModalOpen(true);
|
||||
// setIsScriptModalOpen(true);
|
||||
setCurrentStage(1);
|
||||
}
|
||||
}
|
||||
@ -202,7 +202,7 @@ export function TaskInfo({
|
||||
if (isScriptModalOpen) {
|
||||
setIsScriptModalOpen(false);
|
||||
}
|
||||
setIsScriptModalOpen(true);
|
||||
// setIsScriptModalOpen(true);
|
||||
setCurrentStage(1);
|
||||
}
|
||||
if (currentLoadingText.includes('script')) {
|
||||
|
||||
@ -4,6 +4,7 @@ import React, { useRef, useEffect, useState } from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { Skeleton } from '@/components/ui/skeleton';
|
||||
import { ProgressiveReveal, presets } from '@/components/ui/progressive-reveal';
|
||||
import { Loader2, X } from 'lucide-react';
|
||||
|
||||
interface ThumbnailGridProps {
|
||||
isLoading: boolean;
|
||||
@ -17,6 +18,7 @@ interface ThumbnailGridProps {
|
||||
sketchCount: number;
|
||||
totalSketchCount: number;
|
||||
onSketchSelect: (index: number) => void;
|
||||
currentStage: string;
|
||||
}
|
||||
|
||||
export function ThumbnailGrid({
|
||||
@ -30,7 +32,8 @@ export function ThumbnailGrid({
|
||||
isGeneratingVideo,
|
||||
sketchCount,
|
||||
totalSketchCount,
|
||||
onSketchSelect
|
||||
onSketchSelect,
|
||||
currentStage
|
||||
}: ThumbnailGridProps) {
|
||||
const thumbnailsRef = useRef<HTMLDivElement>(null);
|
||||
const [isDragging, setIsDragging] = useState(false);
|
||||
@ -211,78 +214,47 @@ export function ThumbnailGrid({
|
||||
${currentSketchIndex === index ? 'ring-2 ring-blue-500 z-10' : 'hover:ring-2 hover:ring-blue-500/50'}`}
|
||||
onClick={() => !isDragging && onSketchSelect(index)}
|
||||
>
|
||||
{/* 底层草图,始终显示 未生成对应的视频时显示的草图模糊掉 */}
|
||||
<div className="w-full h-full transform hover:scale-105 transition-transform duration-500">
|
||||
<img
|
||||
className={`w-full h-full object-cover transition-all duration-300 ${
|
||||
(!taskSketch[index] && !isPlaying) ? 'filter blur-sm opacity-60' : ''
|
||||
}`}
|
||||
src={taskSketch[index] ? taskSketch[index].url : video.url}
|
||||
alt={`Thumbnail ${index + 1}`}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 视频层,只在有视频时用ProgressiveReveal动画显示 */}
|
||||
{taskVideos[index] && (
|
||||
<div className="absolute inset-0">
|
||||
{isGeneratingVideo ? (
|
||||
<ProgressiveReveal
|
||||
key={`video-thumbnail-generating-${index}`}
|
||||
revealDuration={0.8}
|
||||
blurDuration={0.3}
|
||||
initialBlur={10}
|
||||
delay={index === currentSketchIndex ? 0 : index * 0.1}
|
||||
customVariants={{
|
||||
hidden: {
|
||||
opacity: 0,
|
||||
scale: 0.95,
|
||||
filter: "blur(10px)"
|
||||
},
|
||||
visible: {
|
||||
opacity: 1,
|
||||
scale: 1,
|
||||
filter: "blur(0px)",
|
||||
transition: {
|
||||
duration: 0.8,
|
||||
ease: [0.23, 1, 0.32, 1],
|
||||
opacity: { duration: 0.6, ease: "easeInOut" },
|
||||
scale: { duration: 1, ease: "easeOut" },
|
||||
filter: { duration: 0.8, ease: "easeOut", delay: 0.2 }
|
||||
}
|
||||
}
|
||||
}}
|
||||
loadingBgConfig={{
|
||||
fromColor: `from-[${bgColors[0]}]`,
|
||||
viaColor: `via-[${bgColors[1]}]`,
|
||||
toColor: `to-[${bgColors[2]}]`,
|
||||
glowOpacity: 0.4,
|
||||
duration: 4
|
||||
}}
|
||||
>
|
||||
<div className="w-full h-full transform hover:scale-105 transition-transform duration-500">
|
||||
<video
|
||||
className="w-full h-full object-cover"
|
||||
src={taskVideos[index].url}
|
||||
playsInline
|
||||
loop
|
||||
muted
|
||||
/>
|
||||
</div>
|
||||
</ProgressiveReveal>
|
||||
) : (
|
||||
/* 生成完成后直接显示视频,不使用ProgressiveReveal */
|
||||
<div className="w-full h-full transform hover:scale-105 transition-transform duration-500">
|
||||
<video
|
||||
className="w-full h-full object-cover"
|
||||
src={taskVideos[index].url}
|
||||
playsInline
|
||||
loop
|
||||
muted
|
||||
/>
|
||||
{/* 视频层 */}
|
||||
<div className="relative w-full h-full transform hover:scale-105 transition-transform duration-500">
|
||||
{taskVideos[index].video_status === 0 && (
|
||||
<div className="absolute inset-0 bg-black/50 flex items-center justify-center z-20">
|
||||
<div className="text-blue-500 text-xl font-bold flex items-center gap-2">
|
||||
<Loader2 className="w-10 h-10 animate-spin" />
|
||||
<span>Generating...</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{taskVideos[index].video_status === 2 && (
|
||||
<div className="absolute inset-0 bg-red-500 flex items-center justify-center z-20">
|
||||
<div className="text-red-500 text-xl font-bold flex items-center gap-2">
|
||||
<X className="w-10 h-10" />
|
||||
<span>Failed</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{taskVideos[index].url ? (
|
||||
<video
|
||||
className="w-full h-full object-cover"
|
||||
src={taskVideos[index].url[0]}
|
||||
playsInline
|
||||
loop
|
||||
muted
|
||||
/>
|
||||
) : (
|
||||
<div className="w-full h-full transform hover:scale-105 transition-transform duration-500">
|
||||
<img
|
||||
className={`w-full h-full object-cover transition-all duration-300 ${
|
||||
(!taskSketch[index] && !isPlaying) ? 'filter blur-sm opacity-60' : ''
|
||||
}`}
|
||||
src={taskSketch[index] ? taskSketch[index].url : video.url}
|
||||
alt={`Thumbnail ${index + 1}`}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
</div>
|
||||
|
||||
<div className="absolute bottom-0 left-0 right-0 p-2 bg-gradient-to-t from-black/60 to-transparent z-10">
|
||||
<span className="text-xs text-white/90">Scene {index + 1}</span>
|
||||
@ -381,7 +353,7 @@ export function ThumbnailGrid({
|
||||
onFocus={() => setIsFocused(true)}
|
||||
onBlur={() => setIsFocused(false)}
|
||||
>
|
||||
{Number(currentStep) > 2 && taskVideos.length > 0 && Number(currentStep) < 6
|
||||
{currentStage === 'video'
|
||||
? renderVideoThumbnails()
|
||||
: renderSketchThumbnails()
|
||||
}
|
||||
|
||||
@ -82,19 +82,25 @@ export function useWorkflowData() {
|
||||
const [needStreamData, setNeedStreamData] = useState(false);
|
||||
const [isPauseWorkFlow, setIsPauseWorkFlow] = useState(false);
|
||||
const [mode, setMode] = useState<'automatic' | 'manual' | 'auto'>('automatic');
|
||||
const [currentStage, setCurrentStage] = useState<'script' | 'character' | 'sketch' | 'shot_sketch' | 'video' | 'final_video'>('script');
|
||||
|
||||
let taskData: any = {
|
||||
sketch: { data: [], total_count: -1 },
|
||||
character: { data: [], total_count: -1 },
|
||||
shot_sketch: { data: [], total_count: -1 },
|
||||
video: { data: [], total_count: -1 },
|
||||
status: '0'
|
||||
status: '0',
|
||||
currentStage: 'script'
|
||||
};
|
||||
let loadingText: any = LOADING_TEXT_MAP.initializing;
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
const { sketchCount, videoCount } = useAppSelector((state) => state.workflow);
|
||||
|
||||
useEffect(() => {
|
||||
console.log('---------currentStage', currentStage);
|
||||
}, [currentStage]);
|
||||
|
||||
const {
|
||||
scriptBlocksMemo, // 渲染剧本数据
|
||||
initializeFromProject,
|
||||
@ -233,6 +239,7 @@ export function useWorkflowData() {
|
||||
final?: any;
|
||||
needStreamData?: boolean;
|
||||
totalSketchCount?: number;
|
||||
currentStage?: string;
|
||||
} = {};
|
||||
|
||||
for (const task of all_task_data) {
|
||||
@ -241,6 +248,7 @@ export function useWorkflowData() {
|
||||
taskData.status = '1';
|
||||
const realSketchResultData = task.task_result.data.filter((item: any) => item.image_path);
|
||||
if (realSketchResultData.length >= 0) {
|
||||
taskData.currentStage = 'sketch';
|
||||
// 正在生成草图中 替换 sketch 数据
|
||||
const sketchList = [];
|
||||
for (const sketch of realSketchResultData) {
|
||||
@ -270,6 +278,7 @@ export function useWorkflowData() {
|
||||
|
||||
if (task.task_name === 'generate_character' && (task.task_status !== 'COMPLETED' || taskData.character.total_count !== taskData.character.data.length)) {
|
||||
if (task.task_result.data.length >= 0 && roles.length !== task.task_result.data.length) {
|
||||
taskData.currentStage = 'character';
|
||||
// 正在生成角色中 替换角色数据
|
||||
const characterList = [];
|
||||
for (const character of task.task_result.data) {
|
||||
@ -299,6 +308,7 @@ export function useWorkflowData() {
|
||||
if (task.task_name === 'generate_shot_sketch' && (task.task_status !== 'COMPLETED' || taskData.shot_sketch.total_count !== taskData.shot_sketch.data.length)) {
|
||||
const realShotResultData = task.task_result.data.filter((item: any) => item.url);
|
||||
if (realShotResultData.length >= 0) {
|
||||
taskData.currentStage = 'shot_sketch';
|
||||
taskData.status = '1';
|
||||
console.log('----------正在生成草图中 替换 sketch 数据', taskShotSketch.length, realShotResultData.length);
|
||||
// 正在生成草图中 替换 sketch 数据
|
||||
@ -331,24 +341,32 @@ export function useWorkflowData() {
|
||||
}
|
||||
|
||||
if (task.task_name === 'generate_videos' && (task.task_status !== 'COMPLETED' || taskData.video.total_count !== taskData.video.data.length)) {
|
||||
const realTaskResultData = task.task_result.data.filter((item: any) => item.urls && item.urls.length > 0);
|
||||
if (realTaskResultData.length >= 0) {
|
||||
console.log('----------正在生成视频中', realTaskResultData.length);
|
||||
if (task.task_result.data) {
|
||||
const realTaskResultData = task.task_result.data.filter((item: any) => (item.urls || (item.video_status !== 0 && item.video_status !== undefined)));
|
||||
// 正在生成视频中 替换视频数据
|
||||
const videoList = [];
|
||||
for (const video of realTaskResultData) {
|
||||
let video_status = 0;
|
||||
for (const video of task.task_result.data) {
|
||||
// 适配旧数据
|
||||
video_status = video.video_status === undefined ? (video.urls ? 1 : 0) : video.video_status;
|
||||
video_status = task.task_status === 'COMPLETED' && video_status === 0 ? 2 : video_status;
|
||||
// 每一项 video 有多个视频 先默认取第一个
|
||||
videoList.push({
|
||||
url: video.urls && video.urls.length > 0 ? video.urls.find((url: string) => url) : null,
|
||||
url: video.urls,
|
||||
script: video.description,
|
||||
audio: null,
|
||||
video_id: video.video_id,
|
||||
video_status: video_status, // 0 生成中 1 生成完成 2 生成失败
|
||||
});
|
||||
}
|
||||
if (realTaskResultData.length > 0) {
|
||||
taskData.currentStage = 'video';
|
||||
}
|
||||
console.log('----------正在生成视频中', realTaskResultData.length);
|
||||
taskData.video.data = videoList;
|
||||
stateUpdates.taskVideos = videoList;
|
||||
stateUpdates.isGeneratingVideo = true;
|
||||
loadingText = LOADING_TEXT_MAP.video(videoList.length, task.task_result.total_count);
|
||||
loadingText = LOADING_TEXT_MAP.video(realTaskResultData.length, task.task_result.total_count);
|
||||
}
|
||||
if (task.task_status === 'COMPLETED') {
|
||||
console.log('----------视频生成完成');
|
||||
@ -368,6 +386,7 @@ export function useWorkflowData() {
|
||||
// 粗剪
|
||||
if (task.task_name === 'generate_final_simple_video') {
|
||||
if (task.task_result && task.task_result.video) {
|
||||
taskData.currentStage = 'final_video';
|
||||
stateUpdates.final = {
|
||||
url: task.task_result.video,
|
||||
};
|
||||
@ -379,6 +398,7 @@ export function useWorkflowData() {
|
||||
// 最终剪辑
|
||||
if (task.task_name === 'generate_final_video') {
|
||||
if (task.task_result && task.task_result.video) {
|
||||
taskData.currentStage = 'final_video';
|
||||
stateUpdates.final = {
|
||||
url: task.task_result.video,
|
||||
};
|
||||
@ -415,6 +435,7 @@ export function useWorkflowData() {
|
||||
if (stateUpdates.taskSketch) updateSketchCount(stateUpdates.taskSketch.length);
|
||||
if (stateUpdates.taskVideos) updateVideoCount(stateUpdates.taskVideos.length);
|
||||
|
||||
if (stateUpdates.currentStage) taskData.currentStage = stateUpdates.currentStage;
|
||||
// 更新 taskObject
|
||||
if (stateUpdates.currentStep) {
|
||||
setTaskObject(prev => {
|
||||
@ -500,6 +521,7 @@ export function useWorkflowData() {
|
||||
// 如果有已完成的数据,同步到状态
|
||||
if (data) {
|
||||
if (data.sketch && data.sketch.data) {
|
||||
taskData.currentStage = 'sketch';
|
||||
taskData.status = '1';
|
||||
const realSketchResultData = data.sketch.data.filter((item: any) => item.image_path);
|
||||
const sketchList = [];
|
||||
@ -526,6 +548,7 @@ export function useWorkflowData() {
|
||||
}
|
||||
}
|
||||
if (data.character && data.character.data && data.character.data.length > 0) {
|
||||
taskData.currentStage = 'character';
|
||||
const characterList = [];
|
||||
for (const character of data.character.data) {
|
||||
characterList.push({
|
||||
@ -549,6 +572,7 @@ export function useWorkflowData() {
|
||||
}
|
||||
}
|
||||
if (data.shot_sketch && data.shot_sketch.data) {
|
||||
taskData.currentStage = 'shot_sketch';
|
||||
const realShotResultData = data.shot_sketch.data.filter((item: any) => item.url);
|
||||
const sketchList = [];
|
||||
for (const sketch of realShotResultData) {
|
||||
@ -575,43 +599,46 @@ export function useWorkflowData() {
|
||||
}
|
||||
}
|
||||
if (data.video.data) {
|
||||
const realDataVideoData = data.video.data.filter((item: any) => item.urls && item.urls.length > 0);
|
||||
const realDataVideoData = data.video.data.filter((item: any) => (item.urls || (item.video_status !== 0 && item.video_status !== undefined)));
|
||||
if (realDataVideoData.length === 0 && taskData.status === '3') {
|
||||
loadingText = LOADING_TEXT_MAP.video(0, data.video.total_count);
|
||||
}
|
||||
if (realDataVideoData.length > 0) {
|
||||
const videoList = [];
|
||||
console.log('----------data.video.data', data.video.data);
|
||||
for (const video of realDataVideoData) {
|
||||
// 每一项 video 有多个视频 默认取存在的项
|
||||
videoList.push({
|
||||
url: video.urls && video.urls.length > 0 ? video.urls.find((url: string) => url) : null,
|
||||
script: video.description,
|
||||
audio: null,
|
||||
video_id: video.video_id,
|
||||
});
|
||||
}
|
||||
taskData.video.data = videoList;
|
||||
taskData.video.total_count = data.video.total_count;
|
||||
setTaskVideos(videoList);
|
||||
updateVideoCount(videoList.length);
|
||||
// 如果在视频步骤,设置为最后一个视频
|
||||
if (data.video.total_count > realDataVideoData.length) {
|
||||
setIsGeneratingVideo(true);
|
||||
loadingText = LOADING_TEXT_MAP.video(realDataVideoData.length, data.video.total_count);
|
||||
} else {
|
||||
taskData.status = '4';
|
||||
loadingText = LOADING_TEXT_MAP.audio;
|
||||
taskData.currentStage = 'video';
|
||||
}
|
||||
const videoList = [];
|
||||
console.log('----------data.video.data', data.video.data);
|
||||
for (const video of data.video.data) {
|
||||
// 每一项 video 有多个视频 默认取存在的项
|
||||
videoList.push({
|
||||
url: video.urls,
|
||||
script: video.description,
|
||||
audio: null,
|
||||
video_id: video.video_id,
|
||||
video_status: video.video_status === undefined ? (video.urls ? 1 : 0) : video.video_status, // 0 生成中 1 生成完成 2 生成失败
|
||||
});
|
||||
}
|
||||
taskData.video.data = videoList;
|
||||
taskData.video.total_count = data.video.total_count;
|
||||
setTaskVideos(videoList);
|
||||
updateVideoCount(videoList.length);
|
||||
// 如果在视频步骤,设置为最后一个视频
|
||||
if (data.video.total_count > realDataVideoData.length) {
|
||||
setIsGeneratingVideo(true);
|
||||
loadingText = LOADING_TEXT_MAP.video(realDataVideoData.length, data.video.total_count);
|
||||
} else {
|
||||
taskData.status = '4';
|
||||
loadingText = LOADING_TEXT_MAP.audio;
|
||||
|
||||
// 暂时没有音频生成 直接跳过
|
||||
taskData.status = '5';
|
||||
loadingText = LOADING_TEXT_MAP.postProduction('generating rough cut video...');
|
||||
}
|
||||
// 暂时没有音频生成 直接跳过
|
||||
taskData.status = '5';
|
||||
loadingText = LOADING_TEXT_MAP.postProduction('generating rough cut video...');
|
||||
}
|
||||
}
|
||||
|
||||
// 粗剪
|
||||
if ((data as any).final_simple_video && (data as any).final_simple_video.video) {
|
||||
taskData.currentStage = 'final_video';
|
||||
setFinal({
|
||||
url: (data as any).final_simple_video.video
|
||||
});
|
||||
@ -620,6 +647,7 @@ export function useWorkflowData() {
|
||||
}
|
||||
|
||||
if (data.final_video && data.final_video.video) {
|
||||
taskData.currentStage = 'final_video';
|
||||
setFinal({
|
||||
url: data.final_video.video
|
||||
});
|
||||
@ -631,6 +659,7 @@ export function useWorkflowData() {
|
||||
console.log('---look-taskData', taskData);
|
||||
|
||||
// 设置步骤
|
||||
setCurrentStage(taskData.currentStage);
|
||||
setCurrentStep(taskData.status);
|
||||
setTaskObject(prev => {
|
||||
if (!prev) return null;
|
||||
@ -718,6 +747,7 @@ export function useWorkflowData() {
|
||||
setAnyAttribute,
|
||||
applyScript,
|
||||
fallbackToStep,
|
||||
originalText
|
||||
originalText,
|
||||
currentStage
|
||||
};
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user