Start · Sprachen · JavaScript · Referenz · MediaRecorder: dataavailable

MediaRecorder: dataavailable

Ereignis

Wird ausgelöst, wenn ein <code>MediaRecorder</code> aufgezeichnete Mediendaten als <code>Blob</code> an die Anwendung übergibt.

seit JavaScript Baseline: alle modernen Browser (Safari 14.1+) Kategorie: webapi

Signatur

mediaRecorder.addEventListener("dataavailable", handler)

Beschreibung

Das Ereignis dataavailable ist der zentrale Kanal, über den ein MediaRecorder seine aufgezeichneten Daten herausgibt. Der Handler erhält ein BlobEvent, dessen Eigenschaft data einen Blob mit den kodierten Mediendaten enthält (z. B. WebM/Opus oder MP4/AAC). Man registriert den Handler mit addEventListener("dataavailable", …) oder über die Eigenschaft ondataavailable.

Das Ereignis wird in folgenden Situationen ausgelöst:

  • wenn stop() aufgerufen wird – der restliche Puffer wird geliefert, danach folgt das stop-Ereignis,
  • wenn der aufgezeichnete Medienstrom endet (z. B. alle Tracks beendet),
  • wenn requestData() aufgerufen wird – die bisher gesammelten Daten werden geliefert und ein neuer Blob begonnen,
  • periodisch alle timeslice Millisekunden, wenn start(timeslice) mit einem Intervall aufgerufen wurde.

Ohne timeslice entsteht typischerweise nur ein einziger großer Blob am Ende der Aufnahme. Mit timeslice erhält man Teilstücke (Chunks), die man sammeln und später zu einem Blob zusammenfügen oder direkt streamen (z. B. per WebSocket oder fetch) kann. Nur der erste Chunk enthält die Container-Header – einzelne spätere Chunks sind für sich allein meist nicht abspielbar.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignisname "dataavailable".
$handler Pflicht (event: BlobEvent) => void Callback, das ein BlobEvent erhält. event.data ist der Blob mit den Mediendaten, event.timecode der Zeitstempel (ms) des Blob-Anfangs.
$options boolean | AddEventListenerOptions false Optionale Listener-Optionen wie once oder signal.

Rückgabewert

Typ
void
Beschreibung
addEventListener gibt nichts zurück. Der Handler erhält ein BlobEvent.

Beispiele

Mikrofonaufnahme mit addEventListener und Download

const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const recorder = new MediaRecorder(stream);
const chunks = [];

recorder.addEventListener('dataavailable', (event) => {
  if (event.data.size > 0) chunks.push(event.data);
});

recorder.addEventListener('stop', () => {
  const blob = new Blob(chunks, { type: recorder.mimeType });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = 'aufnahme.webm';
  a.click();
  URL.revokeObjectURL(url);
  stream.getTracks().forEach((t) => t.stop());
});

recorder.start();
setTimeout(() => recorder.stop(), 5000); // 5 Sekunden aufnehmen

Chunks alle 1000 ms per ondataavailable hochladen

const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
const recorder = new MediaRecorder(stream, { mimeType: 'video/webm;codecs=vp9,opus' });
let index = 0;

recorder.ondataavailable = async ({ data, timecode }) => {
  if (!data.size) return;
  console.log(`Chunk ${index}: ${data.size} Bytes @ ${Math.round(timecode)} ms`);
  await fetch(`/upload?chunk=${index++}`, { method: 'POST', body: data });
};

recorder.start(1000); // alle 1 s ein dataavailable-Ereignis
Chunk 0: 48213 Bytes @ 1712345678901 ms Chunk 1: 51022 Bytes @ 1712345679901 ms

requestData() und Listener wieder entfernen

const stream = await navigator.mediaDevices.getDisplayMedia({ video: true });
const recorder = new MediaRecorder(stream);

const onData = (event) => {
  console.log('Zwischenstand:', event.data.size, 'Bytes');
};

recorder.addEventListener('dataavailable', onData);
recorder.start();

// Nach 3 s Zwischenstand abrufen, dann Listener entfernen
setTimeout(() => {
  recorder.requestData();
  setTimeout(() => {
    recorder.removeEventListener('dataavailable', onData);
    recorder.stop();
  }, 0);
}, 3000);
Zwischenstand: 312840 Bytes

// Wichtig · Fallstricke

  • Reihenfolge: Beim Aufruf von stop() kommt zuerst das letzte dataavailable, danach stop. Den finalen Blob daher im stop-Handler zusammensetzen, nicht direkt nach stop().
  • Leere Blobs: event.data.size kann 0 sein – vor dem Speichern prüfen.
  • Chunks sind nicht eigenständig: Nur der erste Chunk enthält Container-Header. Für Wiedergabe alle Chunks in Reihenfolge zu einem Blob zusammenfügen.
  • timeslice ist ein Richtwert: Browser können das Intervall auf einen Mindestwert anheben oder leicht abweichen.
  • MIME-Typen: Unterstützte Formate unterscheiden sich (Chrome/Firefox: WebM; Safari: MP4). Mit MediaRecorder.isTypeSupported() prüfen und recorder.mimeType für den Blob verwenden.
  • Speicher: Lange Aufnahmen ohne Upload sammeln viele Daten im Arbeitsspeicher; Object-URLs mit URL.revokeObjectURL() freigeben.
  • Kompatibilität: In allen modernen Browsern verfügbar, Safari ab 14.1. getUserMedia erfordert einen sicheren Kontext (HTTPS) und Nutzerzustimmung.