Audio and video
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>controlsshows the play, volume and fullscreen buttons. Without it, only a script can control the video.posteris 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
| Attribute | Effect |
|---|---|
controls | show the built-in player controls |
autoplay | start on load; browsers only allow it when the video is also muted |
muted | start with the sound off |
loop | start again from the beginning when it ends |
playsinline | on iPhones, play inside the page instead of going fullscreen |
preload="none" | download nothing until play is pressed |
width, height | the 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.