Photo by Steve Harvey on Unsplash

Audio on the Web, for Games and VR!

Tips, tricks and getting started.

Tip 1. Don’t use MP3 for Looping Audio

<audio loop preload id="bgsound">
<source src="assets/ambient/loop.ogg" type="audio/ogg" />
<source src="assets/ambient/loop.mp3" type="audio/mpeg" />
</audio>

Tip 2. Don’t use auto-playing audio; have the user turn audio on.

A poll by Jo on Twitter asking how a scene should handle audio
Toggle Button
<input type="checkbox" id="canaudio" /><label for="canaudio">Toggle Audio</label>
#canaudio {
opacity: 0;
position: absolute;
top: 0;
left: 0;
width: 0;
height: 0;
pointer-events: none;
}
label[for="canaudio"] {
position: fixed;
bottom: 1.5rem;
right: 1.5rem;
background: #0004;
padding: 1.5rem;
border-radius: 50%;
border: 2px solid transparent;
width: 3rem;
height: 3rem;
text-align: center;
font-size: 0;
color: white;
}
#canaudio:focus + label[for="canaudio"] {
border: 2px solid white;
}
label[for="canaudio"]::before {
content: "🔇\FE0E";
font-size: 3rem;
line-height: 3rem;
}
#canaudio:checked + label[for="canaudio"]::before {
content: "🔊\FE0E";
}
// Ensure the #canaudio element is not checked as some browsers
// Will remember it's state
window.canaudio.checked = false;
window.canaudio.addEventListener('change', function () {
if (this.checked) {
window.bgsound.play();
// initialise the spatial audio
audioInit();
} else {
window.bgsound.pause();
}
});

Tip 3. Spatial Audio in the Web isn’t as hard to add as you’d expect

<script src="https://cdn.jsdelivr.net/npm/resonance-audio/build/resonance-audio.min.js"></script>
let hasInit = false;function audioInit() {  if (hasInit) return;
hasInit = true;
// Create an AudioContext
const audioContext = new AudioContext();
const resonanceAudioScene = new ResonanceAudio(audioContext);
resonanceAudioScene.output.connect(audioContext.destination);
}
const roomDimensions = {
width: 3.1,
height: 2.5,
depth: 3.4,
};
const roomMaterials = {
left: 'brick-bare',
right: 'curtain-heavy',
front: 'marble',
back: 'glass-thin',
// Room floor
down: 'grass',
// Room ceiling
up: 'transparent',
};
resonanceAudioScene.setRoomProperties(roomDimensions, roomMaterials);
const tempForwardVector = new Vector3();
const tempUpVector = new Vector3();
function onRender() {
tempForwardVector.set(0, 0, -1);
tempForwardVector.applyQuaternion(camera.quaternion);
tempUpVector.set(0, 1, 0);
tempUpVector.applyQuaternion(camera.quaternion);
resonanceAudioScene.setListenerOrientation(
tempForwardVector.x,
tempForwardVector.y,
tempForwardVector.z,
tempUpVector.x,
tempUpVector.y,
tempUpVector.z
);
resonanceAudioScene.setListenerPosition(
camera.position.x,
camera.position.y,
camera.position.z
);
};
const audioElement = document.createElement("audio");
audioElement.src = filename;
const audioElementSource = audioContext.createMediaElementSource(
audioElement
);
const source = resonanceAudioScene.createSource();
audioElementSource.connect(source.input);
source.setPosition(position.x, position.y, position.z);
audioElement.play();

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Ada Rose Cannon

Co-chair of the W3C Immersive Web Working Group, Developer Advocate for Samsung.