Start · Sprachen · JavaScript · Referenz · MediaRecorder.requestData()

MediaRecorder.requestData()

Methode

Löst ein <code>dataavailable</code>-Ereignis mit einem <code>Blob</code> der bisher gepufferten Aufnahmedaten aus und beginnt danach einen neuen Puffer.

seit JavaScript Baseline: alle modernen Browser (seit 2021) Kategorie: webapi

Signatur

MediaRecorder.prototype.requestData()

Beschreibung

Mit requestData() fordert man von einem laufenden MediaRecorder die bis zu diesem Zeitpunkt gesammelten Mediendaten an. Der Browser packt die gepufferten Daten in ein Blob, übergibt es asynchron über ein dataavailable-Ereignis (event.data) und beginnt dann mit einem neuen, leeren Puffer. Die Aufnahme selbst läuft ohne Unterbrechung weiter.

Das ist nützlich, wenn Sie Daten zu selbst gewählten Zeitpunkten abrufen wollen statt in festen Abständen über den timeslice-Parameter von start(), zum Beispiel zum Hochladen von Teilstücken nach einer Nutzeraktion, zum Zwischenspeichern vor dem Schließen einer Seite oder beim Streamen an einen Server in eigenem Takt.

Wichtig: Die zurückgegebenen Blobs sind Fragmente eines durchgehenden Containers (z. B. WebM). Nur das erste Stück enthält die Header-Informationen. Eine abspielbare Datei entsteht meist erst, wenn alle Stücke in der richtigen Reihenfolge zu einem Blob zusammengefügt werden.

Beispiele

Daten per Knopfdruck abrufen

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);
    console.log(`Stück ${chunks.length}: ${event.data.size} Bytes`);
  }
});

recorder.start();

document.querySelector('#snapshot').addEventListener('click', () => {
  if (recorder.state === 'recording') {
    recorder.requestData();
  }
});
Stück 1: 48213 Bytes Stück 2: 31877 Bytes

Teilstücke in eigenem Takt hochladen

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

recorder.ondataavailable = async (event) => {
  if (event.data.size === 0) return;
  const body = new FormData();
  body.append('chunk', event.data, `teil-${index++}.webm`);
  await fetch('/api/upload', { method: 'POST', body });
};

recorder.start();

// Alle 5 Sekunden Daten anfordern
const timer = setInterval(() => recorder.requestData(), 5000);

recorder.onstop = () => clearInterval(timer);

Fehler bei inaktivem Recorder abfangen

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

try {
  recorder.requestData(); // noch nicht gestartet
} catch (err) {
  console.log(err.name, '-', recorder.state);
}
InvalidStateError - inactive

// Wichtig · Fallstricke

  • Ist recorder.state gleich "inactive", wirft die Methode eine DOMException vom Typ InvalidStateError. Prüfen Sie den Zustand deshalb vor dem Aufruf.
  • Im Zustand "paused" ist der Aufruf erlaubt. Es werden dann die bis zur Pause gesammelten Daten geliefert.
  • Das Ereignis wird asynchron ausgelöst. Direkt nach dem Aufruf liegt noch kein Blob vor.
  • Der Blob kann leer sein (size === 0), wenn seit dem letzten Abruf nichts aufgenommen wurde. Solche Blobs sollten Sie herausfiltern.
  • Einzelne Stücke außer dem ersten lassen sich meist nicht eigenständig abspielen, weil ihnen der Container-Header fehlt.
  • Werden timeslice und requestData() zusammen verwendet, entstehen unterschiedlich große Stücke. Das ist unproblematisch, macht aber die Planung von Uploads schwerer.
  • Kompatibilität: Chrome, Edge, Firefox und Safari (ab 14.1) unterstützen die Methode. Getestet werden kann nur in einem sicheren Kontext (HTTPS), in dem getUserMedia verfügbar ist.