Signatur
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
statewird auf"inactive"gesetzt. - Ein letztes
dataavailable-Ereignis mit einemBlobder 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
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);
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);
});
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);
// Wichtig · Fallstricke
- Zustand
"inactive": Ältere Spezifikationsstände und Browser werfen eineInvalidStateError-DOMException, wennstop()auf einem inaktiven Rekorder aufgerufen wird. Die aktuelle Spezifikation ignoriert den Aufruf stattdessen. Prüfe darum vorherrecorder.state !== 'inactive', dann funktioniert es überall. - Geräte bleiben aktiv:
stop()beendet nur die Aufnahme, nicht denMediaStream. Kamera- bzw. Mikrofon-Anzeige bleiben an, bis dutrack.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 imstop-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/mp4bzw.video/mp4. Lies deshalbrecorder.mimeTypeaus, statt ein festes Format anzunehmen.