function object(value: unknown): Record { return value && typeof value === "object" && !Array.isArray(value) ? value as Record : {}; } export function canonicalVip98kVideoRatio(value: string) { return value === "landscape" ? "16:9" : value === "portrait" ? "9:16" : value; } export function vip98kVideoDurationBounds(schema: unknown, resolution?: string) { let min = 0, max = Infinity; let durations: number[] | undefined; const visit = (value: unknown) => { const current = object(value), properties = object(current.properties); const field = object(properties.duration_seconds || properties.duration); if (Number.isFinite(field.minimum)) min = Math.max(min, field.minimum); if (Number.isFinite(field.maximum)) max = Math.min(max, field.maximum); const allowed = Array.isArray(field.enum) ? field.enum : Number.isFinite(field.const) ? [field.const] : undefined; if (allowed) { const numbers = allowed.filter((n: unknown): n is number => typeof n === "number" && Number.isFinite(n) && n > 0); durations = durations ? durations.filter(n => numbers.includes(n)) : numbers; } for (const child of Array.isArray(current.allOf) ? current.allOf : []) visit(child); const condition = object(object(current.if).properties).resolution; if (resolution && object(condition).const === resolution) visit(current.then); }; visit(schema); return { min, max, durations }; } export function mapVip98kVideoParameters(body: Record, schema: unknown) { const properties = object(object(schema).properties); const ratios = object(properties.aspect_ratio).enum; if (Array.isArray(ratios) && !ratios.includes(body.aspect_ratio)) { const alias = body.aspect_ratio === "16:9" ? "landscape" : body.aspect_ratio === "9:16" ? "portrait" : undefined; if (!alias || !ratios.includes(alias)) throw Error("供应商当前线路不支持所选视频比例"); body.aspect_ratio = alias; } const resolutions = object(properties.resolution).enum; if (body.resolution && Array.isArray(resolutions) && !resolutions.includes(body.resolution)) throw Error("供应商当前线路不支持所选视频清晰度,请同步模型规格后重试"); const seconds = Number(body.duration_seconds ?? body.duration); if (seconds) { const bounds = vip98kVideoDurationBounds(schema, String(body.resolution || "")); if (seconds < bounds.min || seconds > bounds.max || (bounds.durations && !bounds.durations.includes(seconds))) throw Error("供应商当前清晰度不支持所选视频时长,请调整镜头时长"); } }