音频音量接口
window.qqqAudio — 统一音频音量管理。一切 goods 的音效必须经此模块获取音量。
API
// 注册 goods 音量策略(gaea-host 自动调用)
window.qqqAudio.register(goodsId, def)
// 注销(gaea-host remove 时自动调用)
window.qqqAudio.unregister(goodsId)
// 获取主路音量 0.0–1.0(IDE 窗口 + goods 默认共用)
window.qqqAudio.getMainVolume()
// 获取 goods 音量 0.0–1.0(自动判断主路/旁路)
window.qqqAudio.getVolume(goodsId)
// 是否独立音量模式
window.qqqAudio.isIndependent(goodsId)
两种模式
'ide'(默认)— 跟随 IDE 音量滑块
// goods 注册时声明
audio: { mode: 'ide' }
getVolume(id) 返回 qqqSettings.get('audio.volume') / 100(出厂默认 25%)。
滑块拉到 50% → 返回 0.5。滑块拉到 100% → 返回 1.0。
'independent' — goods 自有音量
audio: { mode: 'independent' }
getVolume(id) 始终返回 1.0。IDE 滑块不影响此 goods。
goods 可通过自己的 state store 存储独立音量值。目前尚无旁路实例,仅为协议预留。
统一音频机器(2026-08-06)
一切音效的播放统一走主进程 AudioEngine(miniaudio AudioHub,24 并发 SFX 池 + 解码缓存 + 静音修剪 + 休眠自愈):
window.qqqideBridge.audio.play(file, { volume }) // 播放
window.qqqideBridge.audio.stop(scope?) // 停止。'music'/'clipboard'/默认 all
window.qqqideBridge.audio.isAlive() // 引擎存活 → boolean
window.qqqideBridge.audio.invoke(action, params) // 透传引擎动作(play_music/play_radio 等)
// file 路径解析:
// 'yz:<name>' → webapp/assets/yz/ (Roam 音效语义)
// 'assets/<rel>' → webapp/<file> (载荷静态资源)
// 绝对路径 → 原样使用
IDE 自带音效(升级/里程碑/子弹)与 goods 音效全部经此机器播放,音量 = 主路拉杆 × 固定系数(升级 0.55 / 里程碑 0.65 / 子弹 1.0)。
iframe goods 音效接入协议(qqq-sfx)
iframe 型 goods(如 Roam)不直接调 bridge.audio,而是向父窗口发 postMessage,由父窗口统一去重 + 语义映射后播放:
// iframe 内部(q2-roam.js `_playSfx` 同款)
parent.postMessage({ type: 'qqq-sfx', name: 'enter' }, '*');
父窗口接收端(core/shell-rpc.js):
qqq-sfx 消息 → 300ms 去重窗口(key = sfx_<name>)→ 语义映射表 → bridge.audio.play('yz:' + file)
设置面板
齿轮 → 设置 → 「音量」拉杆。
- 类型:刻度拉杆(
slider-stepped) - 节点:0% / 25% / 50% / 75% / 100%
- 默认:25%
- 持久化:
qgs.simple('qqq.settings')keyaudio.volume - 点击轨道任意位置 → 自动吸附最近刻度
使用示例
// goods 内部播放音效(尊重 IDE 音量偏好,走统一音频机器)
function playSound(src) {
var vol = window.qqqAudio.getVolume('my-goods');
window.qqqideBridge.audio.play(src, { volume: vol }).catch(function () {});
}