diff --git a/docs/【编辑器】画板音乐生成入口设计-2026-06-18.md b/docs/【编辑器】画板音乐生成入口设计-2026-06-18.md index 5aa0221af..df513b2cc 100644 --- a/docs/【编辑器】画板音乐生成入口设计-2026-06-18.md +++ b/docs/【编辑器】画板音乐生成入口设计-2026-06-18.md @@ -22,7 +22,7 @@ - `prompt`:用户输入的音效提示词。前端与 BFF 对内仍使用 `prompt`,提交到 VectorEngine Vidu 时同时写入 `prompt` 与 `sound` 同值,兼容线上网关对 `sound` 字段的反序列化要求。 - `model`:固定默认 `audio1.0`,UI 以禁用态模型胶囊显示为 `Vidu`,位置紧贴生成按钮;暂不展示 Suno 文生音效模型入口。 -- `duration`:Vidu 音频时长,UI 以一个无标题参数按钮展示,选项范围 `2-10` 秒,默认 `5` 秒。 +- `duration`:Vidu 音频时长,UI 以一个无标题参数按钮展示当前秒数,点击后展开与视频时长一致的滑动条,范围 `2-10` 秒,步进 `1` 秒,默认 `5` 秒。 - 提交到 VectorEngine 时映射为 Vidu 文生音频字段:`model: "audio1.0"`、`prompt`、`sound: prompt`、`duration`、可选 `seed`。当前编辑器音效固定使用 Vidu `audio1.0`,不再走 Suno `task: "sound"` / `metadata_params` 文生音效契约。 ### 生成游戏背景音乐 @@ -119,7 +119,7 @@ POST /api/editor/audios/background-music/generations - 底部工具栏显示 `生成音乐`。 - 点击 `生成音乐` 只出现选项框,不立刻创建占位。 - 点击 `生成游戏音效` 后出现音效面板,文本字段为 `prompt`;底部左侧只有一个无标题时长参数按钮,右侧为固定 `Vidu` 模型胶囊和生成按钮。 -- 音效时长只提供 `2-10` 秒选项,默认 `5` 秒,提交到 BFF 的字段为 `duration`。 +- 音效时长使用滑动条选择 `2-10` 秒,步进 `1` 秒,默认 `5` 秒,提交到 BFF 的字段为 `duration`。 - 音效面板模型显示 `Vidu`,提交 `model: "audio1.0"`;后端转发到 Vidu 时同时携带 `prompt` 和 `sound`;不显示 Suno 文生音效模型或 Suno 音效入口。 - 点击 `生成游戏背景音乐` 后出现背景音乐面板,字段为 `gpt_description_prompt`,右侧固定显示 `Suno` 模型胶囊,不展示 `make_instrumental`。 - 音效提交到 `/api/editor/audios/sound-effects/generations`,背景音乐提交到 `/api/editor/audios/background-music/generations`。 diff --git a/src/components/image-editor/ImageCanvasGenerationComposerView.test.tsx b/src/components/image-editor/ImageCanvasGenerationComposerView.test.tsx index 196c3100c..a7e94a4fc 100644 --- a/src/components/image-editor/ImageCanvasGenerationComposerView.test.tsx +++ b/src/components/image-editor/ImageCanvasGenerationComposerView.test.tsx @@ -631,14 +631,18 @@ describe('ImageCanvasGenerationComposerView', () => { within(panel).getByRole('button', { name: '音效时长 5秒' }), ); const optionPanel = screen.getByRole('menu', { name: '音效时长选项' }); + const durationSlider = within(optionPanel).getByRole('slider', { + name: '音效时长', + }) as HTMLInputElement; + expect(durationSlider.min).toBe('2'); + expect(durationSlider.max).toBe('10'); + expect(durationSlider.step).toBe('1'); + expect(durationSlider.value).toBe('5'); expect( - within(optionPanel).getByRole('button', { name: '时长 2秒' }), - ).toBeTruthy(); - expect( - within(optionPanel).getByRole('button', { name: '时长 10秒' }), - ).toBeTruthy(); + within(optionPanel).queryByRole('button', { name: '时长 2秒' }), + ).toBeNull(); expect(within(optionPanel).queryByText(/BPM/u)).toBeNull(); - fireEvent.click(within(optionPanel).getByRole('button', { name: '时长 8秒' })); + fireEvent.change(durationSlider, { target: { value: '8' } }); expect(screen.getByLabelText('当前音效时长').textContent).toBe('8'); expect( diff --git a/src/components/image-editor/ImageCanvasGenerationComposerView.tsx b/src/components/image-editor/ImageCanvasGenerationComposerView.tsx index 7d1d35ca4..f03ef5f02 100644 --- a/src/components/image-editor/ImageCanvasGenerationComposerView.tsx +++ b/src/components/image-editor/ImageCanvasGenerationComposerView.tsx @@ -47,7 +47,6 @@ import { DEFAULT_VIDEO_WEB_SEARCH_ENABLED, EDITOR_VIDEO_ASPECT_RATIO_OPTIONS, EDITOR_SOUND_EFFECT_MODEL_OPTIONS, - SOUND_EFFECT_DURATION_OPTIONS, EDITOR_VIDEO_MODEL_OPTIONS, EDITOR_VIDEO_RESOLUTION_OPTIONS, VIDEO_MODEL_SEEDANCE_2_FAST, @@ -817,18 +816,27 @@ function ImageCanvasAudioGenerationComposerView({ 'above', )} > -