6.8 KiB
拼图与抓大鹅结果页音乐入口 2026-05-11
1. 范围
本方案把 VectorEngine 音频生成能力从视觉小说结果页扩展到拼图与抓大鹅结果页:
- 拼图结果页新增
音乐Tab,支持通过 Suno 生成作品背景音乐。 - 抓大鹅结果页在
素材配置 > 背景音乐中支持通过 Suno 生成作品背景音乐;旧一级音乐Tab 已删除。 - 抓大鹅
素材配置 > 物品支持为每个生成物体通过 Vidu 生成点击音效。 - 拼图运行态与抓大鹅运行态内置默认关卡音频配置:通用点击音效
/audio/ui-click-soft.wav、过关音效/audio/ui-level-clear.wav、倒计时临界音效/audio/ui-countdown-warning.wav。 - 拼图和抓大鹅草稿生成阶段会自动生成背景音乐并转存 OSS,结果页继续支持试听和重新生成。
本轮不新增 SpacetimeDB 表,不修改表字段,不把供应商密钥下发到前端。
2. 通用音频接口
后端在既有视觉小说音频路由外新增通用创作音频路由:
| 方法 | 路由 | 用途 |
|---|---|---|
POST |
/api/creation/audio/background-music |
提交 Suno 背景音乐任务 |
POST |
/api/creation/audio/background-music/{task_id}/asset |
查询并转存 Suno 音频资产 |
POST |
/api/creation/audio/sound-effect |
提交 Vidu 音效任务 |
POST |
/api/creation/audio/sound-effect/{task_id}/asset |
查询并转存 Vidu 音效资产 |
通用转存请求由前端传入 entityKind、entityId、slot、assetKind、profileId。后端仍负责:
- 校验 VectorEngine 与 OSS 环境变量。
- 轮询供应商任务结果。
- 下载音频字节。
- 写入 OSS 私有对象。
- 确认
asset_object并绑定asset_entity_binding。 - 音频真正可下载并准备转存时,按
taskId + assetKind + entityId + slot幂等扣除10光点;任务仍在处理中不扣费,转存或资产绑定失败自动退款。
通用背景音乐提交允许 prompt = ""。拼图和抓大鹅草稿生成都按纯音乐处理:后端提交 Suno 时固定带 make_instrumental = true,只用 title 和 tags 约束作品气质,不把歌词或规则描述写入 prompt。视觉小说原路由保持兼容,内部继续复用同一套提交、轮询、转存逻辑。
3. 数据落点
3.1 拼图
拼图作品没有独立作品级 metadata 字段。背景音乐随 levels_json 保存到首个 PuzzleDraftLevel.backgroundMusic:
{
"levelId": "puzzle-level-1",
"backgroundMusic": {
"taskId": "suno-task",
"provider": "vector-engine-suno",
"assetObjectId": "assetobj_1",
"assetKind": "puzzle_background_music",
"audioSrc": "/generated-puzzle-assets/..."
}
}
草稿生成阶段在生成首关作品题目后,使用作品题目作为 Suno title,prompt 为空,tags 使用轻快、拼图、循环、instrumental。生成失败只记录 warning,不阻断草稿进入结果页。运行态从 PuzzleRuntimeLevelSnapshot.backgroundMusic.audioSrc 读取该字段作为背景音乐源,游戏开始后自动循环播放;若字段为空,保持静默背景音乐兜底。
3.2 抓大鹅
抓大鹅作品级音频与物体点击音效复用 generated_item_assets_json 数组保存,不新增表字段:
- 作品背景音乐暂存到第一个
Match3DGeneratedItemAsset.backgroundMusic,表示当前 work profile 的作品级背景音乐。 - 单个物体点击音效保存到对应
Match3DGeneratedItemAsset.clickSound。
这是一个兼容性折中:当前 Match3D work profile 没有 work-level metadata 字段,而 generated_item_assets_json 已经随作品详情、草稿架、运行态入口稳定传递。草稿生成阶段的文本计划在生成物品名称时同步生成 backgroundMusic.title 作为背景音乐名称,backgroundMusic.prompt 固定为空字符串,后端用该名称作为 Suno title 并生成纯音乐。后续若新增正式作品 metadata 表达,应迁移 backgroundMusic 到作品级字段。
4. 前端交互
结果页 UI 保持轻量:
音乐Tab 只展示必要输入、生成按钮、状态与音频预览,不展示供应商规则说明。- 生成完成后立即写回本地草稿状态,并触发既有保存链路或专用保存接口。
- 抓大鹅每个物体音效生成入口放在对应素材详情面板内,不在列表下方展开大段配置。
- 抓大鹅物体音效提示词允许在素材详情面板内编辑;背景音乐只允许在
素材配置 > 背景音乐编辑曲名和风格,生成请求固定使用空prompt。 - 背景音乐和物体音效生成期间都显示进度条,生成完成后展示 audio 控件试听。
- 背景音乐重新生成只要求曲名非空;重新生成继续按纯音乐提交,
prompt = ""。
4.1 运行态默认点击音效
src/services/runtimeAudioFeedback.ts提供通用关卡音频配置DEFAULT_RUNTIME_LEVEL_AUDIO_CONFIG,内部缓存HTMLAudioElement,失败时静默兜底,不阻塞玩法交互。- 拼图点击、按压或拖拽拼块时播放默认通用点击音效,并继续保留既有触觉反馈。
- 抓大鹅点击物体时优先播放该物体绑定的
clickSound.audioSrc;若作品没有生成物体点击音效,则回退播放/audio/ui-click-soft.wav。 - 拼图关卡
currentLevel.status首次进入cleared时播放默认过关音效;抓大鹅 runstatus首次进入won时播放默认过关音效。 - 拼图使用
displayRemainingMs,抓大鹅使用timeLeftMs。当剩余时间进入默认阈值5_000ms后,每个自然秒桶最多播放一次倒计时音效,归零后停止。 - 默认关卡音效跟随现有
musicVolume设置,不新增独立音量 UI,不在运行态界面增加说明文案。 - 拼图和抓大鹅运行态背景音乐同样跟随
musicVolume,读取 generated legacy path 时先换签,再交给隐藏<audio loop preload="auto">自动播放;浏览器拒绝自动播放时静默失败,不阻断游戏交互。
5. 验收
建议执行:
npm run check:encoding
npm run test -- src\components\puzzle-result\PuzzleResultView.test.tsx
npm run test -- src\components\match3d-result\Match3DResultView.test.tsx
npm run typecheck
cargo test -p shared-contracts creation_audio --manifest-path server-rs\Cargo.toml
cargo test -p shared-contracts puzzle --manifest-path server-rs\Cargo.toml
cargo test -p shared-contracts match3d --manifest-path server-rs\Cargo.toml
cargo test -p api-server vector_engine_audio_generation --manifest-path server-rs\Cargo.toml
cargo test -p api-server match3d --manifest-path server-rs\Cargo.toml
cargo check -p api-server --manifest-path server-rs\Cargo.toml
真实生成 smoke 需要本地私密环境配置 VECTOR_ENGINE_BASE_URL、VECTOR_ENGINE_API_KEY 与 OSS 变量。后端改动后使用 npm run api-server 启动,并确认 /healthz。