Start · Sprachen · JavaScript · Referenz · CanvasCaptureMediaStreamTrack

CanvasCaptureMediaStreamTrack

Schnittstelle

Stellt die Videospur eines <code>MediaStream</code> dar, den <code>HTMLCanvasElement.captureStream()</code> aus dem Inhalt eines <code>&lt;canvas&gt;</code> erzeugt.

seit JavaScript Chrome/Edge 51+, Safari 11+; Firefox nur über Canv Kategorie: webapi

Signatur

interface CanvasCaptureMediaStreamTrack extends MediaStreamTrack

Beschreibung

CanvasCaptureMediaStreamTrack gehört zur Media Capture and Streams API und erweitert MediaStreamTrack. Man erstellt die Schnittstelle nicht selbst über einen Konstruktor. Sie entsteht automatisch, wenn man canvas.captureStream() aufruft. Der zurückgegebene MediaStream enthält genau eine Videospur dieses Typs. Sie liefert fortlaufend das, was auf das Canvas gezeichnet wird.

Typische Einsatzzwecke:

  • Canvas-Animationen, Spiele oder Visualisierungen mit MediaRecorder als Video aufnehmen
  • Bearbeitete Kamerabilder (Filter, Overlays, Wasserzeichen) über WebRTC mit RTCPeerConnection.addTrack() versenden
  • Canvas-Inhalte in einem <video>-Element als Vorschau wiedergeben

Zusätzlich zu allen Mitgliedern von MediaStreamTrack (z. B. stop(), enabled, readyState) bietet die Schnittstelle Folgendes:

  • canvas (schreibgeschützt): das HTMLCanvasElement, aus dem die Spur ihre Bilder bezieht
  • requestFrame(): erfasst manuell ein einzelnes Bild. Das ist vor allem sinnvoll, wenn captureStream(0) aufgerufen wurde und deshalb keine Bilder automatisch erfasst werden.

Welche Bildrate die Spur hat, legt das optionale Argument frameRate von captureStream() fest. Ohne Argument wird jedes Mal ein neues Bild erfasst, wenn sich das Canvas ändert. Mit einer Zahl ist das die Obergrenze an Bildern pro Sekunde. Mit 0 wird nur beim Aufruf von requestFrame() erfasst.

Parameter

Name Typ Default Beschreibung
$frameRate number (nicht gesetzt = Bild bei jeder Änderung) Argument von HTMLCanvasElement.captureStream(frameRate), mit dem die Spur entsteht. Legt die höchste Bildrate fest. 0 schaltet die automatische Erfassung ab, dann kommen Bilder nur über requestFrame().

Rückgabewert

Typ
CanvasCaptureMediaStreamTrack
Beschreibung
Die Spur bekommt man über canvas.captureStream().getVideoTracks()[0]. Sie stellt die Eigenschaft canvas und die Methode requestFrame() bereit (Rückgabewert void).

Beispiele

Spur erzeugen und Eigenschaften prüfen

const canvas = document.querySelector('canvas');
const stream = canvas.captureStream(30); // höchstens 30 fps
const [track] = stream.getVideoTracks();

console.log(track.constructor.name);
console.log(track.kind);
console.log(track.canvas === canvas);
CanvasCaptureMediaStreamTrack video true

Canvas-Animation mit MediaRecorder als WebM aufnehmen

const canvas = document.querySelector('#scene');
const ctx = canvas.getContext('2d');
const stream = canvas.captureStream(60);
const recorder = new MediaRecorder(stream, { mimeType: 'video/webm' });
const chunks = [];

recorder.addEventListener('dataavailable', (e) => chunks.push(e.data));
recorder.addEventListener('stop', () => {
  const blob = new Blob(chunks, { type: 'video/webm' });
  const a = document.createElement('a');
  a.href = URL.createObjectURL(blob);
  a.download = 'animation.webm';
  a.click();
});

let x = 0;
const draw = () => {
  ctx.fillStyle = '#111';
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  ctx.fillStyle = 'tomato';
  ctx.fillRect(x, 50, 40, 40);
  x = (x + 3) % canvas.width;
  requestAnimationFrame(draw);
};

draw();
recorder.start();
setTimeout(() => {
  recorder.stop();
  stream.getTracks().forEach((t) => t.stop());
}, 5000);

Bilder manuell mit requestFrame() erfassen

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
const stream = canvas.captureStream(0); // keine automatische Erfassung
const [track] = stream.getVideoTracks();

document.querySelector('video').srcObject = stream;

const renderSlide = (text) => {
  ctx.fillStyle = 'white';
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  ctx.fillStyle = 'black';
  ctx.font = '32px sans-serif';
  ctx.fillText(text, 20, 60);
  // Nur jetzt ein Bild in die Spur schicken
  if (typeof track.requestFrame === 'function') {
    track.requestFrame();
  } else if (typeof stream.requestFrame === 'function') {
    stream.requestFrame(); // Firefox-Variante
  }
};

renderSlide('Folie 1');

Bearbeitetes Canvas-Video per WebRTC senden

const pc = new RTCPeerConnection();
const canvas = document.querySelector('#overlay');
const stream = canvas.captureStream(25);

for (const track of stream.getVideoTracks()) {
  pc.addTrack(track, stream);
}

const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
console.log(pc.getSenders()[0].track.canvas.id);
overlay

// Wichtig · Fallstricke

  • Browser-Kompatibilität: Chromium-Browser und Safari haben die Schnittstelle CanvasCaptureMediaStreamTrack mit canvas und requestFrame(). Firefox kennt captureStream() zwar, legt canvas und requestFrame() aber auf den Stream (CanvasCaptureMediaStream) statt auf die Spur. Deshalb vorher mit einer Funktionsprüfung testen (siehe Beispiel 3).
  • Sicherheit / CORS: Ist das Canvas „tainted“, weil Bilder oder Videos von einer anderen Herkunft ohne CORS-Freigabe gezeichnet wurden, löst captureStream() einen SecurityError aus. Wird das Canvas erst nach dem Aufruf tainted, liefert die Spur keine brauchbaren Inhalte mehr. Fremde Ressourcen deshalb mit crossOrigin = 'anonymous' und passenden CORS-Headern laden.
  • Ohne Zeichenvorgänge entstehen keine neuen Bilder. Ein statisches Canvas ergibt ein „eingefrorenes“ Video. Manche Empfänger (z. B. WebRTC) zeigen dann schwarz oder brechen ab.
  • In Hintergrund-Tabs drosselt der Browser requestAnimationFrame. Die Aufnahme ruckelt dann oder bleibt stehen.
  • Ein <canvas> mit Breite oder Höhe 0 erzeugt keine gültigen Bilder. Für OffscreenCanvas gibt es kein captureStream().
  • Nach der Nutzung track.stop() aufrufen, damit Ressourcen freigegeben werden.