In einem früheren Artikel haben wir die Hardware-Fähigkeiten von Progressive Web Apps (PWAs) detailliert beschrieben. Der Zugriff auf die Kamera ist eine der herausragendsten Funktionen, die wir immer häufiger sehen. Die ordnungsgemäße Integration dieser Funktion in Ihre PWA ist jedoch keine einfache Aufgabe. Deshalb versuchen wir in unserem heutigen Artikel, Sie durch diesen gesamten Prozess zu führen.

Um diese Funktion zu nutzen, sind einige Voraussetzungen hilfreich. Grundlegende Kenntnisse in HTML und JavaScript sind unerlässlich, da die Kamera-APIs über diese Technologien angesprochen werden. Obwohl der Quelltext eine grundlegende PWA, die möglicherweise mit ReactJS erstellt wurde, als Voraussetzung nennt, konzentriert sich der Kern des Kamera-Zugriffs auf allgemeine Web-Standards, die in jeder modernen Webanwendung verwendet werden können.

Können PWAs auf die Kamera zugreifen?
Ja, Progressive Web Apps (PWAs) können auf die Kamera von Geräten zugreifen. Dies wird über die getUserMedia() API realisiert, die Teil des WebRTC-Frameworks ist. Diese API ermöglicht es PWAs, Zugriff auf die Kamera und das Mikrofon des Geräts anzufordern, was Funktionen wie Fotoaufnahme und Videoaufzeichnung ermöglicht.
Zugriff auf die Kamera in einer PWA
Die Grundlagen
Einführung in getUserMedia() – eine API von WebRTC.
Um direkten Zugriff auf eine Kamera und/oder ein Mikrofon zu erhalten, verwendet das Web eine API namens getUserMedia(), die von fast allen modernen Browsern weitgehend unterstützt wird. Diese API ist zusammen mit RTCPeerConnection und RTCDataChannel Teil von WebRTC – einem Framework, das in Browsern integriert ist und Echtzeitkommunikation ermöglicht.
Grundsätzlich fordert die API (navigator.mediaDevices.getUserMedia(constraints)) den Benutzer zur Berechtigung auf, auf Audio- und Videoeingaben des Geräts (z. B. Mikrofon, Webcam, Kamera usw.) zuzugreifen. Mit dieser Berechtigung generiert die API ein JavaScript-Objekt vom Typ MediaStream, das weiter manipuliert werden kann.
Beispiele für Constraints
Nehmen wir an, wir haben eine Schaltfläche:
<button>Mein Gesicht zeigen</button>Und das Klicken auf diese Schaltfläche ruft die Methode navigator.mediaDevices.getUserMedia() auf (ohne Audioeingabe):
navigator.mediaDevices.getUserMedia({ video: true })Wir können auch mit den Constraints sehr spezifisch werden:
navigator.mediaDevices.getUserMedia({ video: { minAspectRatio: 1.333, minFrameRate: 30, width: 1280, heigth: 720 } })Zusätzlich können wir eine facingMode-Eigenschaft im Video-Objekt angeben, die dem Browser mitteilt, welche Kamera des Geräts verwendet werden soll:
{ video: { ... facingMode: { // Verwende die Rückkamera exact: 'environment' } } }Oder:
{ video: { … // Verwende die Frontkamera facingMode: ‘user’ } }Wichtige Hinweise:
- Die API ist nur auf einem sicheren Ursprung (HTTPS) verfügbar.
- Um eine Liste der unterstützten Constraints auf dem aktuellen Gerät zu erhalten, führen Sie Folgendes aus:
navigator.mediaDevices.getSupportedConstraints()Der kompliziertere Teil: Live-Streaming implementieren
Nachdem wir die Grundlagen verstanden haben, kommen wir zum fortgeschrittenen Teil. In diesem Teil versuchen wir, eine Schaltfläche in unserer PWA zu erstellen, die beim Klicken die Kamera öffnet und uns weitere Arbeiten ermöglicht.
Erstellen der Schaltfläche [Get access to camera]
Beginnen wir mit der <button> in unserer HTML-Datei:
<button id="get-access">Zugriff auf Kamera erhalten</button> <video autoplay></video> <script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>Hinweise:
autoplayist vorhanden, um dem MediaStream mitzuteilen, dass er automatisch abgespielt werden soll und nicht beim ersten Frame einfrieren darf.adapter-latest.jsist ein Shim, um Anwendungen von Spezifikationsänderungen und Präfixunterschieden zu isolieren.
Video-Stream in Echtzeit anzeigen, wenn die Schaltfläche geklickt wird
Um einen Video-Stream in Echtzeit anzuzeigen, wenn die Schaltfläche geklickt wird, müssen wir einen EventListener hinzufügen, der aufgerufen wird, wenn das Klick-Ereignis ausgelöst wird:
document.querySelector('#get-access').addEventListener('click', async function init(e) { try { // Hier kommt der Code zum Zugriff auf die Kamera } catch (error) { // Fehlerbehandlung } })Anschließend ruft es navigator.mediaDevices.getUserMedia() auf und fordert einen Video-Stream über die Webcam des Geräts an:
document.querySelector('#get-access').addEventListener('click', async function init(e) { try { const stream = await navigator.mediaDevices.getUserMedia({ audio: false, video: true }) const videoTracks = stream.getVideoTracks() const track = videoTracks[0] alert(`Video erhalten von: ${track.label}`) document.querySelector('video').srcObject = stream document.querySelector('#get-access').setAttribute('hidden', true) // Der Video-Stream wird nach 3 Sekunden Wiedergabe mit track.stop() gestoppt. setTimeout(() => { track.stop() }, 3 * 1000) } catch (error) { alert(`${error.name}`) console.error(error) } })Zusätzlich können Sie, wie oben im Abschnitt Grundlagen angegeben, auch spezifischere Anforderungen für den Video-Stream festlegen:
navigator.mediaDevices.getUserMedia({ video: { mandatory: { minAspectRatio: 1.333, maxAspectRatio: 1.334, facingMode: ‘user’}, optional: [ { minFrameRate: 60 }, { maxWidth: 640 }, { maxHeigth: 480 } ] } }, successCallback, errorCallback);Beachten Sie, dass das obige Beispiel eine ältere Syntax mit mandatory und optional zeigt, während die modernen Beispiele oben eine vereinfachte Syntax verwenden.
Bildmanipulation mit Canvas
Mit dem <video>-Element in Kombination mit einem <canvas> können Sie unseren Echtzeit-Video-Stream weiterverarbeiten. Dies umfasst die Möglichkeit, eine Vielzahl von Effekten anzuwenden, wie z. B. benutzerdefinierte Filter oder Chroma-Keying (auch bekannt als „Green-Screen-Effekt“) – alles mithilfe von JavaScript-Code.
Falls Sie mehr darüber lesen möchten, hat Mozilla einen detaillierten Leitfaden zur Videomanipulation mit Canvas verfasst (der Link dient nur zur Veranschaulichung des Konzepts, der tatsächliche Link wird nicht eingefügt). Dieser Leitfaden kann Ihnen weitere Einblicke in die Möglichkeiten geben.

Schnappschüsse erfassen: takePhoto vs. grabFrame
Die neuen Methoden takePhoto und grabFrame der getUserMedia() API können verwendet werden, um einen Schnappschuss des aktuell gestreamten Videos zu erfassen. Es gibt jedoch signifikante Unterschiede zwischen den beiden Methoden:
| Methode | Beschreibung | Ausgabe | Zweck | Auflösung |
|---|---|---|---|---|
grabFrame() | Erfasst einfach den nächsten Video-Frame. | ImageBitmap | Einfache Frame-Erfassung, geeignet für Canvas-Verarbeitung. | Auflösung des Video-Streams. |
takePhoto() | Unterbricht den Stream kurz und verwendet die höchste verfügbare fotografische Auflösung der Kamera. | Blob (Bilddatei) | Optimiert für das Aufnehmen von Standfotos in hoher Qualität. | Höchste verfügbare fotografische Auflösung. |
Grundsätzlich erfasst grabFrame einfach den nächsten Video-Frame – eine einfache und nicht so effiziente Methode zur Aufnahme von Fotos. Die takePhoto-Methode hingegen verwendet eine bessere Methode zur Aufnahme von Frames, indem sie den aktuellen Video-Stream unterbricht, um die „höchste verfügbare fotografische Kameraauflösung“ der Kamera zur Erfassung eines Blob-Bildes zu nutzen.
In den folgenden Beispielen zeichnen wir den erfassten Frame mithilfe der grabFrame-Methode in ein Canvas-Element:
var grabFrameButton = document.querySelector('button#grabFrame'); var canvas = document.querySelector('canvas'); grabFrameButton.onclick = grabFrame; function grabFrame() { imageCapture.grabFrame() .then(function(imageBitmap) { console.log('Frame erfasst:', imageBitmap); canvas.width = imageBitmap.width; canvas.height = imageBitmap.height; canvas.getContext('2d').drawImage(imageBitmap, 0, 0); canvas.classList.remove('hidden'); }) .catch(function(error) { console.log('grabFrame() Fehler: ', error); }); }Und in diesem Beispiel verwenden wir die takePhoto()-Methode:
var takePhotoButton = document.querySelector('button#takePhoto'); var canvas = document.querySelector('canvas'); takePhotoButton.onclick = takePhoto; // Erhält einen Blob von der aktuell ausgewählten Kameraquelle und // zeigt diesen mit einem img-Element an. function takePhoto() { imageCapture.takePhoto().then(function(blob) { console.log('Foto aufgenommen:', blob); // Ein img Element müsste existieren, um das Bild anzuzeigen // img.classList.remove('hidden'); // img.src = URL.createObjectURL(blob); // Fügen Sie hier Logik hinzu, um den Blob zu verwenden, z.B. auf einem Canvas zeichnen oder hochladen const ctx = canvas.getContext('2d'); const img = new Image(); img.onload = () => { canvas.width = img.width; canvas.height = img.height; ctx.drawImage(img, 0, 0); canvas.classList.remove('hidden'); URL.revokeObjectURL(img.src); // Gibt Speicher frei }; img.src = URL.createObjectURL(blob); }).catch(function(error) { console.log('takePhoto() Fehler: ', error); }); }Um eine Vorstellung davon zu bekommen, wie die oben genannten Methoden in Aktion aussehen, empfehlen wir das Beispiel Simple Image Capture. Alternativ ist PWA Media Capture ebenfalls ein gutes Beispiel dafür, wie eine grundlegende Medienaufnahme-Funktion in einer PWA aussehen könnte (die Links dienen nur zur Veranschaulichung des Konzepts, tatsächliche Links werden nicht eingefügt).
Häufig gestellte Fragen (FAQ)
Kann ich auch auf das Mikrofon zugreifen?
Ja, die getUserMedia() API ermöglicht auch den Zugriff auf das Mikrofon. Sie müssen einfach audio: true in den Constraints angeben.
Ist der Kamerazugriff sicher?
Ja, der Zugriff ist nur auf sicheren Ursprüngen (HTTPS) möglich und erfordert immer eine ausdrückliche Zustimmung des Benutzers durch einen Berechtigungsdialog, der vom Browser angezeigt wird.
Kann ich auswählen, welche Kamera verwendet werden soll (Vorder- oder Rückseite)?
Ja, Sie können die Eigenschaft facingMode in den Video-Constraints verwenden, um festzulegen, ob die Frontkamera ('user') oder die Rückkamera ('environment') bevorzugt oder exakt verwendet werden soll.
Was passiert, wenn der Benutzer die Berechtigung verweigert?
Wenn der Benutzer den Zugriff verweigert, schlägt der Aufruf von getUserMedia() fehl und löst einen Fehler aus. Ihre Anwendung sollte diesen Fehler in einem catch-Block abfangen und entsprechend reagieren, z. B. eine Meldung anzeigen, dass der Zugriff benötigt wird.
Wird diese Funktion von allen Browsern unterstützt?
Die getUserMedia() API und WebRTC werden von den meisten modernen Browsern auf Desktops und Mobilgeräten weitgehend unterstützt. Der Einsatz von Bibliotheken wie adapter.js kann helfen, Unterschiede in den Spezifikationen und Browser-Präfixen auszugleichen.
Fazit
In diesem Artikel haben wir Ihnen die Grundlagen sowie einige fortgeschrittene Tricks zur Implementierung von Kamerafunktionen in Ihrer PWA vorgestellt. Der Rest liegt ganz bei Ihrer Vorstellungskraft, um das Beste aus dieser Funktion zu machen. Die Fähigkeit, direkt auf die Hardware des Geräts zuzugreifen, eröffnet eine Fülle von Möglichkeiten für interaktive und leistungsstarke Webanwendungen.
Hat dich der Artikel Kamera-Zugriff in Web-Apps (PWAs) interessiert? Schau auch in die Kategorie Ogólny rein – dort findest du mehr ähnliche Inhalte!
