Start · Sprachen · JavaScript · Referenz · HTMLMediaElement: loadedmetadata

HTMLMediaElement: loadedmetadata

Ereignis

Wird ausgelöst, sobald die Metadaten eines Audio- oder Videoelements (z. B. Dauer, Abmessungen, Textspuren) geladen sind.

seit JavaScript Baseline: alle Browser Kategorie: webapi

Signatur

mediaElement.addEventListener("loadedmetadata", handler)

Beschreibung

Das Ereignis loadedmetadata feuert an einem <audio>- oder <video>-Element, sobald der Browser genug von der Mediendatei gelesen hat, um die Metadaten zu kennen. Dazu gehören die Gesamtdauer (duration), bei Videos die natürlichen Abmessungen (videoWidth, videoHeight) sowie Audio-, Video- und Textspuren. In diesem Moment wechselt readyState auf HAVE_METADATA (1).

Das Ereignis eignet sich, um die Oberfläche eines eigenen Players vorzubereiten: Dauer anzeigen, einen Fortschrittsbalken skalieren, das Seitenverhältnis eines Containers setzen oder eine Startposition über currentTime festlegen. Zu diesem Zeitpunkt sind aber noch keine Bilddaten dekodiert – für das erste darstellbare Bild ist loadeddata zuständig, für abspielbereit canplay.

Registrieren lässt sich der Handler per addEventListener("loadedmetadata", handler) oder über die Eigenschaft onloadedmetadata. Das Ereignis ist ein einfaches Event, es blubbert nicht (bubbles: false) und ist nicht abbrechbar.

Typische Ereignisreihenfolge beim Laden: loadstart → durationchange → loadedmetadata → loadeddata → canplay → canplaythrough.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignisname "loadedmetadata".
$handler Pflicht (event: Event) => void Rückruffunktion; erhält ein einfaches Event, dessen target das Medienelement ist.
$options boolean | AddEventListenerOptions false Optionen wie { once: true } oder { signal } zum automatischen Entfernen.

Beispiele

Dauer und Auflösung eines Videos anzeigen

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

const formatTime = (s) => {
  const m = Math.floor(s / 60);
  const sec = Math.floor(s % 60).toString().padStart(2, '0');
  return `${m}:${sec}`;
};

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

video.src = 'film.mp4';
Dauer: 2:34 Auflösung: 1920x1080

Wiedergabe an gespeicherter Position fortsetzen (on-Property)

const video = document.querySelector('#player');
const key = `pos:${video.currentSrc || video.src}`;

video.onloadedmetadata = () => {
  const saved = Number(localStorage.getItem(key));
  if (saved > 0 && saved < video.duration) {
    video.currentTime = saved;
  }
};

video.addEventListener('timeupdate', () => {
  localStorage.setItem(key, String(video.currentTime));
});

Metadaten per Promise abwarten – auch wenn schon geladen

const waitForMetadata = (media) =>
  new Promise((resolve, reject) => {
    // Ereignis könnte bereits vorbei sein
    if (media.readyState >= HTMLMediaElement.HAVE_METADATA) {
      resolve(media);
      return;
    }
    const controller = new AbortController();
    const { signal } = controller;
    media.addEventListener('loadedmetadata', () => {
      controller.abort();
      resolve(media);
    }, { signal });
    media.addEventListener('error', () => {
      controller.abort();
      reject(media.error);
    }, { signal });
  });

const audio = new Audio('podcast.mp3');
const el = await waitForMetadata(audio);
console.log(`Länge: ${Math.round(el.duration)} s`);
Länge: 1834 s

Listener wieder entfernen

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

const setAspectRatio = () => {
  video.parentElement.style.aspectRatio = `${video.videoWidth} / ${video.videoHeight}`;
  video.removeEventListener('loadedmetadata', setAspectRatio);
};

video.addEventListener('loadedmetadata', setAspectRatio);

// Wichtig · Fallstricke

  • Wettlaufsituation: Wird der Listener erst registriert, nachdem die Metadaten bereits geladen sind (z. B. bei gecachten Dateien oder Skripten am Seitenende), feuert das Ereignis nicht erneut. Vorher readyState >= 1 prüfen.
  • Kein Bubbling: Ein Listener auf document greift nur in der Capture-Phase: document.addEventListener('loadedmetadata', fn, true).
  • preload: Mit preload="none" lädt der Browser keine Metadaten, bis der Nutzer die Wiedergabe startet. Mobile Browser (v. a. iOS Safari) ignorieren preload teils und laden erst nach Interaktion.
  • duration kann Infinity sein – etwa bei Livestreams oder manchen MediaSource-/WebM-Aufnahmen ohne Dauerangabe. Auch NaN ist möglich, wenn noch keine Daten vorliegen.
  • Bei Audiodateien sind videoWidth/videoHeight gleich 0.
  • Bei jedem Wechsel von src bzw. Aufruf von load() wird das Ereignis erneut ausgelöst – Listener mit { once: true } ggf. neu registrieren.
  • Kompatibilität: in allen modernen Browsern seit Langem unterstützt.