forked from 77media/video-flow
621 lines
23 KiB
TypeScript
621 lines
23 KiB
TypeScript
'use client';
|
||
|
||
import { useState, useEffect, useCallback, useRef, useMemo } from 'react';
|
||
import { useSearchParams } from 'next/navigation';
|
||
import { detailScriptEpisodeNew, getScriptTitle, getRunningStreamData, pauseMovieProjectPlan, resumeMovieProjectPlan, getGenerateEditPlan, regenerateVideo } from '@/api/video_flow';
|
||
import { useScriptService } from "@/app/service/Interaction/ScriptService";
|
||
import { useUpdateEffect } from '@/app/hooks/useUpdateEffect';
|
||
import { LOADING_TEXT_MAP, TaskObject, Status, Stage } from '@/api/DTO/movieEdit';
|
||
|
||
export function useWorkflowData() {
|
||
useEffect(() => {
|
||
console.log("init-useWorkflowData");
|
||
return () => console.log("unmount-useWorkflowData");
|
||
}, []);
|
||
|
||
const searchParams = useSearchParams();
|
||
const episodeId = searchParams.get('episodeId') || '';
|
||
const from = searchParams.get('from') || '';
|
||
const token = localStorage.getItem('token') || '';
|
||
const useid = JSON.parse(localStorage.getItem("currentUser") || '{}').id || NaN;
|
||
// 查看缓存中 是否已经 加载过 这个项目的 剪辑计划
|
||
const isLoaded = localStorage.getItem(`isLoaded_plan_${episodeId}`);
|
||
|
||
let tempTaskObject = useRef<TaskObject>({
|
||
title: '',
|
||
tags: [],
|
||
currentStage: 'script' as Stage,
|
||
status: 'IN_PROGRESS' as Status,
|
||
roles: {
|
||
data: [],
|
||
total_count: -1
|
||
},
|
||
scenes: {
|
||
data: [],
|
||
total_count: -1
|
||
},
|
||
videos: {
|
||
data: [],
|
||
total_count: -1
|
||
},
|
||
final: {
|
||
url: '',
|
||
note: ''
|
||
}
|
||
});
|
||
let loadingText: any = useRef(LOADING_TEXT_MAP.initializing);
|
||
|
||
|
||
// 更新 taskObject 的类型
|
||
const [taskObject, setTaskObject] = useState<TaskObject>(tempTaskObject.current);
|
||
const [currentSketchIndex, setCurrentSketchIndex] = useState(0);
|
||
const [currentLoadingText, setCurrentLoadingText] = useState('loading project info...');
|
||
const [dataLoadError, setDataLoadError] = useState<string | null>(null);
|
||
const [needStreamData, setNeedStreamData] = useState(false);
|
||
const [isPauseWorkFlow, setIsPauseWorkFlow] = useState(false);
|
||
const [canGoToCut, setCanGoToCut] = useState(false);
|
||
const [state, setState] = useState({
|
||
mode: 'automatic' as 'automatic' | 'manual' | 'auto',
|
||
originalText: '',
|
||
isLoading: true
|
||
});
|
||
|
||
const {
|
||
scriptBlocksMemo, // 渲染剧本数据
|
||
initializeFromProject,
|
||
setAnyAttribute,
|
||
applyScript
|
||
} = useScriptService();
|
||
// 监听剧本加载完毕
|
||
const scriptData = useMemo(() => {
|
||
return scriptBlocksMemo.length > 0 ? scriptBlocksMemo : null;
|
||
}, [scriptBlocksMemo]);
|
||
// 监听继续 请求更新数据
|
||
useUpdateEffect(() => {
|
||
if (taskObject.status === 'COMPLETED' || taskObject.status === 'FAILED') {
|
||
return;
|
||
}
|
||
if (isPauseWorkFlow) {
|
||
pauseMovieProjectPlan({ project_id: episodeId });
|
||
} else {
|
||
resumeMovieProjectPlan({ project_id: episodeId });
|
||
}
|
||
}, [isPauseWorkFlow], { mode: "debounce", delay: 1000 });
|
||
|
||
// 自动开始播放一轮
|
||
const autoPlaySketch = useCallback((length: number) => {
|
||
return new Promise<void>((resolve) => {
|
||
let currentIndex = 0;
|
||
const interval = 2000; // 每个草图显示2秒
|
||
|
||
const playNext = () => {
|
||
if (currentIndex < length) {
|
||
console.log('自动播放设置索引:', currentIndex);
|
||
setCurrentSketchIndex(currentIndex);
|
||
currentIndex++;
|
||
setTimeout(playNext, interval);
|
||
} else {
|
||
// 播放完成后重置到第一个
|
||
setTimeout(() => {
|
||
console.log('自动播放完成,重置索引到0');
|
||
setCurrentSketchIndex(0);
|
||
resolve();
|
||
}, 500); // 短暂延迟后重置
|
||
}
|
||
};
|
||
|
||
// 开始播放
|
||
playNext();
|
||
});
|
||
}, []);
|
||
|
||
useEffect(() => {
|
||
if (['video', 'sketch'].includes(taskObject.currentStage)) {
|
||
setCurrentSketchIndex(0);
|
||
}
|
||
}, [taskObject.currentStage]);
|
||
|
||
const generateEditPlan = useCallback(async (isInit?: boolean) => {
|
||
if (isLoaded) {
|
||
return;
|
||
}
|
||
localStorage.setItem(`isLoaded_plan_${episodeId}`, 'true');
|
||
isInit && await getGenerateEditPlan({ project_id: episodeId });
|
||
openEditPlan();
|
||
}, [episodeId]);
|
||
|
||
const openEditPlan = useCallback(async () => {
|
||
window.open(`https://smartcut.movieflow.ai/ai-editor/${episodeId}?token=${token}&user_id=${useid}`, '_target');
|
||
}, [episodeId]);
|
||
|
||
useEffect(() => {
|
||
if (!from && canGoToCut && taskObject.status !== 'COMPLETED') {
|
||
generateEditPlan(true);
|
||
}
|
||
}, [canGoToCut, taskObject.status]);
|
||
|
||
|
||
useUpdateEffect(() => {
|
||
console.log('-----look-taskObject_find_changed-----', taskObject);
|
||
if (taskObject.currentStage === 'script') {
|
||
if (scriptBlocksMemo.length > 0) {
|
||
console.log('应用剧本');
|
||
// 自动模式下 应用剧本;手动模式 需要点击 下一步 触发
|
||
// 确保仅自动触发一次
|
||
// state.mode.includes('auto') && loadingText.current !== LOADING_TEXT_MAP.character && applyScript();
|
||
loadingText.current = LOADING_TEXT_MAP.character;
|
||
} else {
|
||
loadingText.current = LOADING_TEXT_MAP.script;
|
||
}
|
||
}
|
||
if (taskObject.currentStage === 'character') {
|
||
const realCharacterResultData = taskObject.roles.data.filter((item: any) => item.status !== 0);
|
||
if (taskObject.roles.total_count > realCharacterResultData.length) {
|
||
loadingText.current = LOADING_TEXT_MAP.newCharacter(realCharacterResultData.length, taskObject.roles.total_count);
|
||
} else {
|
||
loadingText.current = LOADING_TEXT_MAP.getSketchStatus;
|
||
}
|
||
}
|
||
if (taskObject.currentStage === 'scene') {
|
||
const realSketchResultData = taskObject.scenes.data.filter((item: any) => item.status !== 0);
|
||
if (taskObject.scenes.total_count > realSketchResultData.length) {
|
||
loadingText.current = LOADING_TEXT_MAP.sketch(realSketchResultData.length, taskObject.scenes.total_count);
|
||
} else {
|
||
loadingText.current = LOADING_TEXT_MAP.getVideoStatus;
|
||
}
|
||
}
|
||
|
||
if (taskObject.currentStage === 'video') {
|
||
const realTaskResultData = taskObject.videos.data.filter((item: any) => item.video_status !== 0);
|
||
if (taskObject.videos.total_count > realTaskResultData.length) {
|
||
loadingText.current = LOADING_TEXT_MAP.video(realTaskResultData.length, taskObject.videos.total_count);
|
||
} else {
|
||
loadingText.current = LOADING_TEXT_MAP.postProduction('AI-powered video editing in progress…');
|
||
}
|
||
}
|
||
if (taskObject.currentStage === 'final_video') {
|
||
loadingText.current = LOADING_TEXT_MAP.postProduction('generating fine-grained video clips...');
|
||
}
|
||
if (taskObject.status === 'COMPLETED') {
|
||
loadingText.current = LOADING_TEXT_MAP.complete;
|
||
}
|
||
setCurrentLoadingText(loadingText.current);
|
||
}, [scriptBlocksMemo, taskObject.currentStage, taskObject.scenes.data, taskObject.roles.data, taskObject.videos.data, taskObject.status], {mode: 'none'});
|
||
|
||
// 将 sketchCount 和 videoCount 放到 redux 中 每一次变化也要更新
|
||
|
||
// 添加手动播放控制
|
||
const handleManualPlay = useCallback(async () => {
|
||
if (taskObject.currentStage === 'scene' && taskObject.scenes.data.length > 0) {
|
||
await autoPlaySketch(taskObject.scenes.data.length);
|
||
}
|
||
}, [taskObject.currentStage, taskObject.scenes.data, autoPlaySketch]);
|
||
|
||
// 获取流式数据
|
||
const fetchStreamData = useCallback(async () => {
|
||
if (!episodeId || !needStreamData) return;
|
||
|
||
try {
|
||
const response = await getRunningStreamData({ project_id: episodeId });
|
||
if (!response.successful) {
|
||
throw new Error(response.message);
|
||
}
|
||
|
||
const all_task_data = response.data;
|
||
const { current: taskCurrent } = tempTaskObject;
|
||
|
||
console.log('---look-all_task_data', all_task_data);
|
||
console.log('---look-tempTaskObject', taskCurrent);
|
||
|
||
// 收集所有需要更新的状态
|
||
let stateUpdates = JSON.stringify(taskCurrent);
|
||
|
||
for (const task of all_task_data) {
|
||
// 如果有已完成的数据,同步到状态
|
||
if (task.task_name === 'generate_character' && task.task_result && task.task_result.data) {
|
||
let realCharacterResultData = task.task_result.data.filter((item: any) => item.image_path);
|
||
if (task.task_status === 'COMPLETED') {
|
||
realCharacterResultData = taskCurrent.roles.data.filter((item: any) => item.status !== 0);
|
||
}
|
||
taskCurrent.roles.total_count = task.task_result.total_count;
|
||
if (task.task_status !== 'COMPLETED' || taskCurrent.roles.total_count !== realCharacterResultData.length) {
|
||
taskCurrent.currentStage = 'character';
|
||
// 正在生成角色中 替换角色数据
|
||
const characterList = [];
|
||
for (const character of task.task_result.data) {
|
||
characterList.push({
|
||
name: character.character_name,
|
||
url: character.image_path,
|
||
status: character.image_path ? 1 : (task.task_status === 'COMPLETED' ? 2 : 0),
|
||
type: 'role'
|
||
});
|
||
}
|
||
taskCurrent.roles.data = characterList;
|
||
if (task.task_status === 'COMPLETED') {
|
||
// 角色生成完成
|
||
}
|
||
break;
|
||
}
|
||
|
||
}
|
||
|
||
if (task.task_name === 'generate_sketch' && task.task_result && task.task_result.data) {
|
||
let realSketchResultData = task.task_result.data.filter((item: any) => item.image_path);
|
||
if (task.task_status === 'COMPLETED') {
|
||
realSketchResultData = taskCurrent.scenes.data.filter((item: any) => item.status !== 0);
|
||
}
|
||
console.log('---look-realSketchResultData', realSketchResultData);
|
||
taskCurrent.scenes.total_count = task.task_result.total_count;
|
||
if (task.task_status !== 'COMPLETED' || taskCurrent.scenes.total_count !== realSketchResultData.length) {
|
||
taskCurrent.currentStage = 'scene';
|
||
// 正在生成草图中 替换 sketch 数据
|
||
const sketchList = [];
|
||
for (const sketch of task.task_result.data) {
|
||
sketchList.push({
|
||
url: sketch.image_path,
|
||
script: sketch.sketch_name,
|
||
status: sketch.image_path ? 1 : (task.task_status === 'COMPLETED' ? 2 : 0),
|
||
type: 'scene'
|
||
});
|
||
}
|
||
taskCurrent.scenes.data = sketchList;
|
||
if (task.task_status === 'COMPLETED') {
|
||
// 草图生成完成
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
// debugger;
|
||
|
||
|
||
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)));
|
||
taskCurrent.videos.total_count = task.task_result.total_count;
|
||
if (task.task_status === 'COMPLETED') {
|
||
realTaskResultData = taskCurrent.videos.data.filter((item: any) => item.video_status !== 0);
|
||
}
|
||
if (task.task_status !== 'COMPLETED' || taskCurrent.videos.total_count !== realTaskResultData.length) {
|
||
taskCurrent.currentStage = 'video';
|
||
// 正在生成视频中 替换视频数据
|
||
const videoList = [];
|
||
let videoUrls: string[] = [];
|
||
let video_status = 0;
|
||
for (const video of task.task_result.data) {
|
||
videoUrls = video.urls ? video.urls.filter((url: null | string) => url !== null) : [];
|
||
// 适配旧数据
|
||
video_status = video.video_status === undefined ? (videoUrls.length > 0 ? 1 : 0) : video.video_status;
|
||
// 完成 还是 0 就是 生成失败
|
||
video_status = task.task_status === 'COMPLETED' && video_status === 0 ? 2 : video_status;
|
||
// 每一项 video 有多个视频 先默认取第一个
|
||
videoList.push({
|
||
urls: videoUrls,
|
||
video_id: video.video_id,
|
||
video_status: video_status, // 0 生成中 1 生成完成 2 生成失败
|
||
type: 'video'
|
||
});
|
||
}
|
||
taskCurrent.videos.data = videoList;
|
||
console.log('----------正在生成视频中', realTaskResultData.length);
|
||
if (task.task_status === 'COMPLETED') {
|
||
console.log('----------视频生成完成');
|
||
// 视频生成完成
|
||
// 暂时没有音频生成 直接跳过
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
// 视频分析
|
||
let analyze_video_completed_count = all_task_data.filter((item: any) => item.task_name === 'generate_analyze_video' && item.task_status !== 'INIT' && item.task_status !== 'RUNNING').length;
|
||
let analyze_video_total_count = all_task_data.filter((item: any) => item.task_name === 'generate_analyze_video').length;
|
||
if (analyze_video_total_count && analyze_video_completed_count === analyze_video_total_count) {
|
||
setCanGoToCut(true);
|
||
}
|
||
|
||
// 粗剪
|
||
if (task.task_name === 'generate_final_simple_video') {
|
||
if (task.task_result && task.task_result.video) {
|
||
taskCurrent.currentStage = 'final_video';
|
||
taskCurrent.final.url = task.task_result.video;
|
||
taskCurrent.final.note = 'simple';
|
||
taskCurrent.status = 'COMPLETED';
|
||
}
|
||
}
|
||
|
||
// 最终剪辑
|
||
if (task.task_name === 'generate_final_video') {
|
||
if (task.task_result && task.task_result.video) {
|
||
taskCurrent.currentStage = 'final_video';
|
||
taskCurrent.final.url = task.task_result.video;
|
||
taskCurrent.final.note = 'final';
|
||
taskCurrent.status = 'COMPLETED';
|
||
|
||
// 停止轮询
|
||
setNeedStreamData(false);
|
||
}
|
||
}
|
||
}
|
||
|
||
console.log('-----look-tempTaskObject-----', loadingText.current);
|
||
|
||
// 设置最终的状态更新
|
||
setCurrentLoadingText(loadingText.current);
|
||
|
||
if (JSON.stringify(taskCurrent) !== stateUpdates) {
|
||
console.log('-----look-tempTaskObject-changed-----', taskCurrent);
|
||
// 强制更新,使用新的对象引用确保触发更新
|
||
setTaskObject(prev => {
|
||
const newState = JSON.parse(JSON.stringify({...prev, ...taskCurrent}));
|
||
return newState;
|
||
});
|
||
}
|
||
|
||
} catch (error) {
|
||
console.error('获取数据失败:', error);
|
||
}
|
||
}, [episodeId, needStreamData]);
|
||
|
||
// 轮询获取流式数据
|
||
useUpdateEffect(() => {
|
||
let interval: NodeJS.Timeout;
|
||
|
||
if (needStreamData) {
|
||
interval = setInterval(fetchStreamData, 10000);
|
||
fetchStreamData(); // 立即执行一次
|
||
}
|
||
|
||
return () => {
|
||
if (interval) {
|
||
clearInterval(interval);
|
||
}
|
||
};
|
||
}, [needStreamData, fetchStreamData], {mode: 'none'});
|
||
|
||
// 初始化数据
|
||
const initializeWorkflow = async () => {
|
||
if (!episodeId) {
|
||
setDataLoadError('缺少必要的参数');
|
||
return;
|
||
}
|
||
|
||
try {
|
||
setState({
|
||
mode: 'automatic' as 'automatic' | 'manual' | 'auto',
|
||
originalText: '',
|
||
isLoading: true
|
||
});
|
||
setCurrentLoadingText('loading project info...');
|
||
|
||
// 获取剧集详情
|
||
const response = await detailScriptEpisodeNew({ project_id: episodeId });
|
||
if (!response.successful) {
|
||
throw new Error(response.message);
|
||
}
|
||
|
||
const { status, data, tags, mode, original_text, title, name } = response.data;
|
||
|
||
const { current: taskCurrent } = tempTaskObject;
|
||
|
||
taskCurrent.title = name || 'generating...';
|
||
taskCurrent.tags = tags || [];
|
||
taskCurrent.status = status as Status;
|
||
|
||
// 设置标题
|
||
if (!name) {
|
||
// 如果没有标题,轮询获取
|
||
const titleResponse = await getScriptTitle({ project_id: episodeId });
|
||
console.log('titleResponse', titleResponse);
|
||
if (titleResponse.successful) {
|
||
taskCurrent.title = titleResponse.data.title;
|
||
taskCurrent.tags = titleResponse.data.tags || [];
|
||
}
|
||
}
|
||
|
||
if (status === 'COMPLETED') {
|
||
loadingText = LOADING_TEXT_MAP.complete;
|
||
taskCurrent.currentStage = 'final_video';
|
||
setCanGoToCut(true);
|
||
}
|
||
|
||
// 如果有已完成的数据,同步到状态
|
||
if (data) {
|
||
if (data.character && data.character.data && data.character.data.length > 0) {
|
||
taskCurrent.currentStage = 'character';
|
||
const characterList = [];
|
||
for (const character of data.character.data) {
|
||
characterList.push({
|
||
name: character.character_name,
|
||
url: character.image_path,
|
||
status: character.image_path ? 1 : (data.character.task_status === 'COMPLETED' ? 2 : 0),
|
||
type: 'role'
|
||
});
|
||
}
|
||
taskCurrent.roles.data = characterList;
|
||
taskCurrent.roles.total_count = data.character.total_count;
|
||
if (data.character.total_count > data.character.data.length) {
|
||
// 角色生成中
|
||
} else {
|
||
// 角色生成完成
|
||
}
|
||
}
|
||
if (data.sketch && data.sketch.data) {
|
||
taskCurrent.currentStage = 'scene';
|
||
const realSketchResultData = data.sketch.data.filter((item: any) => item.image_path);
|
||
const sketchList = [];
|
||
for (const sketch of data.sketch.data) {
|
||
sketchList.push({
|
||
url: sketch.image_path,
|
||
script: sketch.sketch_name,
|
||
status: sketch.image_path ? 1 : (data.sketch.task_status === 'COMPLETED' ? 2 : 0),
|
||
type: 'scene'
|
||
});
|
||
}
|
||
taskCurrent.scenes.data = sketchList;
|
||
taskCurrent.scenes.total_count = data.sketch.total_count;
|
||
// 设置为最后一个草图
|
||
if (data.sketch.total_count > realSketchResultData.length) {
|
||
// 场景生成中
|
||
} else {
|
||
// 场景生成完成
|
||
}
|
||
}
|
||
|
||
if (data.video.data) {
|
||
const realDataVideoData = data.video.data.filter((item: any) => (item.urls || (item.video_status !== 0 && item.video_status !== undefined)));
|
||
taskCurrent.currentStage = 'video';
|
||
taskCurrent.videos.total_count = data.video.total_count;
|
||
const videoList = [];
|
||
let videoUrls: string[] = [];
|
||
console.log('----------data.video.data', data.video.data);
|
||
for (const video of data.video.data) {
|
||
videoUrls = video.urls ? video.urls.filter((url: null | string) => url !== null) : [];
|
||
console.log('----------videoUrls', videoUrls);
|
||
let video_status = video.video_status === undefined ? (videoUrls.length > 0 ? 1 : 0) : video.video_status;
|
||
video_status = data.video.task_status === 'COMPLETED' && video_status === 0 ? 2 : video_status;
|
||
// 每一项 video 有多个视频 默认取存在的项
|
||
videoList.push({
|
||
urls: videoUrls,
|
||
video_id: video.video_id,
|
||
video_status: video_status, // 0 生成中 1 生成完成 2 生成失败
|
||
type: 'video'
|
||
});
|
||
}
|
||
taskCurrent.videos.data = videoList;
|
||
// 如果在视频步骤,设置为最后一个视频
|
||
if (data.video.total_count > realDataVideoData.length) {
|
||
// 视频生成中
|
||
} else {
|
||
// 视频生成完成
|
||
// 暂时没有音频生成 直接跳过
|
||
}
|
||
}
|
||
|
||
// 粗剪
|
||
if (data.final_simple_video && data.final_simple_video.video) {
|
||
taskCurrent.currentStage = 'final_video';
|
||
taskCurrent.final.url = data.final_simple_video.video;
|
||
taskCurrent.final.note = 'simple';
|
||
taskCurrent.status = 'COMPLETED';
|
||
}
|
||
|
||
if (data.final_video && data.final_video.video) {
|
||
taskCurrent.currentStage = 'final_video';
|
||
taskCurrent.final.url = data.final_video.video;
|
||
taskCurrent.final.note = 'final';
|
||
taskCurrent.status = 'COMPLETED';
|
||
}
|
||
}
|
||
|
||
console.log('---look-taskData', taskCurrent);
|
||
|
||
if (taskCurrent.currentStage === 'script') {
|
||
console.log('开始初始化剧本', original_text,episodeId);
|
||
// TODO 为什么一开始没项目id
|
||
original_text && initializeFromProject(episodeId, original_text).then(() => {
|
||
});
|
||
}
|
||
|
||
setState({
|
||
mode: mode as 'automatic' | 'manual' | 'auto',
|
||
originalText: original_text,
|
||
isLoading: false
|
||
});
|
||
// 设置步骤
|
||
setTaskObject(prev => {
|
||
const newState = JSON.parse(JSON.stringify({...prev, ...taskCurrent}));
|
||
return newState;
|
||
});
|
||
|
||
// 设置是否需要获取流式数据
|
||
setNeedStreamData(status !== 'COMPLETED');
|
||
|
||
} catch (error) {
|
||
console.error('初始化失败:', error);
|
||
setDataLoadError('加载失败,请重试');
|
||
setState({
|
||
mode: 'automatic' as 'automatic' | 'manual' | 'auto',
|
||
originalText: '',
|
||
isLoading: false
|
||
});
|
||
}
|
||
};
|
||
|
||
// 重试生成视频
|
||
const handleRetryVideo = async (video_id: string) => {
|
||
try {
|
||
// 先停止轮询
|
||
await new Promise(resolve => {
|
||
setNeedStreamData(false);
|
||
resolve(true);
|
||
});
|
||
// 重置视频状态为生成中
|
||
await new Promise(resolve => {
|
||
setTaskObject(prev => {
|
||
const newState = JSON.parse(JSON.stringify(prev));
|
||
const videoIndex = newState.videos.data.findIndex((v: any) => v.video_id === video_id);
|
||
if (videoIndex !== -1) {
|
||
newState.videos.data[videoIndex].video_status = 0;
|
||
}
|
||
return newState;
|
||
});
|
||
resolve(true);
|
||
});
|
||
|
||
// 调用重新生成接口
|
||
await regenerateVideo({ project_id: episodeId, video_id: video_id });
|
||
|
||
// 重新开启轮询
|
||
setNeedStreamData(true);
|
||
} catch (error) {
|
||
console.error('重试生成视频失败:', error);
|
||
// 发生错误时也要恢复轮询状态
|
||
setNeedStreamData(true);
|
||
}
|
||
};
|
||
|
||
// 回退到 指定状态 重新获取数据
|
||
const fallbackToStep = (step: string) => {
|
||
console.log('fallbackToStep', step);
|
||
setNeedStreamData(true);
|
||
// tempTaskObject.current.currentStage = step as Stage;
|
||
// loadingText = LOADING_TEXT_MAP.initializing;
|
||
}
|
||
|
||
// 重试加载数据
|
||
const retryLoadData = () => {
|
||
setDataLoadError(null);
|
||
setCurrentSketchIndex(0);
|
||
// 重新初始化
|
||
initializeWorkflow();
|
||
};
|
||
|
||
// 初始化
|
||
useEffect(() => {
|
||
initializeWorkflow();
|
||
}, [episodeId]);
|
||
|
||
return {
|
||
taskObject,
|
||
scriptData,
|
||
isLoading: state.isLoading,
|
||
currentSketchIndex,
|
||
currentLoadingText,
|
||
dataLoadError,
|
||
setCurrentSketchIndex,
|
||
retryLoadData,
|
||
handleManualPlay,
|
||
isPauseWorkFlow,
|
||
mode: state.mode,
|
||
setIsPauseWorkFlow,
|
||
setAnyAttribute,
|
||
applyScript,
|
||
fallbackToStep,
|
||
originalText: state.originalText,
|
||
// showGotoCutButton: from && currentLoadingText.includes('Post-production') ? true : false,
|
||
showGotoCutButton: canGoToCut ? true : false,
|
||
generateEditPlan: openEditPlan,
|
||
handleRetryVideo
|
||
};
|
||
}
|