audio-api

文档发表:2026-07-02 · 阅读:121 · 更新:2026-08-18

音频音量接口

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') key audio.volume
  • 点击轨道任意位置 → 自动吸附最近刻度

使用示例

// goods 内部播放音效(尊重 IDE 音量偏好,走统一音频机器)
function playSound(src) {
  var vol = window.qqqAudio.getVolume('my-goods');
  window.qqqideBridge.audio.play(src, { volume: vol }).catch(function () {});
}