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

MediaRecorder.stop()

Methode

Beendet eine laufende Medienaufnahme, liefert die restlichen Daten über ein <code>dataavailable</code>-Ereignis und löst anschließend das <code>stop</code>-Ereignis aus.

seit JavaScript Baseline: alle modernen Browser (Chrome 49+, Firef Kategorie: webapi

Signatur

MediaRecorder.prototype.stop()

Beschreibung

Mit stop() beendest du eine Aufnahme, die mit MediaRecorder.start() begonnen wurde. Der Rekorder wechselt sofort in den Zustand "inactive" und sammelt keine weiteren Daten mehr aus dem MediaStream.

Die Methode arbeitet asynchron, auch wenn sie keinen Promise zurückgibt. Nach dem Aufruf passiert Folgendes in dieser Reihenfolge:

  • Der Zustand state wird auf "inactive" gesetzt.
  • Ein letztes dataavailable-Ereignis mit einem Blob der noch nicht ausgelieferten Daten wird ausgelöst.
  • Danach wird das stop-Ereignis ausgelöst.

Die fertige Datei solltest du deshalb erst im stop-Handler (bzw. onstop) aus den gesammelten Blob-Stücken zusammensetzen, nicht direkt nach dem Aufruf von stop(). Anders als pause() lässt sich eine gestoppte Aufnahme nicht fortsetzen. Ein neuer Aufruf von start() beginnt eine neue Aufnahme mit neuen Container-Kopfdaten.

Rückgabewert

Typ
undefined
Beschreibung
Kein Rückgabewert. Das Ergebnis kommt über die Ereignisse dataavailable und stop.

Beispiele

Mikrofon 5 Sekunden aufnehmen und als Audio abspielen

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

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

recorder.addEventListener('stop', () => {
  const blob = new Blob(chunks, { type: recorder.mimeType });
  const audio = new Audio(URL.createObjectURL(blob));
  audio.controls = true;
  document.body.append(audio);
  console.log('Aufnahme fertig:', blob.size, 'Bytes');
});

recorder.start();
setTimeout(() => recorder.stop(), 5000);
Aufnahme fertig: 81234 Bytes

Stop-Button mit Zustandsprüfung und Freigabe von Kamera/Mikrofon

const stopButton = document.querySelector('#stop');
const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
const recorder = new MediaRecorder(stream);
recorder.start(1000); // alle 1000 ms ein Datenstück

stopButton.addEventListener('click', () => {
  if (recorder.state !== 'inactive') {
    recorder.stop();
  }
  // stop() gibt die Geräte NICHT frei – die Tracks selbst beenden
  stream.getTracks().forEach((track) => track.stop());
  console.log('Status:', recorder.state);
});
Status: inactive

stop() in einen Promise verpacken

const stopRecording = (recorder) =>
  new Promise((resolve, reject) => {
    const chunks = [];
    recorder.ondataavailable = (e) => chunks.push(e.data);
    recorder.onstop = () => resolve(new Blob(chunks, { type: recorder.mimeType }));
    recorder.onerror = (e) => reject(e.error);
    recorder.stop();
  });

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

await new Promise((r) => setTimeout(r, 3000));
const blob = await stopRecording(recorder);
console.log(blob.type, blob.size);
audio/webm;codecs=opus 48213

// Wichtig · Fallstricke

  • Zustand "inactive": Ältere Spezifikationsstände und Browser werfen eine InvalidStateError-DOMException, wenn stop() auf einem inaktiven Rekorder aufgerufen wird. Die aktuelle Spezifikation ignoriert den Aufruf stattdessen. Prüfe darum vorher recorder.state !== 'inactive', dann funktioniert es überall.
  • Geräte bleiben aktiv: stop() beendet nur die Aufnahme, nicht den MediaStream. Kamera- bzw. Mikrofon-Anzeige bleiben an, bis du track.stop() für alle Tracks aufrufst.
  • Nicht sofort auf Daten zugreifen: Direkt nach stop() ist das letzte Datenstück noch nicht da. Setze die Datei erst im stop-Ereignis zusammen.
  • Endet der Quell-Stream von selbst (z. B. wenn die Bildschirmfreigabe beendet wird), stoppt der Rekorder automatisch und löst dieselben Ereignisse aus.
  • WebM-Dateien aus Chrome enthalten oft keine Angabe zur Dauer, deshalb lassen sie sich in manchen Playern nicht vor- und zurückspulen. Ist das wichtig, muss die Datei nachträglich bearbeitet werden.
  • Unter Safari ist das Standardformat meist audio/mp4 bzw. video/mp4. Lies deshalb recorder.mimeType aus, statt ein festes Format anzunehmen.