From e3416768ab09cc1320077fb3e1e64103ef9964b5 Mon Sep 17 00:00:00 2001 From: ddCat Date: Mon, 27 Jul 2026 21:38:26 +0800 Subject: [PATCH] =?UTF-8?q?fix(canvas):=20=E8=A7=86=E9=A2=91=E7=94=9F?= =?UTF-8?q?=E6=88=90=20-=20Seedance=20=E8=A7=86=E9=A2=91=E8=AF=B7=E6=B1=82?= =?UTF-8?q?=E6=AD=A3=E7=A1=AE=E4=BC=A0=E9=80=92=E5=A3=B0=E9=9F=B3=E5=BC=80?= =?UTF-8?q?=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/internal/service/provider.go | 9 +++--- backend/internal/service/provider_test.go | 38 +++++++++++++++++++++-- web/src/services/api/video.ts | 1 + 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/backend/internal/service/provider.go b/backend/internal/service/provider.go index 44acf6074..3191eb950 100644 --- a/backend/internal/service/provider.go +++ b/backend/internal/service/provider.go @@ -1655,10 +1655,11 @@ func seedanceVideosBody(input canvasGenerationInput) (map[string]interface{}, er return nil, errors.New("Seedance 参考视频或参考音频需要同时连接至少 1 张主参考图") } body := map[string]interface{}{ - "model": input.Config.Model, - "prompt": seedanceVideosPromptText(input), - "aspect_ratio": normalizeSeedanceVideosRatio(input.Config.Size), - "duration": normalizeSeedanceVideosDuration(input.Config.VideoSeconds), + "model": input.Config.Model, + "prompt": seedanceVideosPromptText(input), + "aspect_ratio": normalizeSeedanceVideosRatio(input.Config.Size), + "duration": normalizeSeedanceVideosDuration(input.Config.VideoSeconds), + "generate_audio": parseBool(input.Config.VideoGenerateAudio, true), } imageURLs := make([]string, 0, len(input.ReferenceImages)) for _, image := range input.ReferenceImages { diff --git a/backend/internal/service/provider_test.go b/backend/internal/service/provider_test.go index 52a098fe7..29f7285f0 100644 --- a/backend/internal/service/provider_test.go +++ b/backend/internal/service/provider_test.go @@ -160,9 +160,10 @@ func TestSeedanceVideosBodyUsesVideosEndpointFields(t *testing.T) { body, err := seedanceVideosBody(canvasGenerationInput{ Prompt: "make it move", Config: providerConfig{ - Model: "seedance-2.0-mini-480p", - Size: "9:16", - VideoSeconds: "8", + Model: "seedance-2.0-mini-480p", + Size: "9:16", + VideoSeconds: "8", + VideoGenerateAudio: "true", }, ReferenceImages: []providerMedia{ {ID: "image-1", DataURL: testReferenceImageDataURL}, @@ -180,6 +181,9 @@ func TestSeedanceVideosBodyUsesVideosEndpointFields(t *testing.T) { if body["aspect_ratio"] != "9:16" || body["duration"] != 8 { t.Fatalf("size fields = %#v %#v", body["aspect_ratio"], body["duration"]) } + if body["generate_audio"] != true { + t.Fatalf("generate_audio = %#v, want true", body["generate_audio"]) + } if body["image_url"] != testReferenceImageDataURL { t.Fatalf("image_url = %#v", body["image_url"]) } @@ -200,6 +204,34 @@ func TestSeedanceVideosBodyUsesVideosEndpointFields(t *testing.T) { } } +func TestSeedanceVideosBodyHonorsGenerateAudio(t *testing.T) { + for _, test := range []struct { + name string + value string + want bool + }{ + {name: "default enabled", want: true}, + {name: "explicit enabled", value: "true", want: true}, + {name: "explicit disabled", value: "false", want: false}, + } { + t.Run(test.name, func(t *testing.T) { + body, err := seedanceVideosBody(canvasGenerationInput{ + Prompt: "make it move", + Config: providerConfig{ + Model: "seedance-2.0-mini-480p", + VideoGenerateAudio: test.value, + }, + }) + if err != nil { + t.Fatalf("seedanceVideosBody() error = %v", err) + } + if body["generate_audio"] != test.want { + t.Fatalf("generate_audio = %#v, want %v", body["generate_audio"], test.want) + } + }) + } +} + func TestSeedanceVideosBodyUsesOrderedFrameImageURLsWhenConfigured(t *testing.T) { body, err := seedanceVideosBody(canvasGenerationInput{ Prompt: "make it move", diff --git a/web/src/services/api/video.ts b/web/src/services/api/video.ts index e2a76470d..f9ec72ae1 100644 --- a/web/src/services/api/video.ts +++ b/web/src/services/api/video.ts @@ -225,6 +225,7 @@ async function buildSeedanceVideosPayload(config: AiConfig, model: string, promp prompt: buildSeedanceVideosPromptText(prompt, imageUrls.length, videoUrls.length, audioUrls.length), aspect_ratio: ratio === "adaptive" ? "16:9" : ratio, duration: duration < 4 ? 5 : duration, + generate_audio: boolConfig(config.videoGenerateAudio, true), ...(imageUrls[0] ? { image_url: imageUrls[0] } : {}), ...(imageUrls.length > 1 ? { reference_image_urls: imageUrls.slice(1) } : {}), ...(videoUrls.length ? { reference_videos: videoUrls } : {}),