fix(canvas): 视频设置 - 按渠道能力隐藏尺寸并联动分辨率宽高

This commit is contained in:
ddCat
2026-08-29 11:05:59 +08:00
parent 6d77c250c1
commit 4b75504f75
15 changed files with 196 additions and 50 deletions

View File

@@ -151,6 +151,31 @@ describe("逻辑模型选择", () => {
expect(defaults.size).toBe("16:9");
});
test("不支持画幅的视频模型不会继续提交旧的全局尺寸", () => {
const model = "autodl-channel::minimax_h3_lightx2v_no_pic";
const profile = defaultModelCapabilityConfig("autodl-comfyui", "minimax_h3_lightx2v_no_pic");
profile.video!.ratios = [];
profile.video!.defaultRatio = "";
profile.video!.resolutions = ["480p竖", "480p横"];
profile.video!.defaultResolution = "480p竖";
const config: AiConfig = {
...defaultConfig,
size: "16:9",
vquality: "720",
channels: [{ id: "autodl-channel", name: "AutoDL", baseUrl: "https://autodl.art", apiKey: "system", apiFormat: "openai", scope: "system", models: ["minimax_h3_lightx2v_no_pic"], modelCosts: [{ model: "minimax_h3_lightx2v_no_pic", capability: "video", protocol: "autodl-comfyui", billingMode: "fixed_request", unitPriceMicrocredits: 1, capabilityConfig: profile }] }],
models: [model],
videoModels: [model],
videoModel: model,
model,
};
const videoNode = { ...node("video", CanvasNodeType.Video), metadata: { model, generationMode: "video" as const } };
const generationConfig = buildGenerationConfig(config, videoNode, "video");
expect(generationConfig.size).toBe("");
expect(generationConfig.vquality).toBe("480p竖");
});
test("后台标注的视频模型不因内部标识缺少视频关键词而回退", () => {
const config = policyConfig();
const selectedModel = config.videoModels[0]!;

View File

@@ -8,7 +8,7 @@ import { CanvasVideoSettingsPopover } from "../src/components/canvas/canvas-vide
import { VideoSettingsPanel } from "../src/components/video-settings-panel";
import { canvasThemes } from "../src/lib/canvas-theme";
import { mergeFetchedChannelModelCosts, type ChannelModelCatalogItem } from "../src/lib/channel-model-catalog";
import { defaultModelCapabilityConfig } from "../src/lib/model-capabilities";
import { defaultModelCapabilityConfig, pluginWorkflowCapabilityConfig } from "../src/lib/model-capabilities";
import { ChannelModelSettings } from "../src/pages/settings/channel-video-pricing";
import { fetchChannelModels } from "../src/services/api/image";
import { createVideoGenerationTask } from "../src/services/api/video";
@@ -62,6 +62,27 @@ function formEntries(body: unknown) {
}
describe("public channel model catalog", () => {
test("projects Manifest video workflow parameters without inventing a size capability", () => {
const profile = pluginWorkflowCapabilityConfig("autodl-comfyui", {
id: "minimax_h3_lightx2v_no_pic",
label: "MiniMax H3 文生视频",
providerId: "autodl-comfyui",
capability: "video",
parameters: [
{ name: "prompt", type: "string", required: true, mapping: "prompt" },
{ name: "duration", type: "integer", mapping: "duration" },
{ name: "resolution", type: "string", mapping: "resolution", values: ["480p竖", "480p横"] },
],
defaults: { duration: 5, resolution: "480p竖" },
})!.video!;
expect(profile.ratios).toEqual([]);
expect(profile.defaultRatio).toBe("");
expect(profile.resolutions).toEqual(["480p竖", "480p横"]);
expect(profile.defaultResolution).toBe("480p竖");
expect(profile.duration).toEqual({ selection: "enum", values: [5], default: 5 });
});
test("preserves six public capabilities without expanding compatibility IDs", async () => {
axios.post = (async () => ({
data: {
@@ -243,6 +264,35 @@ describe("public channel model catalog", () => {
expect(html).not.toContain("720P");
});
test("does not show size controls when the video capability declares no ratios", () => {
const config = configForCatalog([omniCatalog], { videoSeconds: "10", size: "16:9", vquality: "1080" });
const profile = config.channels[0]!.modelCosts![0]!.capabilityConfig!.video!;
profile.ratios = [];
profile.defaultRatio = "";
profile.resolutions = ["1080p"];
profile.defaultResolution = "1080p";
const summaryHtml = renderToStaticMarkup(React.createElement(CanvasVideoSettingsPopover, { config, onConfigChange: () => undefined }));
const panelHtml = renderToStaticMarkup(React.createElement(VideoSettingsPanel, { config, onConfigChange: () => undefined, theme: canvasThemes.dark }));
expect(summaryHtml).toContain("1080P · 10s");
expect(summaryHtml).not.toContain("16:9");
expect(panelHtml).not.toContain("尺寸");
});
test("shows dimensions derived from the selected video resolution and ratio", () => {
const config = configForCatalog([omniCatalog], { videoSeconds: "10", size: "16:9", vquality: "1080" });
const profile = config.channels[0]!.modelCosts![0]!.capabilityConfig!.video!;
profile.resolutions = ["720p", "1080p", "2160p"];
profile.defaultResolution = "720p";
const panelHtml = renderToStaticMarkup(React.createElement(VideoSettingsPanel, { config, onConfigChange: () => undefined, theme: canvasThemes.dark }));
expect(panelHtml).toContain("1920");
expect(panelHtml).toContain("1080");
expect(panelHtml).not.toContain("1280");
});
test("shows the public display name in channel model settings instead of only the internal ID", () => {
const config = configForCatalog([omniCatalog]);

View File

@@ -1,7 +1,7 @@
import { describe, expect, test } from "bun:test";
import { defaultModelCapabilityConfig } from "../src/lib/model-capabilities";
import { formatVideoResolutionLabel, normalizeVideoResolution, videoResolutionComparisonKey, VIDEO_RESOLUTION_CAPABILITY_OPTIONS, VIDEO_RESOLUTION_OPTIONS } from "../src/lib/video-generation-options";
import { formatVideoResolutionLabel, normalizeVideoResolution, videoDimensionsForRatioAndResolution, videoResolutionComparisonKey, VIDEO_RESOLUTION_CAPABILITY_OPTIONS, VIDEO_RESOLUTION_OPTIONS } from "../src/lib/video-generation-options";
describe("video generation resolution options", () => {
test("统一档位包含 1440P 与 4K,并识别常见别名", () => {
@@ -20,6 +20,15 @@ describe("video generation resolution options", () => {
expect(formatVideoResolutionLabel("768p竖")).toBe("768P竖");
});
test("根据当前比例和分辨率推导视频尺寸", () => {
expect(videoDimensionsForRatioAndResolution("16:9", "720p")).toEqual({ width: 1280, height: 720 });
expect(videoDimensionsForRatioAndResolution("16:9", "1080P")).toEqual({ width: 1920, height: 1080 });
expect(videoDimensionsForRatioAndResolution("16:9", "4K")).toEqual({ width: 3840, height: 2160 });
expect(videoDimensionsForRatioAndResolution("9:16", "1080p")).toEqual({ width: 1080, height: 1920 });
expect(videoDimensionsForRatioAndResolution("1:1", "1440p")).toEqual({ width: 1440, height: 1440 });
expect(videoDimensionsForRatioAndResolution("adaptive", "1080p")).toBeUndefined();
});
test("按协议限制实际可选档位", () => {
expect(defaultModelCapabilityConfig("newapi-channel-2").video?.resolutions).toEqual(["480p", "720p", "1080p", "1440p", "2160p"]);
expect(defaultModelCapabilityConfig("volcengine-ark-video").video?.resolutions).toEqual(["480p", "720p", "1080p"]);