video-flow-b/app/service/adapter/oldErrAdapter.ts
2025-09-08 14:58:23 +08:00

346 lines
12 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**============因协同任务开发流程没有明确管理,导致的必要的适配=================**/
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;
}