WebRTC für Webentwickler: Video und Audio direkt im Browser übertragen

Kamera anfordern, Peer-Verbindung aufbauen, Daten direkt zwischen Browsern austauschen: ein Einstieg in WebRTC mit JavaScript – von getUserMedia über Signaling bis zum DataChannel.

Teilen

Videotelefonie, Screensharing, Multiplayer-Spiele ohne Server in der Mitte: All das steckt hinter drei Buchstaben-Kombinationen, die im Browser längst eingebaut sind – WebRTC. Als Webentwickler brauchst du keine Plugins und keine externen SDKs, um Audio, Video oder beliebige Daten direkt von Browser zu Browser zu schicken. In diesem Artikel schauen wir uns die Bausteine an, aus denen jede WebRTC-Anwendung besteht.

Falls du erst einmal aus Nutzersicht verstehen willst, was WebRTC eigentlich leistet und warum man damit ganz ohne App telefonieren kann, lies vorab den Artikel WebRTC: Direkt im Browser telefonieren – ganz ohne App auf voip-basiswissen.de. Dort geht es um das große Bild – hier geht es um den Code.

Baustein 1: getUserMedia

Alles beginnt mit dem Zugriff auf Kamera und Mikrofon. Die Media-Capture-API liefert einen MediaStream, den du direkt in ein <video>-Element hängen kannst:

const stream = await navigator.mediaDevices.getUserMedia({
  video: true,
  audio: true
});
document.querySelector("video").srcObject = stream;

Der Browser fragt den Nutzer um Erlaubnis – ohne HTTPS gibt es grundsätzlich keinen Kamerazugriff. Schon dieser Teil allein reicht für Foto-Apps oder lokale Aufnahmen.

Baustein 2: RTCPeerConnection

Das Herzstück ist die RTCPeerConnection. Sie handelt Codecs aus, kümmert sich um Verschlüsselung (verpflichtend bei WebRTC) und findet einen Netzwerkpfad zwischen den beiden Teilnehmern:

const pc = new RTCPeerConnection({
  iceServers: [{ urls: "stun:stun.l.google.com:19302" }]
});
stream.getTracks().forEach(track => pc.addTrack(track, stream));

Die STUN-Server helfen dabei, die eigene öffentliche Adresse hinter einem NAT-Router herauszufinden. Klappt keine direkte Verbindung, springt ein TURN-Server als Relay ein – das ist der einzige Teil einer WebRTC-Infrastruktur, der nennenswert Betriebskosten verursacht.

Baustein 3: Signaling – der Teil, den du selbst baust

Der häufigste Aha-Moment beim Lernen von WebRTC: Der Verbindungsaufbau selbst ist nicht Teil des Standards. Die beiden Browser müssen sich Angebot und Antwort (SDP-Beschreibungen) sowie ICE-Kandidaten zuschicken – über welchen Kanal, ist dir überlassen. In der Praxis nimmt man fast immer einen kleinen WebSocket-Server:

// Anrufer
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
signaling.send({ type: "offer", sdp: offer });

// Angerufener
await pc.setRemoteDescription(offer);
const answer = await pc.createAnswer();
await pc.setLocalDescription(answer);
signaling.send({ type: "answer", sdp: answer });

Sobald beide Seiten die Beschreibungen ausgetauscht haben und ein ICE-Kandidatenpaar funktioniert, fließen die Medien direkt zwischen den Browsern – der Signaling-Server ist ab dann arbeitslos.

Bonus: der DataChannel

WebRTC kann mehr als Audio und Video. Über pc.createDataChannel("chat") bekommst du einen bidirektionalen Kanal für beliebige Daten – mit einer API, die sich anfühlt wie ein WebSocket, aber Peer-to-Peer läuft. Das eignet sich für Chat neben dem Videobild, Dateiübertragungen oder Spielzustände mit niedriger Latenz.

Wo die Reise hingeht

Ein Minimal-Setup – zwei Browsertabs, ein WebSocket-Server mit zwanzig Zeilen Node.js – ist an einem Nachmittag gebaut und das beste Lernprojekt, um Offer/Answer und ICE wirklich zu verstehen. Danach lohnt der Blick auf Bibliotheken wie mediasoup oder LiveKit, sobald mehr als zwei Teilnehmer in eine Konferenz sollen, denn dann braucht es Media-Server-Architekturen (SFUs).

Und wenn du das Gelernte einordnen willst: Der erwähnte Überblicksartikel auf voip-basiswissen.de zeigt schön, wie genau diese Technik heute in Browser-Telefonie, Kundenservice-Widgets und Videosprechstunden steckt – alles Anwendungen, die du mit den Bausteinen aus diesem Artikel selbst nachbauen kannst.