Signatur
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 abloadedmetadata.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 einVideoPlaybackQuality-Objekt mit Angaben zu ausgelassenen und gesamten Frames.requestPictureInPicture(): startet den Bild-in-Bild-Modus und gibt einPromise<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
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);
}
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);
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);
}
// Wichtig · Fallstricke
- Abmessungen erst nach Metadaten:
videoWidthundvideoHeightsind0, solangeloadedmetadatanoch 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 mitcatchabfangen. - iOS Safari: Ohne
playsInlinebzw. das Attributplaysinlineö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()undgetImageData()werfen dann einenSecurityError. - 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 mitURL.revokeObjectURL()wieder freigeben.