Skip to content

Audio

Related reference: Scene API / Audio

The current advanced Web API mainly provides control over audio objects that already exist in the scene.

In other words, audio is usually configured in the scene editor first, and then the host page uses advanced APIs to:

  • get audio objects
  • play, pause, stop, and replay them
  • read duration, playback position, and loop state
  • seek to a given time
  • listen for playback-related events

Get an Audio Object

There is currently no runtime audio-creation API such as createAudio(). If needed, the host page can still create and control its own native Audio element separately.

The most common way to fetch scene audio is by object name:

js
const audio = await api.getObject('scene-bgm');

If it returns null, that usually means:

  • there is no audio object with that name in the scene
  • the object is not yet readable
  • the name is incorrect

So a safer time to query is usually after loadSceneEnd or sceneStart:

js
iframe.addEventListener('loadSceneEnd', async () => {
  const audio = await api.getObject('scene-bgm');
  console.log(audio);
});

Playback Control

Play

js
await api.playAudio(audio, {
  loop: false,
});

If needed, you can also control looping through options.loop.

Pause, Stop, and Replay

js
await api.pauseAudio(audio);
await api.stopAudio(audio);
await api.playbackAudio(audio, { loop: false });

Their typical differences are:

  • pauseAudio(): pause at the current position
  • stopAudio(): stop and jump back to the beginning
  • playbackAudio(): restart from the beginning

Read Playback State

js
const duration = await api.getAudioDuration(audio);
const paused = await api.getAudioPaused(audio);
const currentTime = await api.getAudioCurrentTime(audio);
const loop = await api.getAudioLoop(audio);

Common uses:

  • switch the host-layer play button icon based on paused
  • show simple progress based on currentTime and duration
  • decide whether loop mode is active based on loop

Seek and Configure Looping

js
await api.setAudioCurrentTime(audio, 12.5);
await api.setAudioLoop(audio, true);

Useful when:

  • a custom host-layer progress bar should seek to a specific position
  • background music should switch between looping and non-looping
  • you need interactions such as "preview a short excerpt" or "replay a specific segment"

Playback Events

Audio objects support media events similar to video:

  • play - fires when playback starts
  • pause - fires when playback pauses
  • ended - fires when playback finishes naturally

Example:

js
function onPlay(event) {
  // https://developer.mozilla.org/en-US/docs/Web/API/Event
}

function onPause(event) {
  // https://developer.mozilla.org/en-US/docs/Web/API/Event
}

function onEnded(event) {
  // https://developer.mozilla.org/en-US/docs/Web/API/Event
}

await api.on('play', onPlay, audio);
await api.on('pause', onPause, audio);
await api.on('ended', onEnded, audio);

Background Music

A common pattern is:

  1. place a background music object in the scene editor
  2. fetch it from the host page with getObject()
  3. call playAudio() after the user clicks "Start Now" or another host-layer button
  4. control pauseAudio() / playbackAudio() with host-layer buttons

Scene Sound Effects

Useful for:

  • playing a prompt sound after a key interaction
  • pairing sound with object clicks, animation completion, or recognition success
  • letting the host layer control mute or replay behavior

Notes

No Runtime Creation API

Current audio support is mainly designed for controlling existing scene audio objects, not creating new audio dynamically from the host page.

Audio Is Not a 3D Object

Audio is not a normal 3D object, so it cannot participate in hierarchy operations such as addChild() the way models, images, and videos do.

Autoplay Is Still Limited by Browsers

Even though the plugin includes some compatibility handling, audio playback is still affected by browser autoplay policy. Pay special attention to:

  • after force-hiding the "Start Now Button", playback is more likely to be blocked
  • restrictions are stricter on iOS and in some in-app WebViews
  • playback is less reliable if it is not triggered by a user gesture

So if your project depends on background music or important audio prompts, it is usually best to:

  1. keep the default start flow, or
  2. provide a clear user-click entry in the host layer before starting audio playback

Plan Object Names in Advance

If you plan to control audio from the host page, give audio objects stable and readable names in the scene editor, for example:

  • scene-bgm
  • button-click-sfx
  • result-voiceover

That makes later getObject() lookups much more reliable.