This commit is contained in:
Azmat@qq.com
2026-09-16 16:52:01 +08:00
parent 7f5307d97c
commit b487b65575
5 changed files with 158 additions and 26 deletions
@@ -12,7 +12,7 @@ export const OMNI_RESOLUTIONS = ["1080p", "720p", "480p"];
export const OMNI_RATIOS = ["9:16", "16:9", "1:1", "4:3", "3:4"];
export const OMNI_VIDEO_DURATIONS = [
"智能时长", "4 秒", "5 秒", "6 秒", "7 秒", "8 秒", "9 秒", "10 秒",
"11 秒", "12 秒", "13 秒", "14 秒", "15 秒", "30 秒",
"11 秒", "12 秒", "13 秒", "14 秒", "15 秒", "30 秒", "45 秒", "60 秒",
];
export const OMNI_IMAGE_COUNTS = ["1 张", "2 张", "4 张", "8 张"];
@@ -70,11 +70,21 @@ function catalogModelLabels(
return unique.length ? unique : fallback;
}
function durationLabelsForModel(config: ModelConfig | undefined, isVideo: boolean): string[] {
function canCreateSegmentedVideo(config: ModelConfig | undefined, model: string): boolean {
// 31–60 秒不是单次 API 时长,而是平台会自动拆成 <=30 秒的两段。
// 只有 Seedance 2.5(或目录里声明了 30 秒能力的模型)可选这个总时长。
return modelDurations(config).some((seconds) => seconds >= 30)
|| /seedance\s*2\.5/i.test(model || "");
}
function durationLabelsForModel(config: ModelConfig | undefined, model: string, isVideo: boolean): string[] {
if (!isVideo) return [...OMNI_IMAGE_COUNTS];
const seconds = modelDurations(config);
if (!seconds.length) return [...OMNI_VIDEO_DURATIONS];
return ["智能时长", ...seconds.map((n) => `${n}`)];
const segmented = canCreateSegmentedVideo(config, model) ? [45, 60] : [];
return ["智能时长", ...seconds, ...segmented]
.filter((seconds, index, values) => values.indexOf(seconds) === index)
.map((seconds) => typeof seconds === "number" ? `${seconds}` : seconds);
}
export function OmniParamBar({
@@ -120,7 +130,7 @@ export function OmniParamBar({
);
const allowedRes = isVideo ? modelResolutions(selected) : [];
const resolutions = withCurrent(allowedRes.length ? allowedRes : OMNI_RESOLUTIONS, resolution);
const durations = withCurrent(durationLabelsForModel(selected, isVideo), duration);
const durations = withCurrent(durationLabelsForModel(selected, model, isVideo), duration);
useEffect(() => {
setCustomOn(isVideo ? duration !== "智能时长" : true);
@@ -173,12 +183,15 @@ export function OmniParamBar({
if (nextRes.length && resolution && !nextRes.includes(resolution)) {
onResolution(nextRes.includes("720p") ? "720p" : nextRes[0]);
}
const nextDur = durationLabelsForModel(selected, true);
if (duration && duration !== "智能时长" && !nextDur.includes(duration)) {
const nextDur = durationLabelsForModel(selected, model, true);
const seconds = Number(String(duration || "").replace(/\D/g, ""));
const isPlannedSegmentedDuration = seconds > 30 && seconds <= 60 && canCreateSegmentedVideo(selected, model);
// 60 秒是总时长,生成时会拆段;不要因为单段目录最高 30 秒就把它偷偷改回 8 秒/智能时长。
if (duration && duration !== "智能时长" && !nextDur.includes(duration) && !isPlannedSegmentedDuration) {
onDuration(nextDur.includes("8 秒") ? "8 秒" : (nextDur.find((x) => x !== "智能时长") || "智能时长"));
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selected?.id, isVideo]);
}, [selected?.id, isVideo, model]);
return (
<>