Start · Sprachen · JavaScript · Referenz · HTMLVideoElement

HTMLVideoElement

Schnittstelle

Repräsentiert ein <code>&lt;video&gt;</code>-Element und erweitert <code>HTMLMediaElement</code> um videospezifische Eigenschaften und Methoden wie Abmessungen, Poster und Bildstatistiken.

seit JavaScript Baseline: alle Browser (seit HTML5) Kategorie: webapi

Signatur

interface HTMLVideoElement extends HTMLMediaElement

Beschreibung

Das Interface HTMLVideoElement wird von jedem <video>-Element im DOM umgesetzt. Es erbt die gesamte Wiedergabesteuerung von HTMLMediaElement, also play(), pause(), currentTime, volume, muted, src sowie Ereignisse wie loadedmetadata, timeupdate oder ended. Zusätzlich kommen Funktionen hinzu, die es nur bei Videos gibt.

Die wichtigsten eigenen Mitglieder:

  • videoWidth / videoHeight (nur lesbar): die tatsächliche Auflösung des Videos in Pixeln, verfügbar ab loadedmetadata.
  • width / height: die Anzeigegröße, entsprechend den HTML-Attributen.
  • poster: URL eines Vorschaubilds, das vor dem Start der Wiedergabe angezeigt wird.
  • playsInline: gibt an, ob das Video auf Mobilgeräten (vor allem iOS) innerhalb der Seite statt im Vollbild abgespielt wird.
  • disablePictureInPicture: verhindert die Bild-in-Bild-Wiedergabe.
  • getVideoPlaybackQuality(): liefert ein VideoPlaybackQuality-Objekt mit Angaben zu ausgelassenen und gesamten Frames.
  • requestPictureInPicture(): startet den Bild-in-Bild-Modus und gibt ein Promise<PictureInPictureWindow> zurück.
  • requestVideoFrameCallback(callback) / cancelVideoFrameCallback(id): registriert einen Rückruf, der einmal pro dargestelltem Videobild ausgelöst wird. Das eignet sich für bildgenaue Verarbeitung.

Typische Einsatzfälle sind eigene Player-Oberflächen, Vorschaubilder über <canvas>, Kamera-Streams per srcObject mit getUserMedia(), Qualitätsmessung beim Streaming und Echtzeit-Effekte mit WebGL oder Canvas.

Instanzen entstehen entweder durch HTML-Markup oder per document.createElement('video'). Ein eigener Konstruktor wie new HTMLVideoElement() lässt sich nicht direkt aufrufen.

Rückgabewert

Typ
HTMLVideoElement
Beschreibung
Wird von document.createElement('video'), document.querySelector('video') usw. zurückgegeben.

Beispiele

Video erzeugen und Auflösung auslesen

const video = document.createElement('video');
video.src = '/media/intro.mp4';
video.poster = '/media/intro-poster.jpg';
video.controls = true;
video.playsInline = true;
video.muted = true; // Voraussetzung für Autoplay in den meisten Browsern
document.body.append(video);

video.addEventListener('loadedmetadata', () => {
  console.log(`Auflösung: ${video.videoWidth}x${video.videoHeight}`);
  console.log(`Dauer: ${video.duration.toFixed(1)} s`);
});

try {
  await video.play();
} catch (err) {
  console.warn('Autoplay blockiert:', err.name);
}
Auflösung: 1920x1080 Dauer: 42.0 s

Vorschaubild (Thumbnail) über Canvas erzeugen

const createThumbnail = (video, time = 1) => new Promise((resolve, reject) => {
  video.addEventListener('seeked', () => {
    const canvas = document.createElement('canvas');
    canvas.width = video.videoWidth;
    canvas.height = video.videoHeight;
    canvas.getContext('2d').drawImage(video, 0, 0);
    canvas.toBlob(resolve, 'image/jpeg', 0.8);
  }, { once: true });
  video.addEventListener('error', reject, { once: true });
  video.currentTime = time;
});

const video = document.querySelector('video');
video.addEventListener('loadeddata', async () => {
  const blob = await createThumbnail(video, 2);
  const img = document.createElement('img');
  img.src = URL.createObjectURL(blob);
  document.body.append(img);
}, { once: true });

Webcam anzeigen und Wiedergabequalität messen

const video = document.querySelector('#kamera');

const stream = await navigator.mediaDevices.getUserMedia({ video: true });
video.srcObject = stream;
await video.play();

setInterval(() => {
  const q = video.getVideoPlaybackQuality();
  const quote = q.totalVideoFrames
    ? (q.droppedVideoFrames / q.totalVideoFrames * 100).toFixed(2)
    : 0;
  console.log(`Frames: ${q.totalVideoFrames}, ausgelassen: ${quote} %`);
}, 5000);
Frames: 150, ausgelassen: 0.00 %

Bild-in-Bild und bildgenaue Callbacks

const video = document.querySelector('video');

document.querySelector('#pip').addEventListener('click', async () => {
  if (!document.pictureInPictureEnabled || video.disablePictureInPicture) return;
  if (document.pictureInPictureElement) {
    await document.exitPictureInPicture();
  } else {
    await video.requestPictureInPicture();
  }
});

if ('requestVideoFrameCallback' in HTMLVideoElement.prototype) {
  const onFrame = (now, metadata) => {
    console.log(`Frame bei ${metadata.mediaTime.toFixed(3)} s`);
    video.requestVideoFrameCallback(onFrame);
  };
  video.requestVideoFrameCallback(onFrame);
}
Frame bei 0.033 s Frame bei 0.067 s …

// Wichtig · Fallstricke

  • Abmessungen erst nach Metadaten: videoWidth und videoHeight sind 0, solange loadedmetadata noch nicht ausgelöst wurde. Deshalb immer auf dieses Ereignis warten.
  • Autoplay-Richtlinien: play() gibt ein Promise zurück. Ohne Nutzerinteraktion wird es meist abgelehnt (NotAllowedError), sofern das Video nicht stummgeschaltet ist (muted). Die Ablehnung deshalb immer mit catch abfangen.
  • iOS Safari: Ohne playsInline bzw. das Attribut playsinline öffnet sich das Video im Vollbild.
  • CORS und Canvas: Wird ein Video von einer fremden Herkunft ohne crossOrigin="anonymous" und passende CORS-Header in ein Canvas gezeichnet, gilt das Canvas als „verunreinigt“ (tainted). toDataURL(), toBlob() und getImageData() werfen dann einen SecurityError.
  • Kompatibilität: Die Grundfunktionen gibt es in allen modernen Browsern. requestVideoFrameCallback() wird in Chromium und Safari unterstützt, in Firefox erst seit Version 132. requestPictureInPicture() fehlt in Firefox, der nur eine eigene Bild-in-Bild-Oberfläche ohne API anbietet. Deshalb vorher mit Feature-Detection prüfen.
  • Ressourcen freigeben: Kamera-Streams mit stream.getTracks().forEach(t => t.stop()) beenden. Object-URLs mit URL.revokeObjectURL() wieder freigeben.