<audio> and <video> (Multimedia) share HTMLMediaElement; new Audio(url) needs no markup. play() returns a promise that rejects with NotAllowedError when the autoplay policy blocks sound before any user interaction, or NotSupportedError when no source is playable.
| Kind | Most-used members |
|---|---|
| Methods | play(), pause(), load(), canPlayType(type) |
| Position | currentTime, duration, paused, ended, loop |
| Sound and speed | volume (0-1), muted, playbackRate |
| Loading | src, currentSrc, readyState, buffered (Timing Media Clips) |
| Events | loadedmetadata, playing, pause, timeupdate, ended, error |
<button id="toggle">Play</button><pre id="log"></pre>
<script type="module">
const audio = new Audio('alarm.mp3');
const button = document.querySelector('#toggle');
button.addEventListener('click', () => (audio.paused
? audio.play().catch((err) => { button.textContent = err.name; }) : audio.pause()));
audio.addEventListener('play', () => { button.textContent = 'Pause'; });
audio.addEventListener('pause', () => { button.textContent = 'Play'; });
document.querySelector('#log').textContent = ['audio/mpeg', 'audio/flac', 'video/x-flv']
.map((type) => `canPlayType('${type}'): "${audio.canPlayType(type)}"`).join('\n');
</script>
canPlayType() answers "probably", "maybe" or "". Update the UI from play and pause events, since media keys change state too. Autoplaying video must be muted. For per-frame work use requestVideoFrameCallback() (Baseline since October 2024); timeupdate fires only about 4 to 66 times a second.