mirror of
https://github.com/basketikun/infinite-canvas.git
synced 2026-08-05 17:04:27 +08:00
feat(api): add support for 火山方舟 protocol and enhance video reference validation
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { modelOptionName, resolveModelRequestConfig, type AiConfig } from "@/stores/use-config-store";
|
||||
import { resolveModelRequestConfig, type AiConfig } from "@/stores/use-config-store";
|
||||
import type { ReferenceImage } from "@/types/image";
|
||||
import type { ReferenceAudio, ReferenceVideo } from "@/types/media";
|
||||
|
||||
@@ -7,9 +7,10 @@ export const SEEDANCE_REFERENCE_LIMITS = {
|
||||
videos: 3,
|
||||
audios: 3,
|
||||
imageMaxBytes: 30 * 1024 * 1024,
|
||||
videoMaxBytes: 50 * 1024 * 1024,
|
||||
videoMaxBytes: 200 * 1024 * 1024,
|
||||
audioMaxBytes: 15 * 1024 * 1024,
|
||||
};
|
||||
export const SEEDANCE_VIDEO_MIME_TYPES = ["video/mp4", "video/quicktime"];
|
||||
|
||||
export const seedanceResolutionOptions = [
|
||||
{ value: "480p", label: "480p" },
|
||||
@@ -56,28 +57,13 @@ const seedancePixels = {
|
||||
},
|
||||
} as const;
|
||||
|
||||
export function isSeedanceVideoConfig(config: AiConfig | Pick<AiConfig, "model" | "videoModel" | "baseUrl">) {
|
||||
export function isSeedanceVideoConfig(config: AiConfig | Pick<AiConfig, "model" | "videoModel" | "apiFormat">) {
|
||||
const requestConfig = "channels" in config ? resolveModelRequestConfig(config, config.model || config.videoModel) : config;
|
||||
return isSeedanceVideoModel(modelOptionName(requestConfig.model || requestConfig.videoModel)) || isArkPlanBaseUrl(requestConfig.baseUrl);
|
||||
return requestConfig.apiFormat === "ark";
|
||||
}
|
||||
|
||||
export function isSeedanceVideoModel(model: string) {
|
||||
const value = model.toLowerCase();
|
||||
return value.includes("seedance") || value.includes("doubao-seedance");
|
||||
}
|
||||
|
||||
export function isSeedanceFastModel(model: string) {
|
||||
const value = model.toLowerCase();
|
||||
return isSeedanceVideoModel(value) && value.includes("fast");
|
||||
}
|
||||
|
||||
export function isArkPlanBaseUrl(baseUrl: string) {
|
||||
return baseUrl.toLowerCase().includes("ark.cn-beijing.volces.com/api/plan/v3") || baseUrl.toLowerCase().includes("/api/plan/v3");
|
||||
}
|
||||
|
||||
export function normalizeSeedanceResolution(value: string, model = "") {
|
||||
export function normalizeSeedanceResolution(value: string) {
|
||||
const normalized = normalizeResolutionToken(value);
|
||||
if (isSeedanceFastModel(model) && normalized === "1080p") return "720p";
|
||||
return seedanceResolutionOptions.some((item) => item.value === normalized) ? normalized : "720p";
|
||||
}
|
||||
|
||||
@@ -149,7 +135,8 @@ export function seedanceVideoReferenceError(videos: ReferenceVideo[]) {
|
||||
for (let index = 0; index < videos.length; index += 1) {
|
||||
const video = videos[index];
|
||||
const label = seedanceReferenceLabel("video", index);
|
||||
if (video.bytes && video.bytes > SEEDANCE_REFERENCE_LIMITS.videoMaxBytes) return `${label} 超过 50MB,请压缩后再上传`;
|
||||
if (!SEEDANCE_VIDEO_MIME_TYPES.includes(video.type)) return `${label} 仅支持 mp4/mov 格式`;
|
||||
if (video.bytes && video.bytes > SEEDANCE_REFERENCE_LIMITS.videoMaxBytes) return `${label} 超过 200MB,请压缩后再上传`;
|
||||
if (video.durationMs) {
|
||||
if (video.durationMs < 2000 || video.durationMs > 15000) return `${label} 时长需要在 2-15 秒之间`;
|
||||
totalDurationMs += video.durationMs;
|
||||
@@ -159,7 +146,7 @@ export function seedanceVideoReferenceError(videos: ReferenceVideo[]) {
|
||||
const ratio = video.width / video.height;
|
||||
if (ratio < 0.4 || ratio > 2.5) return `${label} 宽高比需要在 0.4-2.5 之间`;
|
||||
const pixels = video.width * video.height;
|
||||
if (pixels < 640 * 640 || pixels > 2206 * 946) return `${label} 像素总量不符合 Seedance 要求,请转成 480p/720p/1080p 后再上传`;
|
||||
if (pixels < 640 * 640 || pixels > 3326 * 2494) return `${label} 总像素需要在 409600-8295044 之间`;
|
||||
}
|
||||
}
|
||||
if (totalDurationMs > 15000) return "Seedance 参考视频总时长不能超过 15 秒";
|
||||
|
||||
Reference in New Issue
Block a user