forked from 77media/video-flow
201 lines
4.9 KiB
TypeScript
201 lines
4.9 KiB
TypeScript
import { post } from './request';
|
|
import { ProjectTypeEnum } from '@/app/model/enums';
|
|
import { ApiResponse } from '@/api/common';
|
|
|
|
// 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 {
|
|
category: 'sketch' | 'character' | 'video' | 'music' | 'final_video';
|
|
message: string;
|
|
data: any;
|
|
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<any>> => {
|
|
return post<ApiResponse<any>>('/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);
|
|
}; |