CodeMIRAI
0 XP

Audio and video

2 min read 4 runnable examples Quiz included

Video

HTML
<video controls width="360" poster="https://picsum.photos/seed/flower/360/203">
  <source src="https://mdn.github.io/shared-assets/videos/flower.webm" type="video/webm">
  <source src="https://mdn.github.io/shared-assets/videos/flower.mp4" type="video/mp4">
  Your browser doesn't support video.
</video>
  • controls shows the play, volume and fullscreen buttons. Without it, only a script can control the video.
  • poster is the picture shown before playback starts.
  • Each <source> offers a different format, and the browser plays the first one it supports.
  • The text inside appears only in a browser that can't play video at all.

Useful attributes

AttributeEffect
controlsshow the built-in player controls
autoplaystart on load; browsers only allow it when the video is also muted
mutedstart with the sound off
loopstart again from the beginning when it ends
playsinlineon iPhones, play inside the page instead of going fullscreen
preload="none"download nothing until play is pressed
width, heightthe display size

A silent, looping background clip:

HTML
<video autoplay muted loop playsinline width="360">
  <source src="https://mdn.github.io/shared-assets/videos/flower.mp4" type="video/mp4">
</video>

Audio

HTML
<audio controls>
  <source src="https://mdn.github.io/shared-assets/audio/t-rex-roar.mp3" type="audio/mpeg">
  Your browser doesn't support audio.
</audio>

<audio> takes the same attributes as <video>, apart from the visual ones like poster and width.

Captions

Captions make a video usable for deaf and hard-of-hearing viewers, and for anyone watching with the sound off. Add a WebVTT file with <track>:

HTML
<video controls src="lesson.mp4">
  <track kind="captions" src="lesson.en.vtt" srclang="en" label="English" default>
</video>

A .vtt file is plain text with timings:

WebVTT captions
WEBVTT

00:00:00.000 --> 00:00:03.500
Welcome to the lesson.

00:00:03.500 --> 00:00:07.000
Today we're learning about video.

Controlling playback with JavaScript

HTML
<video id="clip" width="320" muted playsinline>
  <source src="https://mdn.github.io/shared-assets/videos/flower.mp4" type="video/mp4">
</video>
<p>
  <button data-do="play">Play</button>
  <button data-do="pause">Pause</button>
  <button data-do="restart">Restart</button>
  <button data-do="speed">Speed: 1×</button>
</p>
<script>
  const clip = document.querySelector("#clip");
  document.querySelectorAll("[data-do]").forEach((btn) => {
    btn.addEventListener("click", () => {
      const action = btn.dataset.do;
      if (action === "play") clip.play();
      if (action === "pause") clip.pause();
      if (action === "restart") clip.currentTime = 0;
      if (action === "speed") {
        clip.playbackRate = clip.playbackRate === 1 ? 2 : 1;
        btn.textContent = `Speed: ${clip.playbackRate}×`;
      }
    });
  });
  clip.addEventListener("ended", () => console.log("The video finished"));
</script>

Embedding YouTube and other players

Video sites give you an <iframe> snippet under Share → Embed:

HTML
<iframe width="560" height="315"
        src="https://www.youtube.com/embed/VIDEO_ID"
        title="YouTube video player"
        allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
        allowfullscreen></iframe>

It's shown here rather than run, because the preview box is sandboxed and video sites' players refuse to work inside it. Hosting video on such a service saves you bandwidth: video files are large, and they stream each viewer the right quality for their connection.

Finished this lesson?Mark it complete to earn +20 XP and move your progress on.