Multimedia

<video> and <audio> play media natively, with no plugin. Give them a src, or several <source> children the browser tries in order, skipping any whose type it cannot play. Anything else inside the element is fallback content, shown only by browsers that do not know the element at all.

Both accept controls, autoplay, muted, loop, crossorigin and preload (none, metadata or auto); <video> adds width, height, poster (shown before playback) and playsinline (no forced fullscreen on iPhone). Browsers block audible autoplay until the user interacts with the site, so a background video must be autoplay muted loop playsinline. Chromium-only controlslist="nodownload" trims the built-in controls.

<track> attaches timed text in the WebVTT format: kind is subtitles (translation), captions (dialogue plus sounds, for deaf viewers), descriptions, chapters or metadata; srclang and label feed the captions menu; and default turns one track on.

A video with format fallbacks, a poster and captionsHTML
<!doctype html>
<html lang="en">
  <meta charset="utf-8">
  <base href="https://cdn.jsdelivr.net/gh/mdn/learning-area@main/html/multimedia-and-embedding/">
  <video controls muted playsinline preload="metadata" width="280" height="280"
         poster="video-and-audio-content/poster.png">
    <source src="video-and-audio-content/rabbit320.webm" type="video/webm">
    <source src="video-and-audio-content/rabbit320.mp4" type="video/mp4">
    <track kind="captions" src="rabbit.en.vtt" srclang="en" label="English" default>
    <p>Your browser cannot play this video.
       <a href="video-and-audio-content/rabbit320.mp4">Download the MP4</a>.</p>
  </video>
Browser output of Listing 2.21
Browser output of 21

The capture shows the poster and Chrome 1 's native controls; preload="metadata" asks only for the duration and dimensions until the user presses play. The captions file is plain text served as text/vtt: a WEBVTT line, then blank-line separated cues such as 00:00:03.500 --> 00:00:07.000 followed by the caption text. A cross-origin track loads only with crossorigin on the media element and an Access-Control-Allow-Origin header on the response.

Which codecs play where

A file format (container) such as MP4 or WebM wraps separately compressed video and audio streams (codecs). Put the most efficient combination first and a universal one last, and add a codecs parameter so the browser can skip a source without downloading it: type='video/webm; codecs="av01.0.05M.08, opus"'.

Video and audio codec support, September 2026
Codec (container) Chrome, Edge Firefox 555 Safari 10 Use it for
H.264 + AAC (MP4) Yes Yes Yes Universal fallback
VP9 + Opus (WebM) Yes Yes 16+ (iOS 17.4+) Good compression, royalty-free
AV1 (MP4, WebM) Chrome 70+, Edge 121+ 67+ 17+ with hardware decoder only Smallest files, royalty-free
HEVC / H.265 (MP4) Hardware-dependent Hardware-dependent (137+) Yes Apple-centric, HDR
Ogg Theora (Ogg) Removed Removed No Nothing: re-encode old files
MP3, AAC, FLAC (audio) Yes Yes Yes Music and podcasts
Opus (WebM, Ogg) Yes Yes macOS 15.4+, iOS 18.4+ Speech, low bitrates
Encoding web-ready video with FFmpeg
# H.264 + AAC fallback, index moved to the start for fast playback
ffmpeg -i master.mov -c:v libx264 -crf 23 -preset slow -c:a aac -b:a 128k \
  -movflags +faststart clip.mp4
# AV1 + Opus in WebM (SVT-AV1 encoder)
ffmpeg -i master.mov -c:v libsvtav1 -crf 35 -c:a libopus -b:a 96k clip.webm
Embedding other content and third-party players

<embed src="guide.pdf" type="application/pdf"> and <object data="guide.pdf">fallback link</object> hand a file to the browser's built-in viewer; only <object> can hold fallback content. Both were built for plugins such as Flash, which Adobe stopped supporting on December 31, 2020. For YouTube 9 , use its <iframe> embed (<iframe>), or lite-youtube-embed 6,349 (github.com/paulirish/lite-youtube-embed (https://github.com/paulirish/lite-youtube-embed 6,349 ), Apache-2.0), which loads the player only on click. Adaptive streaming (HLS, DASH) switches quality with the network: Safari and Chrome 142+ play HLS natively, and hls.js 16,957 or dash.js 5,548 add it elsewhere via Media Source Extensions (Media Source Extensions). Scripting playback is covered in Playing Audio and Video.