修复bug

This commit is contained in:
北枳 2025-08-29 07:56:58 +08:00
parent e420d835be
commit 7296baaf2a
6 changed files with 36 additions and 96 deletions

View File

@ -680,10 +680,6 @@ export interface TaskObject {
data: Scene[]; data: Scene[];
total_count: number; total_count: number;
}; // 场景 }; // 场景
shot_sketch: {
data: ShotSketch[];
total_count: number;
}; // 分镜草图
videos: { videos: {
data: ShotVideo[]; data: ShotVideo[];
total_count: number; total_count: number;

View File

@ -206,7 +206,7 @@ export default function CreateToVideo2() {
<div className="p-4"> <div className="p-4">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<h2 className="text-sm font-medium text-white line-clamp-1"> <h2 className="text-sm font-medium text-white line-clamp-1">
{project.name || "Unnamed"} {/* {project.name || "Unnamed"} */}
</h2> </h2>
</div> </div>
</div> </div>

View File

@ -333,7 +333,7 @@ export const MediaViewer = React.memo(function MediaViewer({
</motion.div> </motion.div>
{/* 操作按钮组 */} {/* 操作按钮组 */}
<AnimatePresence> {/* <AnimatePresence>
<motion.div <motion.div
className="absolute top-4 right-4 z-10 gap-2 hidden group-hover:flex" className="absolute top-4 right-4 z-10 gap-2 hidden group-hover:flex"
initial={{ opacity: 0, y: -10 }} initial={{ opacity: 0, y: -10 }}
@ -346,7 +346,7 @@ export const MediaViewer = React.memo(function MediaViewer({
onClick={() => handleEditClick('3', 'final')} onClick={() => handleEditClick('3', 'final')}
/> />
</motion.div> </motion.div>
</AnimatePresence> </AnimatePresence> */}
{/* 视频信息浮层 */} {/* 视频信息浮层 */}
<motion.div <motion.div
@ -430,7 +430,7 @@ export const MediaViewer = React.memo(function MediaViewer({
> >
{/* 背景模糊的图片 */} {/* 背景模糊的图片 */}
{taskObject.videos.data[currentSketchIndex].video_status !== 1 && ( {taskObject.videos.data[currentSketchIndex].video_status !== 1 && (
<div className="absolute inset-0 overflow-hidden z-20" style={{background: `url(${taskObject.shot_sketch.data[currentSketchIndex]?.url}) no-repeat center center`}}> <div className="absolute inset-0 overflow-hidden z-20">
{/* 生成中 */} {/* 生成中 */}
{taskObject.videos.data[currentSketchIndex].video_status === 0 && ( {taskObject.videos.data[currentSketchIndex].video_status === 0 && (
<div className="absolute inset-0 bg-black/10 flex items-center justify-center"> <div className="absolute inset-0 bg-black/10 flex items-center justify-center">
@ -499,7 +499,7 @@ export const MediaViewer = React.memo(function MediaViewer({
)} )}
{/* 操作按钮组 */} {/* 操作按钮组 */}
<AnimatePresence> {/* <AnimatePresence>
<motion.div <motion.div
className="absolute top-4 right-4 gap-2 z-[21] hidden group-hover:flex" className="absolute top-4 right-4 gap-2 z-[21] hidden group-hover:flex"
initial={{ opacity: 0, y: -10 }} initial={{ opacity: 0, y: -10 }}
@ -512,7 +512,7 @@ export const MediaViewer = React.memo(function MediaViewer({
onClick={() => handleEditClick('3')} onClick={() => handleEditClick('3')}
/> />
</motion.div> </motion.div>
</AnimatePresence> </AnimatePresence> */}
{/* 底部控制区域 */} {/* 底部控制区域 */}
{ taskObject.videos.data[currentSketchIndex].video_status === 1 && ( { taskObject.videos.data[currentSketchIndex].video_status === 1 && (
@ -598,7 +598,7 @@ export const MediaViewer = React.memo(function MediaViewer({
</div> </div>
{/* 操作按钮组 */} {/* 操作按钮组 */}
<AnimatePresence> {/* <AnimatePresence>
<motion.div <motion.div
className="absolute top-4 right-4 gap-2 hidden group-hover:flex" className="absolute top-4 right-4 gap-2 hidden group-hover:flex"
initial={{ opacity: 0, y: -10 }} initial={{ opacity: 0, y: -10 }}
@ -611,7 +611,7 @@ export const MediaViewer = React.memo(function MediaViewer({
onClick={() => handleEditClick('1')} onClick={() => handleEditClick('1')}
/> />
</motion.div> </motion.div>
</AnimatePresence> </AnimatePresence> */}
{/* 底部播放按钮 */} {/* 底部播放按钮 */}
<AnimatePresence> <AnimatePresence>
@ -683,9 +683,7 @@ export const MediaViewer = React.memo(function MediaViewer({
return renderSketchContent([...taskObject.roles.data, ...taskObject.scenes.data][currentSketchIndex]); return renderSketchContent([...taskObject.roles.data, ...taskObject.scenes.data][currentSketchIndex]);
} }
if (taskObject.currentStage === 'shot_sketch') {
return renderSketchContent(taskObject.shot_sketch.data[currentSketchIndex]);
}
return null; return null;
}); });

View File

@ -51,12 +51,19 @@ export function ThumbnailGrid({
if (taskObject.currentStage === 'video') { if (taskObject.currentStage === 'video') {
return taskObject.videos.data; return taskObject.videos.data;
} else if (taskObject.currentStage === 'scene' || taskObject.currentStage === 'character') { } else if (taskObject.currentStage === 'scene' || taskObject.currentStage === 'character') {
return [...taskObject.roles.data, ...taskObject.scenes.data]; // 为 roles 和 scenes 数据添加唯一标识前缀,避免重复
} else if (taskObject.currentStage === 'shot_sketch') { const rolesWithPrefix = taskObject.roles.data.map((role, index) => ({
return taskObject.shot_sketch.data; ...role,
uniqueId: `role_${index}`
}));
const scenesWithPrefix = taskObject.scenes.data.map((scene, index) => ({
...scene,
uniqueId: `scene_${index}`
}));
return [...rolesWithPrefix, ...scenesWithPrefix];
} }
return []; return [];
}, [taskObject.currentStage, taskObject.videos.data, taskObject.scenes.data, taskObject.shot_sketch.data]); }, [taskObject.currentStage, taskObject.videos.data, taskObject.roles.data, taskObject.scenes.data]);
// 使用 useRef 存储前一次的数据,避免触发重渲染 // 使用 useRef 存储前一次的数据,避免触发重渲染
const prevDataRef = useRef<any[]>([]); const prevDataRef = useRef<any[]>([]);
@ -162,7 +169,7 @@ export function ThumbnailGrid({
return ( return (
<div <div
key={`video-${urls}`} key={`video-${urls}-${index}`}
className={`relative aspect-video rounded-lg overflow-hidden className={`relative aspect-video rounded-lg overflow-hidden
${currentSketchIndex === index ? 'ring-2 ring-blue-500 z-10' : 'hover:ring-2 hover:ring-blue-500/50'}`} ${currentSketchIndex === index ? 'ring-2 ring-blue-500 z-10' : 'hover:ring-2 hover:ring-blue-500/50'}`}
onClick={() => !isDragging && onSketchSelect(index)} onClick={() => !isDragging && onSketchSelect(index)}
@ -195,14 +202,7 @@ export function ThumbnailGrid({
/> />
) : ( ) : (
<div className="w-full h-full transform hover:scale-105 transition-transform duration-500"> <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 select-none ${
(!taskObject.shot_sketch.data[index]) ? 'filter blur-sm opacity-60' : ''
}`}
src={taskObject.shot_sketch.data[index] ? taskObject.shot_sketch.data[index].url : video.urls?.[0] || ''}
alt={`Thumbnail ${index + 1}`}
draggable="false"
/>
</div> </div>
)} )}
@ -230,7 +230,7 @@ export function ThumbnailGrid({
return ( return (
<div <div
key={`sketch-${sketch.url}`} key={sketch.uniqueId || `sketch-${sketch.url}-${index}`}
className={`relative aspect-video rounded-lg overflow-hidden className={`relative aspect-video rounded-lg overflow-hidden
${currentSketchIndex === index ? 'ring-2 ring-blue-500 z-10' : 'hover:ring-2 hover:ring-blue-500/50'}`} ${currentSketchIndex === index ? 'ring-2 ring-blue-500 z-10' : 'hover:ring-2 hover:ring-blue-500/50'}`}
onClick={() => !isDragging && onSketchSelect(index)} onClick={() => !isDragging && onSketchSelect(index)}
@ -309,7 +309,6 @@ export function ThumbnailGrid({
> >
{taskObject.currentStage === 'video' && renderVideoThumbnails()} {taskObject.currentStage === 'video' && renderVideoThumbnails()}
{(taskObject.currentStage === 'scene' || taskObject.currentStage === 'character') && renderSketchThumbnails(getCurrentData())} {(taskObject.currentStage === 'scene' || taskObject.currentStage === 'character') && renderSketchThumbnails(getCurrentData())}
{taskObject.currentStage === 'shot_sketch' && renderSketchThumbnails(taskObject.shot_sketch.data)}
</div> </div>
); );
} }

View File

@ -15,6 +15,7 @@ export function useWorkflowData() {
const searchParams = useSearchParams(); const searchParams = useSearchParams();
const episodeId = searchParams.get('episodeId') || ''; const episodeId = searchParams.get('episodeId') || '';
const token = localStorage.getItem('token') || '';
let tempTaskObject = useRef<TaskObject>({ let tempTaskObject = useRef<TaskObject>({
title: '', title: '',
@ -29,10 +30,6 @@ export function useWorkflowData() {
data: [], data: [],
total_count: -1 total_count: -1
}, },
shot_sketch: {
data: [],
total_count: -1
},
videos: { videos: {
data: [], data: [],
total_count: -1 total_count: -1
@ -108,11 +105,17 @@ export function useWorkflowData() {
}, []); }, []);
useEffect(() => { useEffect(() => {
if (['video', 'shot_sketch', 'sketch'].includes(taskObject.currentStage)) { if (['video', 'sketch'].includes(taskObject.currentStage)) {
setCurrentSketchIndex(0); setCurrentSketchIndex(0);
} }
}, [taskObject.currentStage]); }, [taskObject.currentStage]);
useEffect(() => {
if (token && currentLoadingText.includes('Post-production')) {
window.open(`https://smartcut.huiying.video/ai-editor/${episodeId}?token=${token}`, '_self');
}
}, [currentLoadingText, token, episodeId]);
useUpdateEffect(() => { useUpdateEffect(() => {
console.log('-----look-taskObject_find_changed-----', taskObject); console.log('-----look-taskObject_find_changed-----', taskObject);
@ -143,14 +146,7 @@ export function useWorkflowData() {
loadingText.current = LOADING_TEXT_MAP.getShotSketchStatus; loadingText.current = LOADING_TEXT_MAP.getShotSketchStatus;
} }
} }
if (taskObject.currentStage === 'shot_sketch') {
const realShotResultData = taskObject.shot_sketch.data.filter((item: any) => item.status !== 0);
if (taskObject.shot_sketch.total_count > realShotResultData.length) {
loadingText.current = LOADING_TEXT_MAP.shotSketch(realShotResultData.length, taskObject.shot_sketch.total_count);
} else {
loadingText.current = LOADING_TEXT_MAP.getVideoStatus;
}
}
if (taskObject.currentStage === 'video') { if (taskObject.currentStage === 'video') {
const realTaskResultData = taskObject.videos.data.filter((item: any) => item.video_status !== 0); const realTaskResultData = taskObject.videos.data.filter((item: any) => item.video_status !== 0);
if (taskObject.videos.total_count > realTaskResultData.length) { if (taskObject.videos.total_count > realTaskResultData.length) {
@ -166,7 +162,7 @@ export function useWorkflowData() {
loadingText.current = LOADING_TEXT_MAP.complete; loadingText.current = LOADING_TEXT_MAP.complete;
} }
setCurrentLoadingText(loadingText.current); setCurrentLoadingText(loadingText.current);
}, [scriptBlocksMemo, taskObject.currentStage, taskObject.scenes.data, taskObject.roles.data, taskObject.shot_sketch.data, taskObject.videos.data, taskObject.status], {mode: 'none'}); }, [scriptBlocksMemo, taskObject.currentStage, taskObject.scenes.data, taskObject.roles.data, taskObject.videos.data, taskObject.status], {mode: 'none'});
// 将 sketchCount 和 videoCount 放到 redux 中 每一次变化也要更新 // 将 sketchCount 和 videoCount 放到 redux 中 每一次变化也要更新
@ -175,10 +171,7 @@ export function useWorkflowData() {
if (taskObject.currentStage === 'scene' && taskObject.scenes.data.length > 0) { if (taskObject.currentStage === 'scene' && taskObject.scenes.data.length > 0) {
await autoPlaySketch(taskObject.scenes.data.length); await autoPlaySketch(taskObject.scenes.data.length);
} }
if (taskObject.currentStage === 'shot_sketch' && taskObject.shot_sketch.data.length > 0) { }, [taskObject.currentStage, taskObject.scenes.data, autoPlaySketch]);
await autoPlaySketch(taskObject.shot_sketch.data.length);
}
}, [taskObject.currentStage, taskObject.scenes.data, taskObject.shot_sketch.data, autoPlaySketch]);
// 获取流式数据 // 获取流式数据
const fetchStreamData = useCallback(async () => { const fetchStreamData = useCallback(async () => {
@ -256,33 +249,7 @@ export function useWorkflowData() {
} }
// debugger; // debugger;
if (task.task_name === 'generate_shot_sketch' && task.task_result && task.task_result.data) {
let realShotResultData = task.task_result.data.filter((item: any) => item.url);
if (task.task_status === 'COMPLETED') {
realShotResultData = taskCurrent.shot_sketch.data.filter((item: any) => item.status !== 0);
}
taskCurrent.shot_sketch.total_count = task.task_result.total_count;
if (task.task_status !== 'COMPLETED' || taskCurrent.shot_sketch.total_count !== realShotResultData.length) {
taskCurrent.currentStage = 'shot_sketch';
console.log('----------正在生成草图中 替换 sketch 数据', realShotResultData.length);
// 正在生成草图中 替换 sketch 数据
const sketchList = [];
for (const sketch of task.task_result.data) {
sketchList.push({
url: sketch.url,
script: sketch.description,
status: sketch.url ? 1 : (task.task_status === 'COMPLETED' ? 2 : 0),
type: 'shot_sketch'
});
}
taskCurrent.shot_sketch.data = sketchList;
if (task.task_status === 'COMPLETED') {
// 草图生成完成
}
break;
}
}
if (task.task_name === 'generate_videos' && task.task_result && task.task_result.data) { if (task.task_name === 'generate_videos' && task.task_result && task.task_result.data) {
let realTaskResultData = task.task_result.data.filter((item: any) => (item.urls || (item.video_status !== 0 && item.video_status !== undefined))); let realTaskResultData = task.task_result.data.filter((item: any) => (item.urls || (item.video_status !== 0 && item.video_status !== undefined)));
@ -464,27 +431,7 @@ export function useWorkflowData() {
// 场景生成完成 // 场景生成完成
} }
} }
if (data.shot_sketch && data.shot_sketch.data) {
taskCurrent.currentStage = 'shot_sketch';
const realShotResultData = data.shot_sketch.data.filter((item: any) => item.url);
const sketchList = [];
for (const sketch of data.shot_sketch.data) {
sketchList.push({
url: sketch.url,
script: sketch.description,
status: sketch.url ? 1 : (data.shot_sketch.task_status === 'COMPLETED' ? 2 : 0),
type: 'shot_sketch'
});
}
taskCurrent.shot_sketch.data = sketchList;
taskCurrent.shot_sketch.total_count = data.shot_sketch.total_count;
// 设置为最后一个草图
if (data.shot_sketch.total_count > realShotResultData.length) {
// 草图生成中
} else {
// 草图生成完成
}
}
if (data.video.data) { if (data.video.data) {
const realDataVideoData = data.video.data.filter((item: any) => (item.urls || (item.video_status !== 0 && item.video_status !== undefined))); const realDataVideoData = data.video.data.filter((item: any) => (item.urls || (item.video_status !== 0 && item.video_status !== undefined)));
taskCurrent.currentStage = 'video'; taskCurrent.currentStage = 'video';

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 5.5 MiB