v0.1首个正式支持的版本化规范查看版本范围

管理媒体采集与播放

媒体能力的核心不是一串字节,而是用户授权后产生、可随时撤销的设备句柄。

{
  "apiVersion": "0.1",
  "canvases": { "preview": { "mode": "pixels" } },
  "capabilities": [
    "host:capture.requestCamera",
    "host:capture.requestMic",
    "host:canvas.present",
    "host:playback.open"
  ],
  "events": ["capture.ended", "playback.ready", "playback.ended"],
  "apiLimits": {}
}

读取、写入和停止方法都由已取得的媒体句柄授权,不出现在 capability 列表。

1. 在用户操作中申请

let cameraStream;

startButton.onclick = async () => {
  cameraStream = await host.capture.requestCamera({
    facing: 'user', maxWidth: 1280, maxHeight: 720,
  });
  if (cameraStream) startPreview(cameraStream);
};

用户取消返回 null。不要在定时器或页面启动时自动申请。

2. 读取与背压

async function readOneFrame(stream, afterSequence) {
  const bytes = framePool.acquire(stream.frameBytes);
  const frame = await host.capture.frame(stream.camera, bytes, afterSequence);
  return { bytes: bytes.subarray(0, frame.written), frame };
}

复用缓冲;frame() 自己异步等待更新的 sequence,不需要另一个可读事件。不要并发读取同一句柄。

3. 预览或处理

将摄像头帧处理后交给 canvas.present()

const { bytes, frame } = await readOneFrame(cameraStream);
applyEffect(bytes, frame);
await host.canvas.present('preview', bytes, {
  ...frame,
  format: 'rgba8',
});

句柄不穿过 asset/file token;只有已校验字节进入应用处理路径。

4. 播放 guest 产生的音频

const output = await host.playback.open({ channels: 1, latency: 'interactive' });
host.events.on('playback.ready', ({ writableFrames }) => {
  host.playback.write(output.output, synth.renderBytes(writableFrames));
});

capture.readAudio()playback.write() 可以组合,但回声消除、混音和重采样属于 guest 库。

5. 撤销与清理

host.events.on('capture.ended', ({ handle }) => detach(handle));
await host.capture.stop(cameraStream.camera);
await host.playback.stop(output.output, 'immediate');

事件送达后句柄已失效。只清理本地状态,不要对失效句柄循环重试。

相关参考

captureplaybackcanvas.present()

Host API 版本与分层概览Host API v0.1版本非正式提议提议canvas API呈现canvas.getInfo()方法canvas.draw()方法canvas.present()方法canvas.measureText()方法canvas.frame event事件canvas.resize event事件asset API呈现asset.read()方法asset.loadFont()方法playback API呈现playback.open()方法playback.write()方法playback.stop()方法playback.ready event事件playback.ended event事件input API输入input.focus()方法input.pointer event事件input.key event事件input.wheel event事件input.focusChange event事件ime API输入ime.openSession()方法ime.updateState()方法ime.updateGeometry()方法ime.closeSession()方法ime.textUpdate event事件ime.composition event事件ime.formatUpdate event事件ime.characterBoundsRequest event事件ime.ended event事件capture API输入capture.requestCamera()方法capture.requestMic()方法capture.frame()方法capture.readAudio()方法capture.stop()方法capture.ended event事件store API数据store.get()方法store.put()方法store.delete()方法store.list()方法store.deletePrefix()方法clipboard API数据clipboard.readText()方法clipboard.writeText()方法env API平台集成env.snapshot()方法env.change event事件开始调用 Host API指南构建交互式绘图应用指南构建自绘文本编辑器指南管理媒体采集与播放指南组织本地数据与同步指南