/**============因协同任务开发流程没有明确管理,导致的必要的适配=================**/ import { ScriptRoleEntity, VideoSegmentEntity } from "../domain/Entities"; import { LensType, ContentItem } from "../domain/valueObject"; export type task_item = { /** 镜头1描述 */ shot_1: string; /** 镜头2描述 */ shot_2: string; /** 镜头3描述 */ shot_3: string; /** 镜头4描述 */ shot_4: string; /** 镜头5描述 */ shot_5: string; /** 镜头6描述 */ shot_6: string; /** 镜头7描述 */ shot_7: string; /** 镜头8描述 */ shot_8: string; /** 镜头9描述 */ shot_9: string; /** 镜头10描述 */ shot_10: string; } /** * @description 视频片段后端结构 */ export class VideoSegmentEntityAdapter { /** 原始文本 */ original_text: string = ""; /** 任务状态 */ task_status: string = ""; /** 任务结果 */ task_result: Array<{ /** 任务ID */ video_id: string; /** 任务状态 */ video_status: number|null; /** 叙事目标 */ narrative_goal: string; /** 镜头1描述 */ shot_1: string; /** 镜头2描述 */ shot_2: string; /** 镜头3描述 */ shot_3: string; /** 镜头4描述 */ shot_4: string; /** 镜头5描述 */ shot_5: string; /** 镜头6描述 */ shot_6: string; /** 镜头7描述 */ shot_7: string; /** 镜头8描述 */ shot_8: string; /** 镜头9描述 */ shot_9: string; /** 镜头10描述 */ shot_10: string; /** 视频列表 */ videos: Array<{ /** 视频地址 */ video_url: string; /** 视频ID */ video_id: string; /**视频片段状态 0:视频加载中 1:任务已完成 2:任务失败 */ video_status: number|null; }>; }> = []; project_characters: ScriptRoleEntity[] = []; /** * @description 解析shotContent,分离镜头描述和对话内容 * @param shotContent 原始shot内容 * @returns {description: string, dialogues: ContentItem[]} 解析后的描述和对话内容 */ static parseShotContent(shotContent: string): { description: string; dialogues: ContentItem[] } { const lines = shotContent.split('\n').map(line => line.trim()).filter(line => line.length > 0); const dialogues: ContentItem[] = []; let descriptionLines: string[] = []; for (const line of lines) { // 检查是否是对话行,格式:人物名称[CH-XX]: 对话内容 const dialogueMatch = line.match(/^(.+?)\s*\[CH-\d+\]:\s*(.+)$/); if (dialogueMatch) { const roleName = dialogueMatch[1].trim(); const content = dialogueMatch[2].trim(); dialogues.push({ roleName, content }); } else { // 如果不是对话行,则认为是描述内容 descriptionLines.push(line); } } const description = descriptionLines.join('\n'); return { description, dialogues }; } /** * @description 将后端数据结构转换为VideoSegmentEntity数组 * @param data 后端数据结构 * @returns VideoSegmentEntity[] 视频片段实体数组 */ static toVideoSegmentEntity(data: VideoSegmentEntityAdapter): VideoSegmentEntity[] { const entities: VideoSegmentEntity[] = []; if (data.task_result && data.task_result.length > 0) { // 遍历task_result中的每一项 data.task_result.forEach((result, index) => { // 从task_result中提取镜头信息 const lens: LensType[] = []; // 处理镜头1到镜头10 for (let i = 1; i <= 10; i++) { const shotKey = `shot_${i}` as keyof typeof result; const shotContent = (result as any)[shotKey] as string; if (shotContent && shotContent.trim()) { // 解析shotContent,分离镜头描述和对话内容 const { description, dialogues } = this.parseShotContent(shotContent); // 创建镜头项,包含描述和对话内容 const lensItem = new LensType(`shot_${i}`, description, dialogues); lens.push(lensItem); } } // 如果没有任何镜头但有narrative_goal,将其作为镜头1 if (lens.length === 0 && result.narrative_goal) { const narrativeLens = new LensType("shot_1", result.narrative_goal, []); lens.push(narrativeLens); } // 提取视频URL列表 // const videoUrls: { // video_url: string; // video_id: string; // video_status: number|null; // }[] = result.videos; // if (result.videos && result.videos.length > 0) { // videoUrls.push(...result.videos.map(video => ({ // video_url: video.video_url, // video_id: video.video_id, // video_status: video.video_status||1 // }))); // } // 根据task_status和videoUrls内容确定状态 let status = result.videos[0]?.video_status||1 // 创建VideoSegmentEntity const entity: VideoSegmentEntity = { id: result.video_id, // 生成临时ID,包含索引 name: `video_${index}`, // 生成临时名称,包含索引 sketchUrl: "", // 后端数据中没有sketchUrl,设为空字符串 videoUrl: result.videos, status: result.video_status, lens: lens }; entities.push(entity); }); } return entities; } /** * @description 将VideoSegmentEntity数组转换为后端数据结构 * @param entities 视频片段实体数组 * @returns VideoSegmentEntityAdapter 后端数据结构 */ static fromVideoSegmentEntity(entities: VideoSegmentEntity[]): VideoSegmentEntityAdapter { const taskResults: Array<{ video_id: string; video_status: number|null; narrative_goal: string; shot_1: string; shot_2: string; shot_3: string; shot_4: string; shot_5: string; shot_6: string; shot_7: string; shot_8: string; shot_9: string; shot_10: string; videos: Array<{ video_url: string; video_id: string; video_status: number|null }>; }> = []; // 遍历每个实体,转换为task_result项 entities.forEach(entity => { // 从lens中提取镜头描述(支持镜头1到镜头10) const shots: { [key: string]: string } = {}; for (let i = 1; i <= 10; i++) { const lensItem = entity.lens.find(lens => lens.name === `shot_${i}`); if (lensItem) { // 重新组合镜头描述和对话内容 let fullContent = lensItem.script; // 如果有对话内容,添加到镜头描述后面 if (lensItem.content && lensItem.content.length > 0) { const dialogueLines = lensItem.content.map(dialogue => `${dialogue.roleName} : ${dialogue.content}` ); fullContent += '\n' + dialogueLines.join('\n'); } shots[`shot_${i}`] = fullContent; } else { shots[`shot_${i}`] = ""; } } // 如果有更多镜头,可以合并到narrative_goal中 let narrative_goal = ""; const additionalLenses = entity.lens .filter(lens => !lens.name.match(/^shot_[1-9]$|^shot_10$/)) .map(lens => `${lens.name}: ${lens.script}`) .join("; "); if (additionalLenses) { narrative_goal = additionalLenses; } // 构建videos数组 const videos = entity.videoUrl.map(url => { return { video_url: url.video_url, video_id: url.video_id, video_status: url.video_status } }); taskResults.push({ narrative_goal: narrative_goal, video_id: entity.id, video_status: entity.status, shot_1: shots.shot_1 || "", shot_2: shots.shot_2 || "", shot_3: shots.shot_3 || "", shot_4: shots.shot_4 || "", shot_5: shots.shot_5 || "", shot_6: shots.shot_6 || "", shot_7: shots.shot_7 || "", shot_8: shots.shot_8 || "", shot_9: shots.shot_9 || "", shot_10: shots.shot_10 || "", videos: videos }); }); // 根据第一个实体的status确定task_status(如果数组为空,默认为COMPLETED) let task_status: string = "COMPLETED"; if (entities.length > 0) { const firstEntity = entities[0]; if (firstEntity.status === 0) { task_status = "IN_PROGRESS"; // 视频加载中映射为IN_PROGRESS } else if (firstEntity.status === 1) { task_status = "COMPLETED"; // 任务已完成 } else if (firstEntity.status === 2) { task_status = "FAILED"; // 任务失败 } } // 创建VideoSegmentEntityAdapter const adapter = new VideoSegmentEntityAdapter(); adapter.original_text = ""; // 实体中没有original_text,设为空字符串 adapter.task_status = task_status; adapter.task_result = taskResults; return adapter; } /** * @description 将LensType数组转换为task_item类型 * @param lensTypes 镜头类型数组 * @returns task_item 任务项 */ static lensTypeToTaskItem(lensTypes: LensType[]): task_item { // 初始化镜头对象,所有字段设为空字符串 const shots: { [key: string]: string } = { shot_1: "", shot_2: "", shot_3: "", shot_4: "", shot_5: "", shot_6: "", shot_7: "", shot_8: "", shot_9: "", shot_10: "" }; // 遍历所有LensType,处理镜头1到镜头10 lensTypes.forEach(lensType => { const shotMatch = lensType.name.match(/^shot_(\d+)$/); if (shotMatch) { const shotNumber = shotMatch[1]; const shotKey = `shot_${shotNumber}` as keyof typeof shots; // 重新组合镜头描述和对话内容 let fullContent = lensType.script; // 如果有对话内容,添加到镜头描述后面 if (lensType.content && lensType.content.length > 0) { const dialogueLines = lensType.content.map(dialogue => `${dialogue.roleName} : ${dialogue.content}` ); fullContent += '\n' + dialogueLines.join('\n'); } shots[shotKey] = fullContent; } }); // 返回完整的task_item对象 return { shot_1: shots.shot_1, shot_2: shots.shot_2, shot_3: shots.shot_3, shot_4: shots.shot_4, shot_5: shots.shot_5, shot_6: shots.shot_6, shot_7: shots.shot_7, shot_8: shots.shot_8, shot_9: shots.shot_9, shot_10: shots.shot_10 }; } } /**视频片段基础数据 */ export interface TaskSketch { url: string; video_id: string; }