MediaStream API — der pragmatische Standard

Die MediaStream API (Teil der WebRTC-Familie) ist seit 2015 in allen Mainstream-Browsern verfügbar. Mit ihr greift eine Webseite — nach expliziter Erlaubnis — auf Webcam, Smartphone-Kamera und Mikrofon zu. 2026 hat sich der Stack stabilisiert und ist Mainstream-tauglich für Profilfoto-Upload, QR-Scan, Live-Filter, AR-Effekte und Document-Scan.

Das Grund-Pattern

async function startCamera() {
  try {
    const stream = await navigator.mediaDevices.getUserMedia({
      video: {
        facingMode: "user",      // "environment" für Rückkamera
        width: { ideal: 1920 },
        height: { ideal: 1080 }
      },
      audio: false
    });
    const video = document.querySelector("video");
    video.srcObject = stream;
    await video.play();
  } catch (err) {
    console.error("Camera access denied or unavailable:", err);
  }
}

Berechtigungen und UX

getUserMedia() löst eine Browser-Permissions-Dialog aus. Wichtige UX-Praktiken:

  • Niemals beim Page-Load fragen. Erst nach einer expliziten Nutzer- Aktion (Button-Klick) — sonst lehnen Nutzer pauschal ab.
  • Vorab erklären, warum. Ein kurzer Hinweis „Wir nutzen die Kamera für dein Profilfoto" vor der Browser-Frage erhöht die Zustimmung-Rate messbar.
  • Fallback anbieten. Wenn Berechtigung verweigert wird, klassischen File-Upload als Plan B.
  • Berechtigung gespeichert. Chrome merkt sich die Antwort per Site — beim zweiten Besuch wird kein Dialog mehr gezeigt.

Snapshot im Canvas erstellen

Aus einem laufenden Video-Stream einen statischen Schnappschuss machen:

function takeSnapshot(video) {
  const canvas = document.createElement("canvas");
  canvas.width = video.videoWidth;
  canvas.height = video.videoHeight;
  const ctx = canvas.getContext("2d");
  ctx.drawImage(video, 0, 0);
  return canvas.toBlob(blob => {
    const url = URL.createObjectURL(blob);
    document.querySelector("img.preview").src = url;
  }, "image/jpeg", 0.9);
}

Das Blob kann direkt als Profilfoto hochgeladen, in IndexedDB gespeichert oder weiter verarbeitet werden — z.B. mit Background-Removal.

Use-Case 1 — Profilfoto-Upload

Der Klassiker: Nutzer macht ein Selfie für sein Profil. Best Practice:

  1. Kamera mit facingMode: "user" für Selfie-Cam.
  2. Live-Preview mit weicher Crop-Box im Overlay (z.B. Kreis 400×400).
  3. Spiegelung der Vorschau (CSS transform: scaleX(-1)) — Nutzer sieht sich wie im Spiegel.
  4. Beim Capture: nicht gespiegelt speichern.
  5. Auf dem Server EXIF strippen (siehe EXIF-Beitrag).

Use-Case 2 — QR-Code-Scan

Browser-QR-Scan ohne native App. Stack: getUserMedia() + Canvas + die zxing-wasm-Library (WebAssembly-Port von ZXing). Performance auf Mid-Range-Smartphones: 5–10 FPS, ausreichend für stabilen Scan.

Wichtig: Rückkamera nutzen via facingMode: "environment". Auf Smartphones ist die Auto-Fokus-Funktion entscheidend — über applyConstraints({ focusMode: "continuous" }) aktivieren.

Use-Case 3 — Document-Scan

Pass-Foto, Vertrag, Quittung digitalisieren. Pipeline:

  1. Kamera-Stream im Vollbild.
  2. Edge-Detection per OpenCV.js oder neuerem shape-detector-api (Chrome).
  3. Auto-Crop auf den erkannten Dokument-Umriss.
  4. Perspektivische Korrektur (Trapez → Rechteck).
  5. Schwarzweiß-Konvertierung mit adaptiver Threshold-Erkennung.
  6. Export als PNG oder PDF.

Browser-only-Document-Scanner sind 2026 wettbewerbsfähig mit nativen Apps wie Scanner Pro oder Adobe Scan — mit der Datenschutz-Stärke, dass nichts hochgeladen wird.

Use-Case 4 — AR-Vorschau

Möbel-Käufer wollen sehen, wie der Stuhl in der eigenen Wohnung aussieht. Browser-AR ist 2026 produktiv möglich via:

  • WebXR Device API: native AR-Sessions in Chrome auf Android- ARCore-Geräten und Safari auf iPhones (seit visionOS 1.0).
  • MediaStream + Three.js/AR.js: poor-man's AR via Marker-Tracking, funktioniert in jedem Browser.
  • Model-Viewer Web Componentvon Google: einbettet ein 3D-Modell mit einem "In AR ansehen"-Button, der iOS-Quick-Look oder Android-Scene-Viewer startet.

Use-Case 5 — Live-Hintergrund-Effekte

Video-Stream live verarbeiten: Hintergrund-Blur (wie Zoom), Greenscreen-Ersatz, Beauty-Filter. Stack:

  1. getUserMedia() Stream.
  2. Frame-by-Frame via requestVideoFrameCallback.
  3. Segmentation mit MediaPipe oder BiRefNet (siehe Background-Removal-Beitrag).
  4. Composit mit dem Ersatz-Hintergrund auf einem zweiten Canvas.
  5. Output-Stream via captureStream() in ein neues Video-Element.

Performance: auf einer M2-CPU mit WebGPU 30+ FPS bei 720p. Auf Mid-Range-Android mit MediaPipe ~15–20 FPS — akzeptabel.

Browser-Kompatibilität 2026

  • Chrome 110+: volles MediaStream-API plus WebGPU-Accelerated-Processing.
  • Safari 17+: stabil auf macOS und iOS. iOS 17 brachte endlich PWA-Camera-Access ohne Safari-Detour.
  • Firefox 130+: volles MediaStream, WebGPU seit 2025 stabil.
  • Edge: Chromium-basiert, identisch zu Chrome.
  • Mobile In-App-Browser (TikTok, Instagram): oft eingeschränkt. Wenn Nutzer aus einer App heraus deinen Link öffnet, kann Kamera-Access fehlen.

Datenschutz-Praxis

  • Stream immer beenden, wenn die Funktion fertig ist: stream.getTracks().forEach(t => t.stop()). Sonst läuft die Kamera weiter und die LED bleibt an.
  • Nie unerwartet aufzeichnen. Die MediaRecorder-API kann Audio/Video aufzeichnen. Wer das nutzt, sollte explizit zustimmen lassen.
  • HTTPS-Pflicht. getUserMedia() funktioniert nur über HTTPS oder auf localhost. Sicher gegen MITM-Lauscher.

HTML-Fallback ohne MediaStream

Auf Mobile gibt es einen schönen klassischen Weg: <input type="file" accept="image/*" capture="user"> öffnet auf iOS und Android direkt die Kamera-App. Kein Permission-Dialog, kein Stream-Management. Nicht so flexibel wie MediaStream, aber für „mach ein Foto und lade es hoch"-Use-Cases oft die einfachere Wahl.

Tools-Empfehlung

  • Web-API direkt: für einfache Foto-Capture und Profilfoto-Upload.
  • html5-qrcode oder zxing-wasm: für QR-Scan.
  • MediaPipe: für Face-Detection, Segmentation, Pose-Estimation.
  • OpenCV.js: für klassische Bildverarbeitungs-Algorithmen.
  • Google's model-viewer: für AR-Vorschau ohne eigenen 3D-Stack.

Quellen

MDN — getUserMedia · W3C — Media Capture and Streams · Google MediaPipe · zxing-js library · OpenCV.js · W3C — WebXR Device API · model-viewer (Google) · web.dev — Capturing Images.