Start · Sprachen · JavaScript · Referenz · HTMLMediaElement: stalled

HTMLMediaElement: stalled

Ereignis

Wird ausgelöst, wenn der Browser Mediendaten laden will, aber unerwartet etwa 3 Sekunden lang keine Daten mehr eintreffen.

seit JavaScript Baseline: alle Browser Kategorie: webapi

Signatur

element.addEventListener("stalled", handler)

Beschreibung

Das Ereignis stalled wird an einem <audio>- oder <video>-Element (HTMLMediaElement) ausgelöst, wenn der Browser gerade Mediendaten abruft (networkState === NETWORK_LOADING), aber für etwa drei Sekunden keine neuen Daten mehr ankommen. Typische Ursachen sind abgerissene Netzwerkverbindungen, überlastete Server oder sehr langsame mobile Verbindungen.

Man registriert den Handler entweder per addEventListener("stalled", handler) oder über die Eigenschaft onstalled. Das Ereignis ist nicht abbrechbar und steigt nicht auf (kein Bubbling). Es ist ein einfaches Event ohne zusätzliche Eigenschaften.

Praktisch nutzt man stalled, um Nutzern einen Hinweis wie „Verbindung langsam…“ anzuzeigen, Diagnosedaten zu sammeln oder nach einer Wartezeit einen Neuversuch anzustoßen. Wichtig: stalled bedeutet nicht zwingend, dass die Wiedergabe steht – solange genug gepuffert ist, läuft sie weiter. Für echte Wiedergabeunterbrechungen ist waiting das passendere Ereignis.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignisname "stalled".
$handler Pflicht (event: Event) => void Callback, der ein einfaches Event-Objekt erhält; event.target ist das Medienelement.
$options boolean | AddEventListenerOptions false Optionen wie once, passive oder signal (zum Abmelden per AbortController).

Rückgabewert

Typ
void
Beschreibung
addEventListener gibt nichts zurück. Der Handler erhält ein Event (nicht abbrechbar, kein Bubbling).

Beispiele

Hinweis bei stockendem Download anzeigen

const video = document.querySelector('video');
const hinweis = document.querySelector('#netz-hinweis');

video.addEventListener('stalled', () => {
  hinweis.textContent = 'Verbindung langsam – Daten werden nachgeladen…';
  hinweis.hidden = false;
  console.log('stalled, networkState:', video.networkState);
});

// Sobald wieder Daten eintreffen, Hinweis ausblenden
video.addEventListener('progress', () => {
  hinweis.hidden = true;
});
stalled, networkState: 2

Über die on-Property und wieder abmelden

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

audio.onstalled = (event) => {
  console.warn('Audio-Download stockt:', event.target.currentSrc);
};

// Später abmelden
audio.onstalled = null;
Audio-Download stockt: https://example.com/podcast.mp3

Automatischer Neuversuch mit removeEventListener

const video = document.querySelector('video');
let timer = null;

const onStalled = () => {
  clearTimeout(timer);
  // Nach 10 s ohne Fortschritt Quelle neu laden
  timer = setTimeout(() => {
    const pos = video.currentTime;
    console.log('Neuversuch ab', pos.toFixed(1), 's');
    video.load();
    video.currentTime = pos;
    video.play().catch(console.error);
  }, 10_000);
};

const onProgress = () => clearTimeout(timer);

video.addEventListener('stalled', onStalled);
video.addEventListener('progress', onProgress);

// Aufräumen, z. B. beim Verlassen der Seite/Komponente
const cleanup = () => {
  clearTimeout(timer);
  video.removeEventListener('stalled', onStalled);
  video.removeEventListener('progress', onProgress);
};
Neuversuch ab 42.3 s

// Wichtig · Fallstricke

  • Nicht mit waiting verwechseln: stalled betrifft den Download, waiting die Wiedergabe. Ein Video kann trotz stalled ungestört weiterlaufen, wenn der Puffer reicht.
  • Fehlalarme: Manche Browser (v. a. Mobil-Safari und Chrome mit preload="metadata" oder preload="none") feuern stalled auch, wenn der Browser das Laden absichtlich pausiert, um Bandbreite zu sparen. Deshalb keine harten Fehlerreaktionen allein darauf stützen – mit readyState, buffered und progress gegenprüfen.
  • Bei Media Source Extensions (MSE, z. B. hls.js, dash.js) ist stalled wenig aussagekräftig; dort liefern die Bibliotheken eigene Puffer-Ereignisse.
  • Das Ereignis steigt nicht auf – Delegation über einen Elternknoten funktioniert nur in der Capture-Phase ({ capture: true }).
  • Browser-Kompatibilität: in allen modernen Browsern seit Langem unterstützt.