199 lines
9.1 KiB
JavaScript
199 lines
9.1 KiB
JavaScript
"use strict";
|
||
var __defProp = Object.defineProperty;
|
||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||
var __export = (target, all) => {
|
||
for (var name in all)
|
||
__defProp(target, name, { get: all[name], enumerable: true });
|
||
};
|
||
var __copyProps = (to, from, except, desc) => {
|
||
if (from && typeof from === "object" || typeof from === "function") {
|
||
for (let key of __getOwnPropNames(from))
|
||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||
}
|
||
return to;
|
||
};
|
||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||
|
||
// ../huobao-source/backend/src/services/adapters/local-video.ts
|
||
var local_video_exports = {};
|
||
__export(local_video_exports, {
|
||
LocalVideoAdapter: () => LocalVideoAdapter
|
||
});
|
||
module.exports = __toCommonJS(local_video_exports);
|
||
|
||
// ../huobao-source/backend/src/services/adapters/url.ts
|
||
function joinProviderUrl(baseUrl, requiredPrefix, path) {
|
||
const normalizedBase = (baseUrl || "").replace(/\/+$/, "");
|
||
const normalizedPrefix = normalizeSegment(requiredPrefix);
|
||
const normalizedPath = normalizeSegment(path);
|
||
if (!normalizedBase) {
|
||
return `${normalizedPrefix}${normalizedPath}`;
|
||
}
|
||
try {
|
||
const url = new URL(normalizedBase);
|
||
const currentPath = url.pathname.replace(/\/+$/, "");
|
||
const mergedPrefix = currentPath.endsWith(normalizedPrefix) ? currentPath : `${currentPath}${normalizedPrefix}`;
|
||
url.pathname = `${mergedPrefix}${normalizedPath}`.replace(/\/{2,}/g, "/");
|
||
return url.toString();
|
||
} catch {
|
||
const basePath = normalizedBase.endsWith(normalizedPrefix) ? normalizedBase : `${normalizedBase}${normalizedPrefix}`;
|
||
return `${basePath}${normalizedPath}`;
|
||
}
|
||
}
|
||
function normalizeSegment(segment) {
|
||
if (!segment) return "";
|
||
return segment.startsWith("/") ? segment : `/${segment}`;
|
||
}
|
||
|
||
// ../huobao-source/backend/src/services/adapters/minimax-video.ts
|
||
var H3_MODEL_PREFIX = "minimax-h3";
|
||
var DEFAULT_MODEL = "MiniMax-H3";
|
||
var REF_LIMITS = { images: 9, videos: 3, audios: 3, total: 12 };
|
||
var PROMPT_MAX_CHARS = 7e3;
|
||
var VALID_RATIOS = /* @__PURE__ */ new Set(["16:9", "9:16", "1:1", "4:3", "3:4", "21:9"]);
|
||
function parseUrlArray(raw) {
|
||
if (!raw) return [];
|
||
try {
|
||
const arr = JSON.parse(raw);
|
||
return Array.isArray(arr) ? arr.filter((u) => typeof u === "string" && u.trim()) : [];
|
||
} catch {
|
||
return [];
|
||
}
|
||
}
|
||
var MiniMaxVideoAdapter = class {
|
||
provider = "minimax";
|
||
buildGenerateRequest(config, record) {
|
||
const model = record.model || config.model || DEFAULT_MODEL;
|
||
if (!model.toLowerCase().startsWith(H3_MODEL_PREFIX)) {
|
||
throw new Error(`\u4EC5\u652F\u6301 MiniMax H3 \u7CFB\u5217\u6A21\u578B\uFF08MiniMax-H3*\uFF09\uFF0C\u5F53\u524D: ${model}`);
|
||
}
|
||
const prompt = (record.prompt || "").trim();
|
||
const refImages = parseUrlArray(record.referenceImageUrls);
|
||
const refVideos = parseUrlArray(record.referenceVideoUrls);
|
||
const refAudios = parseUrlArray(record.referenceAudioUrls);
|
||
const firstFrame = (record.firstFrameUrl || record.imageUrl || "").trim();
|
||
const lastFrame = (record.lastFrameUrl || "").trim();
|
||
if (!prompt) throw new Error("MiniMax H3 \u8981\u6C42\u5FC5\u987B\u63D0\u4F9B\u63D0\u793A\u8BCD\uFF08text content\uFF09");
|
||
if (prompt.length > PROMPT_MAX_CHARS) {
|
||
throw new Error(`\u63D0\u793A\u8BCD\u8D85\u957F\uFF1AMiniMax H3 \u4E0A\u9650 ${PROMPT_MAX_CHARS} \u5B57\u7B26\uFF0C\u5F53\u524D ${prompt.length}`);
|
||
}
|
||
const totalRefs = refImages.length + refVideos.length + refAudios.length + (firstFrame ? 1 : 0) + (lastFrame ? 1 : 0);
|
||
if (refImages.length > REF_LIMITS.images || refVideos.length > REF_LIMITS.videos || refAudios.length > REF_LIMITS.audios || totalRefs > REF_LIMITS.total) {
|
||
throw new Error(`\u53C2\u8003\u7D20\u6750\u8D85\u9650\uFF1A\u56FE\u7247\u2264${REF_LIMITS.images}\u3001\u89C6\u9891\u2264${REF_LIMITS.videos}\u3001\u97F3\u9891\u2264${REF_LIMITS.audios}\u3001\u603B\u6570\u2264${REF_LIMITS.total}`);
|
||
}
|
||
const content = [{ type: "text", text: prompt }];
|
||
if (firstFrame) content.push({ type: "image_url", image_url: { url: firstFrame }, role: "first_frame" });
|
||
if (lastFrame) content.push({ type: "image_url", image_url: { url: lastFrame }, role: "last_frame" });
|
||
for (const url of refImages) {
|
||
content.push({ type: "image_url", image_url: { url }, role: "reference_image" });
|
||
}
|
||
for (const url of refVideos) {
|
||
content.push({ type: "video_url", video_url: { url }, role: "reference_video" });
|
||
}
|
||
for (const url of refAudios) {
|
||
content.push({ type: "audio_url", audio_url: { url }, role: "reference_audio" });
|
||
}
|
||
const body = {
|
||
model,
|
||
content,
|
||
duration: this.normalizeDuration(record.duration),
|
||
resolution: this.normalizeResolution(record.resolution)
|
||
};
|
||
if (config.gpu && config.gpu !== "auto") body.gpu = config.gpu;
|
||
if (!firstFrame) {
|
||
const ratio = (record.aspectRatio || "").trim();
|
||
body.ratio = VALID_RATIOS.has(ratio) ? ratio : "16:9";
|
||
}
|
||
return {
|
||
url: joinProviderUrl(config.baseUrl, "/v2", "/video_generation"),
|
||
method: "POST",
|
||
headers: {
|
||
"Content-Type": "application/json",
|
||
"Authorization": `Bearer ${config.apiKey}`
|
||
},
|
||
body
|
||
};
|
||
}
|
||
parseGenerateResponse(result) {
|
||
const taskId = result.task_id ?? result.task?.id;
|
||
const state = result.task?.status ?? result.status;
|
||
const videoUrl = result.task?.content?.url || result.content?.url || result.video_url;
|
||
if (videoUrl && (!state || state === "succeeded")) {
|
||
return { isAsync: false, videoUrl, taskId: taskId == null ? void 0 : String(taskId), duration: result.task?.duration ?? result.duration };
|
||
}
|
||
if (taskId != null) return { isAsync: true, taskId: String(taskId) };
|
||
throw new Error("No task_id or video url in response");
|
||
}
|
||
buildPollRequest(config, taskId) {
|
||
return {
|
||
url: joinProviderUrl(config.baseUrl, "/v2", `/query/video_generation/${taskId}`),
|
||
method: "GET",
|
||
headers: {
|
||
"Authorization": `Bearer ${config.apiKey}`
|
||
},
|
||
body: void 0
|
||
};
|
||
}
|
||
parsePollResponse(result) {
|
||
const task = result.task && typeof result.task === "object" ? result.task : result;
|
||
const status = task.status;
|
||
if (status === "succeeded") {
|
||
return {
|
||
status: "completed",
|
||
videoUrl: task.content?.url || task.video_url,
|
||
duration: task.duration
|
||
};
|
||
}
|
||
if (status === "failed" || status === "cancelled") {
|
||
const err = task.error;
|
||
const msg = typeof err === "string" ? err : err?.message || JSON.stringify(err) || "Video generation failed";
|
||
const code = err && typeof err === "object" && err.code ? `[${err.code}] ` : "";
|
||
return { status: "failed", error: `${code}${msg}` };
|
||
}
|
||
return { status: "processing", stage: task.delivery?.status === "transferring" ? "transferring" : void 0 };
|
||
}
|
||
extractVideoUrl(result) {
|
||
const task = result.task && typeof result.task === "object" ? result.task : result;
|
||
return task.content?.url || task.video_url || null;
|
||
}
|
||
normalizeDuration(duration) {
|
||
const parsed = Math.round(Number(duration || 5));
|
||
if (!Number.isFinite(parsed)) return 5;
|
||
return Math.min(15, Math.max(4, parsed));
|
||
}
|
||
/** MiniMax 仅 768P / 2K 两档;项目侧 480p/720p 统一归到 768P,1080p/2K 归到 2K */
|
||
normalizeResolution(resolution) {
|
||
const r = (resolution || "").toLowerCase();
|
||
if (r === "2k" || r === "1080p") return "2K";
|
||
return "768P";
|
||
}
|
||
};
|
||
|
||
// ../huobao-source/backend/src/services/adapters/local-video.ts
|
||
var MODELS = /* @__PURE__ */ new Set(["MiniMax-H3", "MiniMax-H3-Hybrid", "MiniMax-H3-R2V-4Step", "LTX-2.3", "LTX-2.3-Text-Preserve", "Wan2.2-I2V", "MiniMax-H3-VDN-H3"]);
|
||
var LocalVideoAdapter = class extends MiniMaxVideoAdapter {
|
||
provider = "localvideo";
|
||
buildGenerateRequest(config, record) {
|
||
const model = record.model || config.model || "MiniMax-H3";
|
||
if (!MODELS.has(model)) throw new Error(`\u672C\u5730\u89C6\u9891\u4EFB\u52A1\u6C60\u4E0D\u652F\u6301\u6A21\u578B\uFF1A${model}`);
|
||
if (record.referenceFileUrl || record.referenceLinkUrl) throw new Error("\u672C\u5730\u89C6\u9891\u6682\u4E0D\u652F\u6301 file / link \u53C2\u8003\u7D20\u6750");
|
||
const request = super.buildGenerateRequest(config, { ...record, model: "MiniMax-H3" });
|
||
const body = request.body;
|
||
const resolution = String(record.resolution || "768P").toUpperCase();
|
||
if (!["480P", "720P", "768P", "1080P", "2K", "4K"].includes(resolution)) throw new Error("\u4E0D\u652F\u6301\u7684\u672C\u5730\u89C6\u9891\u5206\u8FA8\u7387");
|
||
if (resolution === "4K" && model !== "MiniMax-H3-VDN-H3") throw new Error("4K \u9700\u8981 VDN-H3 \u9AD8\u6E05\u5236\u4F5C\u6A21\u578B");
|
||
body.model = model;
|
||
body.resolution = resolution;
|
||
if (config.gpu && config.gpu !== "auto") body.gpu = config.gpu;
|
||
if (record.seed != null) body.seed = record.seed;
|
||
return request;
|
||
}
|
||
};
|
||
// Annotate the CommonJS export names for ESM import in node:
|
||
0 && (module.exports = {
|
||
LocalVideoAdapter
|
||
});
|