video-flow-b/api/video_flow.ts
2025-08-17 19:44:30 +08:00

1151 lines
29 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 { post, streamJsonPost } from "./request";
import { ProjectTypeEnum } from "@/app/model/enums";
import { ApiResponse } from "@/api/common";
import { BASE_URL } from "./constants";
import {
AITextEntity,
RoleEntity,
SceneEntity,
VideoSegmentEntity,
} from "@/app/service/domain/Entities";
import { TagValueObject } from "@/app/service/domain/valueObject";
import {
ContentItem,
LensType,
ScriptSlice,
} from "@/app/service/domain/valueObject";
import { task_item, VideoSegmentEntityAdapter } from "@/app/service/adapter/oldErrAdapter";
import { VideoFlowProjectResponse, NewCharacterItem, NewCharacterListResponse, CharacterListByProjectWithHighlightResponse, CharacterUpdateAndRegenerateRequest, CharacterUpdateAndRegenerateResponse } from "./DTO/movieEdit";
import { RoleResponse } from "./DTO/movieEdit";
import { RoleRecognitionResponse } from "./DTO/movieEdit";
/**
* 角色替换参数接口
*/
export interface CharacterReplacement {
/** 原始角色名称 */
original_name: string;
/** 原始角色描述 */
original_description: string;
/** 新角色名称 */
new_name: string;
/** 新角色描述 */
new_description: string;
}
// API 响应类型
interface BaseApiResponse<T> {
code: number;
successful: boolean;
message: string;
data: T;
}
// 剧集详情数据类型
interface EpisodeDetail {
project_id: string;
name: string;
status: "running" | "completed";
step: "sketch" | "character" | "video" | "music" | "final_video";
last_message: string;
data: TaskData | null;
mode: "auto" | "manual";
resolution: "1080p" | "4k";
}
// 任务数据类型
interface TaskData {
sketch?: Array<{
url: string;
script: string;
bg_rgb: string[];
}>;
roles?: Array<{
name: string;
url: string;
sound: string;
soundDescription: string;
roleDescription: string;
}>;
videos?: Array<{
url: string;
script: string;
audio: string;
}>;
music?: Array<{
url: string;
script: string;
name: string;
duration: string;
totalDuration: string;
isLooped: boolean;
}>;
final?: {
url: string;
};
}
// 流式数据类型
export interface StreamData<T = any> {
category: "sketch" | "character" | "video" | "music" | "final_video";
message: string;
data: T;
status: "running" | "completed";
total?: number;
completed?: number;
all_completed?: boolean;
}
// 场景/分镜头数据结构
export interface Scene {
id: string;
name: string;
description: string;
plot: string;
dialogue: string;
narration: string;
imageUrl?: string;
}
// 角色数据结构
export interface Character {
name: string;
desc: string;
}
// 剧本到分镜头提示词模型
export interface ScenePrompts {
scenes: Scene[]; // 分场景列表
characters?: Character[]; // 角色列表
summary?: string; // 剧情概要
scene?: string; // 场景描述
atmosphere?: string; // 氛围描述
episode_id?: number; // 剧集ID
total_shots?: string; // 总镜头数
}
// 剧本转分镜头请求接口
export interface ScriptToSceneRequest {
script: string;
episode_id: number;
script_id: number;
project_type: ProjectTypeEnum.SCRIPT_TO_VIDEO;
}
// 视频转分镜头请求接口
export interface VideoToSceneRequest {
video_url: string;
episode_id: number;
script_id: number;
project_type: ProjectTypeEnum.VIDEO_TO_VIDEO;
}
// 转换分镜头请求类型
export type ConvertScenePromptRequest =
| ScriptToSceneRequest
| VideoToSceneRequest;
// 转换分镜头响应接口
export type ConvertScenePromptResponse = BaseApiResponse<ScenePrompts>;
/**
* 将剧本或视频转换为分镜头提示词
* @param request - 请求参数,根据 project_type 自动判断是剧本还是视频模式
* @returns Promise<ConvertScenePromptResponse>
*/
export const convertScenePrompt = async (
request: ConvertScenePromptRequest
): Promise<ConvertScenePromptResponse> => {
// return post<ConvertScenePromptResponse>('/video_flow/convert-scene-prompts', request);
return new Promise((resolve) => {
setTimeout(() => {
resolve({
code: 0,
message: "success",
data: {
scenes: [],
characters: [],
summary: "",
scene: "",
atmosphere: "",
episode_id: 0,
total_shots: "",
},
successful: true,
});
}, 0);
});
};
/**
* 剧本转分镜头提示词
* @param script - 剧本内容
* @returns Promise<ConvertScenePromptResponse>
*/
export const convertScriptToScene = async (
script: string,
episode_id: number,
script_id: number
): Promise<ConvertScenePromptResponse> => {
return convertScenePrompt({
script,
episode_id,
script_id,
project_type: ProjectTypeEnum.SCRIPT_TO_VIDEO,
});
};
/**
* 视频转分镜头提示词
* @param video_url - 视频链接
* @returns Promise<ConvertScenePromptResponse>
*/
export const convertVideoToScene = async (
video_url: string,
episode_id: number,
script_id: number
): Promise<ConvertScenePromptResponse> => {
return convertScenePrompt({
video_url,
episode_id,
script_id,
project_type: ProjectTypeEnum.VIDEO_TO_VIDEO,
});
};
// 新-获取剧集详情
export const detailScriptEpisodeNew = async (data: {
project_id: string;
}): Promise<ApiResponse<VideoFlowProjectResponse>> => {
return post("/movie/get_movie_project_detail", data);
};
// 获取 title 接口
export const getScriptTitle = async (data: {
project_id: string;
}): Promise<ApiResponse<any>> => {
return post<ApiResponse<any>>("/movie/get_movie_project_description", data);
};
// 获取 数据 全量(需轮询)
export const getRunningStreamData = async (data: {
project_id: string;
}): Promise<ApiResponse<any>> => {
return post<ApiResponse<any>>("/movie/get_status", data);
};
// 获取 脚本 接口
export const getScriptTags = async (data: {
project_id: string;
}): Promise<any> => {
return post<any>("/movie/text_to_script_tags", data);
};
// 获取 loading-场景 接口
export const getSceneJson = async (data: {
project_id: string;
}): Promise<ApiResponse<any>> => {
return post<any>("/movie/scene_json", data);
};
// 获取 loading-分镜 接口
export const getShotSketchJson = async (data: {
project_id: string;
}): Promise<ApiResponse<any>> => {
return post<any>("/movie/shot_sketch_json", data);
};
// 获取 loading-视频 接口
export const getVideoJson = async (data: {
project_id: string;
}): Promise<ApiResponse<any>> => {
return post<any>("/movie/video_json", data);
};
/**
* 重新生成角色
* @param request - 重新生成角色请求参数
* @returns Promise<ApiResponse<RoleEntity>>
*/
export const regenerateRole = async (request: {
/** 角色提示词 */
prompt: string;
/** 标签列表 */
tagTypes: TagValueObject[];
/** 角色ID可选如果重新生成现有角色 */
roleId?: string;
}): Promise<ApiResponse<RoleEntity>> => {
return post<ApiResponse<any>>("/movie/regenerate_role", request);
};
/**
* 应用角色到分镜
* @param request - 应用角色请求参数
* @returns Promise<ApiResponse<任务状态>>
*/
export const applyRoleToShots = async (request: {
/** 项目ID */
project_id: string;
/** 分镜ID列表 */
shot_id: string;
/** 角色替换参数列表 */
character_replacements: CharacterReplacement[];
/** 是否等待完成 */
wait_for_completion?: boolean;
/** 数据缓存 */
character_draft: string;
}): Promise<ApiResponse<{
/** 任务ID */
task_id: string;
/** 项目ID */
project_id: string;
/** 分镜ID */
shot_id: string;
/** 任务状态 */
status: string;
/** 状态描述 */
message: string;
/** 视频URL列表仅当wait_for_completion=true且完成时 */
urls?: string[];
/** 是否完成 */
finished: boolean;
/** 耗时仅当wait_for_completion=true时 */
elapsed_time?: number;
}>> => {
return post("/movie/regenerate_shot_video", request);
};
/**
* 获取角色应用到的分镜列表
* @param request - 获取角色分镜列表请求参数
* @returns Promise<ApiResponse<分镜列表>>
*/
export const getRoleShots = async (request: {
/** 角色ID */
roleId: string;
}): Promise<
ApiResponse<{
/** 分镜列表 */
shots: VideoSegmentEntity[];
/** 已应用的分镜ID列表 */
appliedShotIds: string[];
}>
> => {
return post<ApiResponse<any>>("/movie/get_role_shots", request);
};
/**
* 获取角色列表
* @param request - 获取角色列表请求参数
* @returns Promise<ApiResponse<角色实体列表>>
*/
export const getRoleList = async (request: {
/** 项目ID */
projectId: string;
}): Promise<ApiResponse<RoleEntity[]>> => {
return post<ApiResponse<any>>("/movie/get_role_list", request);
};
/**
* 获取角色数据
* @param request - 获取角色数据请求参数
* @returns Promise<ApiResponse<{ AI文本数据, 标签列表 }>>
*/
export const getRoleData = async (request: {
/** 角色ID */
roleId: string;
}): Promise<
ApiResponse<{
/** AI文本数据 */
text: AITextEntity;
/** 标签列表 */
tags: TagValueObject[];
}>
> => {
return post<ApiResponse<any>>("/movie/get_role_data", request);
};
/**
* 获取用户角色库
* @returns Promise<ApiResponse<角色实体列表>>
*/
export const getUserRoleLibrary = async (): Promise<
ApiResponse<RoleEntity[]>
> => {
return post<ApiResponse<any>>("/movie/get_user_role_library", {});
};
/**
* 替换角色
* @param request - 替换角色请求参数
* @returns Promise<ApiResponse<替换结果>>
*/
export const replaceRole = async (request: {
/** 当前角色ID */
currentRoleId: string;
/** 替换的角色ID */
replaceRoleId: string;
}): Promise<ApiResponse<any>> => {
return post<ApiResponse<any>>("/movie/replace_role", request);
};
/**
* 修改标签
* @param request - 修改标签请求参数
* @returns Promise<ApiResponse<修改后的标签>>
*/
export const updateTag = async (request: {
/** 标签ID */
tagId: string;
/** 新的标签内容 */
content: string | number;
}): Promise<ApiResponse<TagValueObject>> => {
return post<ApiResponse<any>>("/movie/update_tag", request);
};
/**
* 修改文案
* @param request - 修改文案请求参数
* @returns Promise<ApiResponse<修改后的文案>>
*/
export const updateText = async (request: {
/** 文案ID */
textId: string;
/** 新的文案内容 */
content: string;
}): Promise<ApiResponse<AITextEntity>> => {
return post<ApiResponse<any>>("/movie/update_text", request);
};
/**
* 重新生成场景
* @param request - 重新生成场景请求参数
* @returns Promise<ApiResponse<重新生成的场景>>
*/
export const regenerateScene = async (request: {
/** 场景提示词 */
prompt: string;
/** 标签列表 */
tagTypes: TagValueObject[];
/** 场景ID可选如果重新生成现有场景 */
sceneId?: string;
}): Promise<ApiResponse<SceneEntity>> => {
return post<ApiResponse<any>>("/movie/regenerate_scene", request);
};
/**
* 应用场景到分镜
* @param request - 应用场景请求参数
* @returns Promise<ApiResponse<应用结果>>
*/
export const applySceneToShots = async (request: {
/** 场景ID */
sceneId: string;
/** 分镜ID列表 */
shotIds: string[];
}): Promise<ApiResponse<any>> => {
return post<ApiResponse<any>>("/movie/apply_scene_to_shots", request);
};
/**
* 获取场景数据
* @param request - 获取场景数据请求参数
* @returns Promise<ApiResponse<{ AI文本数据, 标签列表 }>>
*/
export const getSceneData = async (request: {
/** 场景ID */
sceneId: string;
}): Promise<
ApiResponse<{
/** AI文本数据 */
text: AITextEntity;
/** 标签列表 */
tags: TagValueObject[];
}>
> => {
return post<ApiResponse<any>>("/movie/get_scene_data", request);
};
/**
* 获取场景列表
* @param request - 获取场景列表请求参数
* @returns Promise<ApiResponse<场景实体列表>>
*/
export const getSceneList = async (request: {
/** 项目ID */
projectId: string;
}): Promise<ApiResponse<SceneEntity[]>> => {
return post<ApiResponse<any>>("/movie/get_scene_list", request);
};
/**
* 获取场景应用到的分镜列表
* @param request - 获取场景分镜列表请求参数
* @returns Promise<ApiResponse<分镜列表>>
*/
export const getSceneShots = async (request: {
/** 场景ID */
sceneId: string;
}): Promise<
ApiResponse<{
/** 分镜列表 */
shots: VideoSegmentEntity[];
/** 已应用的分镜ID列表 */
appliedShotIds: string[];
}>
> => {
return post<ApiResponse<any>>("/movie/get_scene_shots", request);
};
/**
* 获取分镜关联的角色信息列表
* @param request - 获取分镜角色信息请求参数
* @returns Promise<ApiResponse<角色实体列表>>
*/
export const getShotRoles = async (request: {
/** 分镜ID */
shotId: string;
}): Promise<ApiResponse<RoleEntity[]>> => {
return post<ApiResponse<any>>("/movie/get_shot_roles", request);
};
/**
* 获取分镜关联的场景信息列表
* @param request - 获取分镜场景信息请求参数
* @returns Promise<ApiResponse<场景实体列表>>
*/
export const getShotScenes = async (request: {
/** 分镜ID */
shotId: string;
}): Promise<ApiResponse<SceneEntity[]>> => {
return post<ApiResponse<any>>("/movie/get_shot_scenes", request);
};
/**
* 获取分镜详细数据
* @param request - 获取分镜数据请求参数
* @returns Promise<ApiResponse<{ AI文本数据, 标签列表 }>>
*/
export const getShotData = async (request: {
/** 分镜ID */
shotId: string;
}): Promise<
ApiResponse<{
/** AI文本数据 */
text: AITextEntity;
/** 标签列表 */
tags: TagValueObject[];
}>
> => {
return post<ApiResponse<any>>("/movie/get_shot_data", request);
};
/**
* 重新生成分镜
* @param request - 重新生成分镜请求参数
* @returns Promise<ApiResponse<任务状态>>
*/
export const regenerateShot = async (request: {
/** 项目ID */
project_id:string;
/** 分镜ID */
shot_id?: string;
/** 镜头描述 */
shot_descriptions?: task_item;
// /** 角色ID替换参数格式为{oldId:string,newId:string}[] */
// roleReplaceParams?: { oldId: string; newId: string }[];
// /** 场景ID替换参数格式为{oldId:string,newId:string}[] */
// sceneReplaceParams?: { oldId: string; newId: string }[];
}): Promise<ApiResponse<{
/** 任务ID */
task_id: string;
/** 项目ID */
project_id: string;
/** 分镜ID */
shot_id: string;
/** 任务状态 */
status: string;
/** 状态描述 */
message: string;
/** 视频URL列表仅当wait_for_completion=true且完成时 */
urls?: string[];
/** 是否完成 */
finished: boolean;
/** 耗时仅当wait_for_completion=true时 */
elapsed_time?: number;
}>> => {
return post("/movie/regenerate_shot_video", request);
};
/**
* 获取分镜列表
* @param request - 获取分镜列表请求参数
* @returns Promise<ApiResponse<分镜实体列表>>
*/
export const getShotList = async (request: {
/** 项目ID */
project_id: string;
}): Promise<ApiResponse<VideoSegmentEntityAdapter>> => {
return post<ApiResponse<any>>("/movie_cut/get_task_list", request);
};
/**
* 替换分镜角色
* @param request - 替换分镜角色请求参数
* @returns Promise<ApiResponse<替换结果>>
*/
export const replaceShotRole = async (request: {
/** 分镜ID */
shotId: string;
/** 旧角色ID */
oldRoleId: string;
/** 新角色ID */
newRoleId: string;
}): Promise<ApiResponse<any>> => {
return post<ApiResponse<any>>("/movie/replace_shot_role", request);
};
/**
* 获取分镜视频剧本内容
* @param request - 获取分镜视频剧本请求参数
* @returns Promise<ApiResponse<剧本片段列表>>
*/
export const getShotVideoScript = async (request: {
/** 分镜ID */
shotId: string;
}): Promise<ApiResponse<string>> => {
return post<ApiResponse<any>>("/movie/get_shot_video_script", request);
};
/**
* AI生成剧本流式接口
* @param request - AI生成剧本请求参数
* @returns Promise<ApiResponse<流式数据>>
*/
export const generateScriptStream = (
request: {
/** 剧本提示词 */
text: string;
},
onData: (data: any) => void
): Promise<void> => {
return new Promise((resolve, reject) => {
streamJsonPost("/text_to_script/stream", request, (data) => {
switch(data.status) {
case 'streaming':
onData(data.content);
break;
case 'completed':
console.log('生成完成:', data.message);
resolve()
return;
case 'error':
console.error('生成失败:', data.message);
reject(data.message)
return;
}
})
})
};
/**
* 应用剧本
* @param request - 应用剧本请求参数
* @returns Promise<ApiResponse<应用结果>>
*/
export const applyScriptToShot = async (request: {
/** 项目ID */
project_id: string;
})=> {
return post<ApiResponse<any>>("/movie/create_movie_project_plan_v1", request);
};
/**
* 获取项目剧本数据
* @param request 请求参数
*/
export const getProjectScript = async (request: {
/** 项目ID */
project_id: string;
})=> {
return post<
ApiResponse<{
/** 项目id */
project_id: string;
/** 生成的剧本文本 */
generated_script: string;
}>
>("/movie/get_generated_script_by_project_id", request);
};
/**
* 保存剧本
* @param request 保存剧本请求参数
* @returns Promise<ApiResponse<保存结果>>
*/
export const saveScript = async (request: {
/** 项目ID */
project_id: string;
/**用户id */
user_id:string;
/** 剧本文本 */
generated_script: string;
}): Promise<ApiResponse<any>> => {
return post<ApiResponse<any>>("/movie/update_generated_script", request);
};
/**
* 中断视频任务
* @returns Promise<ApiResponse<{ projectId: string }>>
*/
export const abortVideoTask = async (request: {
/** 项目ID */
project_id: string;
}): Promise<ApiResponse<any>> => {
return post("/movie/abort_video_task", request);
};
export const pausePlanFlow = async (request: {
/** 项目ID */
project_id: string;
/** 计划ID */
plan_id: string;
}): Promise<ApiResponse<any>> => {
return post("/api/v1/video/pause", request);
};
export const resumePlanFlow = async (request: {
/** 项目ID */
project_id: string;
/** 计划ID */
plan_id: string;
}): Promise<ApiResponse<any>> => {
return post("/api/v1/video/resume", request);
};
export const createMovieProjectV1 = async (request: {
/** 剧本内容 */
script: string;
/** 用户ID */
user_id: string;
/** 模式automatic | manual */
mode: "automatic" | "manual";
/** 分辨率720p | 1080p | 4k */
resolution: "720p" | "1080p" | "4k";
/** 语言 */
language: string;
/** 视频时长 */
video_duration: string;
}) => {
return post<ApiResponse<{
/** 项目ID */
project_id: string;
/** 计划ID */
plan_id: string;
/** 项目名称 */
name: string;
/** 项目状态 */
status: string;
}>>("/movie/create_movie_project_v1", request);
};
/**
* 增强剧本流式接口
* @param request - 增强剧本请求参数
* @param onData - 流式数据回调
* @returns Promise<void>
*/
export const enhanceScriptStream = (
request: {
/** 原始剧本文本 */
original_script: string;
/** AI优化要求 */
aiOptimizing: string;
},
onData: (data: any) => void
): Promise<void> => {
return new Promise((resolve, reject) => {
streamJsonPost("/movie/enhance_script", request, (data) => {
switch(data.status) {
case 'streaming':
onData(data.content);
break;
case 'completed':
console.log('剧本增强完成:', data.message);
resolve()
return;
case 'error':
console.error('剧本增强失败:', data.message);
reject(data.message)
return;
}
})
})
};
/**
* AI优化镜头内容接口
* @param request - AI优化请求参数
* @returns Promise<ApiResponse<LensType[]>> 优化后的镜头数据
*/
export const optimizeShotContent = async (request: {
/** 视频片段ID */
shotId: string;
/** 用户优化需求 */
userRequirement: string;
/** 镜头数据数组 */
lensData: LensType[];
}): Promise<ApiResponse<LensType[]>> => {
return post<ApiResponse<LensType[]>>("/api/v1/shot/optimize_content", request);
};
/**
* 暂停电影项目计划
* @param request - 暂停项目请求参数
* @returns Promise<ApiResponse<暂停结果>>
*/
export const pauseMovieProjectPlan = async (request: {
/** 项目ID */
project_id: string;
}): Promise<ApiResponse<{
/** 项目ID */
project_id: string;
/** 暂停结果描述 */
message: string;
}>> => {
return post("/movie/pause_movie_project_plan", request);
};
/**
* 继续电影项目计划
* @param request - 继续项目请求参数
* @returns Promise<ApiResponse<继续结果>>
*/
export const resumeMovieProjectPlan = async (request: {
/** 项目ID */
project_id: string;
}): Promise<ApiResponse<{
/** 项目ID */
project_id: string;
/** 继续结果描述 */
message: string;
}>> => {
return post("/movie/resume_movie_project_plan", request);
};
/**
* AI优化角色描述
* @param request - AI优化角色描述请求参数
* @returns Promise<ApiResponse<优化后的角色描述>>
*/
export const optimizeRoleDescription = async (request: {
/** 角色ID */
roleId: string;
/** 用户优化建议 */
userSuggestion: string;
/** 角色描述文本 */
roleDescription: string;
}): Promise<ApiResponse<{
/** 优化后的角色描述 */
optimizedDescription: string;
}>> => {
return post("/movie/optimize_role_description", request);
};
/**
* 更新分镜提示词数据
* @param request - 更新分镜提示词请求参数
* @returns Promise<ApiResponse<any>> 更新结果
*/
export const updateShotPrompt = async (request: {
/** 项目ID */
project_id: string;
/** 分镜ID */
shot_id: string;
/** 镜头描述 */
shot_descriptions: task_item;
}): Promise<ApiResponse<any>> => {
return post("/movie/update_shot_prompt", request);
};
/**
* 人脸识别接口
* @param request - 人脸识别请求参数
* @returns Promise<ApiResponse<RoleRecognitionResponse>> 人脸识别结果
*/
export const faceRecognition = async (request: {
/** 项目ID */
project_id: string;
/** 视频ID */
video_id: string;
/** 目标图片URL */
target_image_url: string;
}): Promise<ApiResponse<RoleRecognitionResponse>> => {
return post("/character/face_recognition", request);
};
/**
* 获取所有角色列表接口
* @returns Promise<ApiResponse<NewCharacterListResponse>> 所有角色列表
*/
export const getAllCharacterList = async (request:{
user_id:string;
}): Promise<ApiResponse<NewCharacterListResponse>> => {
return post<ApiResponse<NewCharacterListResponse>>("/character/list_all", request);
};
/**
* 获取相似角色列表接口
* @param request - 获取相似角色请求参数
* @returns Promise<ApiResponse<相似角色列表>>
*/
export const getSimilarCharacters = async (request: {
/** 用户ID */
userId: string;
/** 用户描述(角色描述) */
user_description: string;
/** 相似度限制 */
similar_limit: number;
}): Promise<ApiResponse<{
/** 相似角色列表 */
characters: Array<{
/** 角色ID */
id: string;
/** 角色名称 */
name: string;
/** 角色描述 */
description: string;
/** 角色图片 */
image_url: string;
/** 相似度分数 */
similarity_score: number;
}>;
/** 总数量 */
total_count: number;
}>> => {
return post("/character/search_and_recommend", request);
};
/**
* 获取项目角色列表(含高亮关键词)接口
* @param request - 项目角色列表请求参数
* @returns Promise<ApiResponse<RoleResponse[]>> 项目角色列表
*/
export const getCharacterListByProjectWithHighlight = async (request: {
/** 项目ID */
project_id: string;
/** 每个角色最多提取的高亮关键词数量 */
max_keywords?: number;
}): Promise<ApiResponse<RoleResponse>> => {
return post("/character/list_by_project_with_highlight", request);
};
/**
* 角色更新和重新生成接口
* @param request - 角色更新和重新生成请求参数
* @returns Promise<ApiResponse<CharacterUpdateAndRegenerateResponse>> 更新后的角色信息
*/
export const updateAndRegenerateCharacter = async (request: CharacterUpdateAndRegenerateRequest) => {
return post<ApiResponse<CharacterUpdateAndRegenerateResponse>>("/character/update_and_regenerate", request);
};
/**
* 角色描述智能优化接口
* @param request - 角色描述优化请求参数
* @returns Promise<ApiResponse<优化后的角色描述>>
*/
export const generateCharacterDescription = async (request: {
/** 前端提供的原始文字描述 */
original_text: string;
}): Promise<ApiResponse<{
/** 优化后的角色描述 */
optimized_description: string;
/** 关键词列表 */
keywords: string[];
}>> => {
return post("/character/generate_description", request);
};
/**
* 批量更新视频片段状态和视频地址接口
* @param request - 批量更新视频片段请求参数
* @returns Promise<ApiResponse<更新结果>>
*/
export const batchUpdateVideoSegments = async (request: {
/** 项目ID */
project_id: string;
/** 要更新的视频片段列表 */
segments: Array<{
/** 视频片段ID */
shot_id: string;
/** 新的视频地址列表 */
video_urls: string[];
/** 新的状态 0:视频加载中 1:任务已完成 2:任务失败 */
status: number;
/** 优化后的描述文本 */
optimized_description?: string;
/** 关键词列表 */
keywords?: string[];
}>;
}): Promise<ApiResponse<{
/** 更新成功的片段数量 */
success_count: number;
/** 更新失败的片段数量 */
failed_count: number;
/** 更新结果详情 */
results: Array<{
shot_id: string;
success: boolean;
message?: string;
}>;
}>> => {
return post("/movie/batch_update_video_segments", request);
};
/**
* 获取角色在项目中的视频片段列表接口
* @param request - 获取角色视频片段请求参数
* @returns Promise<ApiResponse<角色视频片段列表>>
*/
export const getCharacterShots = async (request: {
/** 项目ID */
project_id: string;
/** 角色名称 */
character_name: string;
}): Promise<ApiResponse<{
/** 角色名称 */
character_name: string;
/** 项目ID */
project_id: string;
/** 场景列表 */
scenes: Array<{
/** 视频ID */
video_id: string;
/** 视频URL列表 */
video_urls: {
video_url: string;
video_id: string;
video_status: number|null;
}[];
}>;
/** 总数量 */
total_count: number;
}>> => {
return post("/character/get_character_scenes", request);
};
/**
* 保存重新生成的角色到角色库
* @param request - 保存重新生成角色请求参数
* @returns Promise<ApiResponse<保存结果>>
*/
export const saveRegeneratedCharacter = async (request: {
/** 用户ID */
user_id: string;
/** 项目ID用于从项目脚本中提取角色信息 */
project_id: string;
/** 修改前的用户名称,用于在脚本中查找对应角色 */
original_character_name: string;
/** 角色描述文本 */
character_description: string;
/** 角色图片URL */
character_image: string;
/** 多个视频地址(支持任意数量) */
video_urls: string[];
}): Promise<ApiResponse<{
/** 保存成功的角色ID */
character_id: string;
/** 保存结果消息 */
message: string;
}>> => {
return post("/character/save_regenerated_character", request);
};
/**
* 分析图片并生成描述
* @description 接收图片URL调用AI服务分析图片并生成详细描述
* @param request - 图片分析请求参数
* @returns Promise<ApiResponse<图片描述结果>>
*/
export const analyzeImageDescription = async (request: {
/** 图片的URL地址必须是有效的HTTP/HTTPS链接 */
image_url: string;
}): Promise<ApiResponse<{
/** 图片描述文本 */
description: string;
/** 图片URL */
image_url: string;
/** 高亮关键词列表 */
highlights: string[];
}>> => {
return post<ApiResponse<{
description: string;
image_url: string;
highlights: string[];
}>>("/character/analyze_image_description", request);
};
/**
* 检查分镜视频状态
* @description 保存当前项目数据
* @param request - 请求参数
* @returns Promise<ApiResponse<any>> 保存结果
*/
export const checkShotVideoStatus = async (request: {
/** 项目ID */
project_id: string;
}): Promise<ApiResponse<any>> => {
return post<ApiResponse<any>>("/check_shot_video_status", request);
};
/**
* 智能检测修改类型并进行相应的修改操作
* @description 支持角色修改和分镜修改的自动判断与批量处理
* @param request - 请求参数
* @returns Promise<ApiResponse<智能修改结果>>
*/
export const modifyCharacterOrScene = async (request: {
/** 项目ID */
project_id: string;
/** 新的角色库角色 */
character_id: {
/** 角色ID */
character_id: string;
/** 角色名称 */
name: string;
}[];
/** 视频任务关联列表 */
video_tasks: Array<{
/** 生成视频的任务ID */
task_id: string;
/** 该任务对应的video_id列表 */
video_ids: string[];
}>;
}) => {
return post<ApiResponse<{
project_id: string;
modify_type: "character" | "scene";
video_tasks: Array<{
task_id: string;
video_ids: string[];
}>;
message: string;
details: Record<string, any>;
warning: string | null;
video_check_tasks: Array<{
task_id: string;
video_ids: string[];
}>;
video_check_started: number;
}>>("/character/modify_character_or_scene", request);
};