Signatur
Beschreibung
Die Schnittstelle BlobEvent erweitert Event und steht für Ereignisse, die einen Blob mitliefern. In der Praxis begegnet sie einem fast nur beim Ereignis dataavailable eines MediaRecorder: Hat der Recorder einen Teil der Audio- oder Videoaufnahme fertig kodiert, gibt er ihn als BlobEvent aus.
Die wichtigsten Eigenschaften sind data (nur lesbar, ein Blob mit den kodierten Mediendaten) und timecode (nur lesbar, ein DOMHighResTimeStamp, also der Zeitstempel des ersten Datenblocks im Blob, relativ zum ersten Blob dieser Aufnahme). Ruft man MediaRecorder.start(timeslice) mit einem Zeitintervall auf, entsteht pro Intervall ein Event. Ohne timeslice kommt nur ein einziges Event, und zwar beim Aufruf von stop() oder requestData().
Man sammelt die Blöcke meist in einem Array und fügt sie nach dem stop-Event mit new Blob(chunks, { type }) zu einer abspielbaren oder hochladbaren Datei zusammen. Alternativ kann man jeden Block sofort weitergeben, etwa per WebSocket oder fetch, um live zu streamen.
Einen eigenen BlobEvent kann man mit dem Konstruktor new BlobEvent(type, { data, timecode }) erzeugen. Das ist vor allem für Tests und Mocks nützlich.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Konstruktor-Parameter: Name des Ereignisses, z. B. "dataavailable". |
|
| $options Pflicht | { data: Blob, timecode?: DOMHighResTimeStamp, bubbles?: boolean, cancelable?: boolean, composed?: boolean } | Konstruktor-Optionen. data ist Pflicht und muss ein Blob sein. timecode ist optional. Dazu kommen die üblichen Optionen von EventInit. |
Rückgabewert
BlobEvent-Instanz mit den nur lesbaren Eigenschaften data (Blob) und timecode (number).Beispiele
Mikrofon aufnehmen und als Audiodatei abspielen
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const recorder = new MediaRecorder(stream);
const chunks = [];
recorder.addEventListener('dataavailable', (event) => {
// event ist ein BlobEvent
if (event.data.size > 0) chunks.push(event.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);
stream.getTracks().forEach((t) => t.stop());
console.log(`Aufnahme: ${blob.size} Bytes, Typ ${blob.type}`);
});
recorder.start();
setTimeout(() => recorder.stop(), 3000); // 3 Sekunden aufnehmen
Bildschirm in Blöcken aufnehmen und live hochladen (timeslice)
const stream = await navigator.mediaDevices.getDisplayMedia({ video: true });
const recorder = new MediaRecorder(stream, { mimeType: 'video/webm' });
recorder.ondataavailable = async ({ data, timecode }) => {
console.log(`Block bei ${timecode.toFixed(0)} ms, ${data.size} Bytes`);
await fetch('/api/upload-chunk', {
method: 'POST',
headers: { 'Content-Type': data.type },
body: data,
});
};
// Alle 1000 ms ein BlobEvent
recorder.start(1000);
BlobEvent manuell erzeugen (z. B. für Tests)
const blob = new Blob(['Testdaten'], { type: 'text/plain' });
const event = new BlobEvent('dataavailable', { data: blob, timecode: 42 });
const target = new EventTarget();
target.addEventListener('dataavailable', (e) => {
console.log(e instanceof BlobEvent, e.data.size, e.timecode);
});
target.dispatchEvent(event);
// Wichtig · Fallstricke
- Leere Blöcke:
event.datakann die Größe 0 haben, etwa beirequestData()direkt nach dem Start. Vor dem Speichern alsodata.size > 0prüfen. - Reihenfolge beim Stoppen: Das letzte
dataavailable-Event kommt vor demstop-Event. Den finalen Blob deshalb erst imstop-Handler zusammensetzen. - Einzelne Blöcke sind nicht eigenständig abspielbar: Nur der erste Block enthält den Container-Header (z. B. von WebM). Spätere Blöcke ergeben erst zusammen mit ihm eine gültige Datei.
- Formate je nach Browser: Safari erzeugt meist
video/mp4bzw.audio/mp4, Chrome und Firefox eher WebM. DeshalbMediaRecorder.isTypeSupported()nutzen undrecorder.mimeTypeübernehmen. - Kompatibilität:
timecodewird nicht von allen Browsern gleich zuverlässig gefüllt. Safari unterstützt die API erst ab Version 14.1. - Sicherheit: Aufnahmen setzen
getUserMedia/getDisplayMediavoraus, also einen sicheren Kontext (HTTPS) und die Zustimmung des Nutzers. MitURL.createObjectURLerzeugte URLs nach Gebrauch perURL.revokeObjectURLfreigeben, sonst entstehen Speicherlecks.