Lädt...

PHP WebRTC Dokumentation

Komplette WebRTC-Implementierung in reinem PHP für Echtzeitkommunikation ohne externe Server

Reine PHP-Implementierung

Keine externen Abhängigkeiten oder Server erforderlich

Einführung

PHP WebRTC ist eine vollständige Implementierung des WebRTC-Protokolls in reinem PHP. Sie wurde entwickelt, um Echtzeitkommunikation (RTC) für PHP-Anwendungen zu ermöglichen, ohne sich auf externe Server zu verlassen.

Medientransport

Audio-/Videotransport über RTP/SRTP mit vollständiger Codec-Unterstützung

DataChannels

SCTP DataChannels für Echtzeit-Datenaustausch

NAT-Traversal

STUN/TURN-Unterstützung für NAT-Traversal und Konnektivität

Sicherheit

ICE- und DTLS-Verarbeitung mit Verschlüsselungsunterstützung

Perfekt für: PHP-Entwickler, die Peer-to-Peer-Kommunikation in Web-Apps, Signalisierungsservern oder Backend-Diensten mit nativem PHP integrieren möchten.

Anforderungen & Installation

Erforderliche Abhängigkeiten

Um PHP WebRTC zu verwenden, müssen Sie Folgendes installiert haben:

  • Linux (Ubuntu/Debian bevorzugt)
  • Windows-Nutzer: Verwenden Sie WSL oder Docker Desktop
  • macOS-Nutzer: Verwenden Sie einen Emulator wie UTM oder führen Sie das Projekt mit Docker aus
  • PHP 8.4+ mit aktiviertem FFI
  • PHP-Erweiterungen: gmp, protobuf (für RTCSignaling)
  • FFmpeg Shared Libraries (libav*)
  • Opus v1.4
  • libvpx v1.15.0
Hinweis: Native Unterstützung für Windows und macOS ist für kommende Releases geplant (in wenigen Monaten).

Bash-Installationsskript

Erstellen Sie eine Datei mit dem Namen install-deps.sh:

#!/bin/bash
set -e

echo "🔧 Updating system and installing base dependencies..."
apt-get update && apt-get install -y \
    apt-transport-https \
    ca-certificates \
    gnupg \
    autoconf \
    automake \
    build-essential \
    cmake \
    git \
    libtool \
    pkg-config \
    yasm \
    nasm \
    wget \
    unzip \
    curl \
    libzip-dev \
    libgmp-dev \
    libssl-dev \
    libsrtp2-dev \
    libx264-dev \
    libffi-dev \
    libprotobuf-dev \
    php-gmp \
    php-zip \
    php-ffi \
    php-cli \
    php-mbstring \
    php-curl \
    php-xml \
    php-bcmath \
    php-sockets \
    php-pcntl \
    python3 \
    && rm -rf /var/lib/apt/lists/*

echo "✅ Base system dependencies installed."

echo "📦 Installing PHP Protobuf extension..."
pecl install protobuf
echo "extension=protobuf.so" > /etc/php/8.4/cli/conf.d/30-protobuf.ini
echo "✅ Protobuf extension installed and enabled."

echo "⚙️ Enabling PHP FFI..."
echo "ffi.enable=true" > /etc/php/8.4/cli/conf.d/30-ffi.ini
echo "✅ FFI enabled."

echo "🎬 Building and installing FFmpeg 7.1.1..."
cd /tmp
wget https://ffmpeg.org/releases/ffmpeg-7.1.1.tar.bz2
tar xjf ffmpeg-7.1.1.tar.bz2
cd ffmpeg-7.1.1
./configure --enable-shared --enable-gpl --enable-libx264 --enable-libopus --enable-libvpx
make -j$(nproc)
make install
ldconfig
cd /tmp && rm -rf ffmpeg-7.1.1*
echo "✅ FFmpeg 7.1.1 installed."

echo "🎧 Building and installing libopus 1.4..."
cd /tmp
wget https://github.com/xiph/opus/releases/download/v1.4/opus-1.4.tar.gz
tar xzvf opus-1.4.tar.gz
cd opus-1.4
./configure --prefix=/usr/local --enable-shared
make -j$(nproc)
make install
ldconfig
cd /tmp && rm -rf opus-1.4*
echo "✅ libopus 1.4 installed."

echo "🎥 Building and installing libvpx 1.15.0..."
cd /tmp
wget https://github.com/webmproject/libvpx/archive/refs/tags/v1.15.0.tar.gz
tar xzvf v1.15.0.tar.gz
cd libvpx-1.15.0
./configure --prefix=/usr/local --enable-shared --disable-examples
make -j$(nproc)
make install
ldconfig
cd /tmp && rm -rf libvpx-1.15.0*
echo "✅ libvpx 1.15.0 installed."

echo "🎉 All dependencies installed successfully!"

Geben Sie dem Skript Ausführungsrechte und führen Sie es aus:

chmod +x install-deps.sh
./install-deps.sh

Composer-Installation

Installieren Sie PHP WebRTC über Composer:

composer require quasarstream/webrtc

Alternativ können Sie die Abhängigkeit zu Ihrer composer.json-Datei hinzufügen:

{
    "require": {
        "quasarstream/webrtc": "^1.0"
    }
}

RTCPeerConnection Konfiguration

RTCConfiguration Übersicht

Die Klasse RTCConfiguration bietet Optionen zur Konfiguration Ihrer RTCPeerConnection. Dazu gehören STUN-/TURN-Server und optionale TLS-Zertifikats- und Private-Key-Pfade für sichere DTLS-Verbindungen.

use Webrtc\Webrtc\RTCConfiguration;
use Webrtc\ICE\RTCIceServer;

$stunServer = new RTCIceServer();
$stunServer->setUrls(['stun:stun.l.google.com:19302']);

$turnServer = new RTCIceServer();
$turnServer->setUrls(['turn:turn.example.com']);
$turnServer->setUsername('user');
$turnServer->setCredential('pass');
$turnServer->setCredentialType('password');

$config = new RTCConfiguration(
    iceServers: [$stunServer, $turnServer],
    certificatePath: '/etc/ssl/certs/rtc-cert.pem',
    privateKeyPath: '/etc/ssl/private/rtc-key.pem'
);

// You can also construct a default configuration (uses Google's public STUN):
$configuration = new RTCConfiguration();
$pc = new RTCPeerConnection($configuration);

// Or don't pass any variable
$pc = new RTCPeerConnection();

Es gibt auch die Möglichkeit, ein assoziatives Array zur Konfiguration zu übergeben:

use Webrtc\Webrtc\RTCConfiguration;

$pc = new RTCPeerConnection([
    'iceServers' => [
        [
            'urls' => ['stun:stun.l.google.com:19302']
        ],
        [
            'urls' => ['turn:turn.example.com'],
            'username' => 'user',
            'credential' => 'pass',
            'credentialType' => 'password'
        ]
    ],
    'certificatePath' => '/etc/ssl/certs/rtc-cert.pem',
    'privateKeyPath' => '/etc/ssl/private/rtc-key.pem'
]);

RTCPeerConnection

Die Klasse RTCPeerConnection in PHP WebRTC ist das Herzstück der Peer-to-Peer-Kommunikation. Sie verwaltet:

  • ICE-Aushandlung
  • DTLS-Verschlüsselung
  • RTP-Medienübertragung
  • SCTP DataChannel-Kommunikation

Initialisierung

Dies erstellt eine neue WebRTC-Peer-Verbindungsinstanz. Optional können Sie hier ein RTCConfiguration-Objekt übergeben, wenn Sie ICE-Server oder DTLS-Zertifikate anpassen möchten.

$pc = new RTCPeerConnection();

Eingehende DataChannels verarbeiten

$pc->on("datachannel", function (RTCDataChannel $channel) {
    $channel->on("message", function (string $message) use ($channel) {
        $channel->send($message); // Echo the message
    });
});
Hinweis: Wenn der entfernte Peer einen DataChannel erstellt, wird das datachannel-Ereignis ausgelöst. Innerhalb dieses Ereignisses können Sie auf message-Ereignisse lauschen und reagieren. Sie können DataChannels verwenden, um JSON, Binärdaten oder sogar benutzerdefinierte Signalisierungsprotokolle zu senden.

Medienspuren verarbeiten

$pc->on("track", function (MediaStreamTrack $track) use ($pc) {
    $pc->addTrack($track);
});

Wenn ein entfernter Peer eine Medienspur (Audio/Video) hinzufügt, wird das track-Ereignis ausgelöst. Sie können optional $pc->addTrack($track) aufrufen, um es auf Ihrer Seite zu registrieren, oder es an einen MediaStream anhängen.

Aushandlung von Sitzungsbeschreibungen

Das folgende Code-Snippet demonstriert, wie ein eingehendes SDP-Angebot in einer WebRTC-Sitzung mit PHP gehandhabt wird. Es folgt dem Offer/Answer-Austauschmodell des WebRTC-Standards und spiegelt das Verhalten in JavaScript-basierten Implementierungen wider.

$pc->setRemoteDescription($request->getOffer())
    ->then(fn() => $pc->createAnswer())
    ->then(fn(RTCSessionDescription $description) => $pc->setLocalDescription($description))
    ->then(fn() => $request->sendOffer($pc->getLocalDescription()))
    ->catch(fn(Throwable $e) => $request->respondError($e->getMessage(), 400));

Dies führt den klassischen WebRTC-"Answer"-Prozess durch:

  1. Entferntes Angebot festlegen – vom anderen Peer
  2. Antwort erstellen – Ihre SDP-Antwort
  3. Antwort erstellen – Ihre generierte SDP-Antwort
  4. Lokales SDP zurücksenden – z. B. über Ihren Signalisierungsserver
Dies setzt voraus, dass datachannel$request eine Abstraktion in Ihrer App ist, die WebRTC-Angebote/Antworten über HTTP/WebSocket empfängt/sendet.

Zustandsänderungen

Sie können die internen Zustandsübergänge einer WebRTC RTCPeerConnection-Instanz mithilfe von Ereignis-Listenern beobachten. Diese Ereignisse helfen, den Lebenszyklus und den Konnektivitätsstatus der Verbindung zu verfolgen, was für das Debugging und die Diagnose unerlässlich ist.

// state changes trigger
$pc->on("connectionstatechange", function () use ($pc) {
    echo sprintf("connectionstatechange: %s\n", $pc->getConnectionState()->name);
});

$pc->on("iceconnectionstatechange", function () use ($pc) {
    echo sprintf("iceconnectionstatechange: %s\n", $pc->getIceConnectionState()->name);
});

$pc->on("icegatheringstatechange", function () use ($pc) {
    echo sprintf("icegatheringstatechange: %s\n", $pc->getIceGatheringState()->name);
});

$pc->on("signalingstatechange", function () use ($pc) {
    echo sprintf("signalingstatechange: %s\n", $pc->getSignalingState()->name);
});

Dieser Code richtet Ereignis-Listener auf einem WebRTC RTCPeerConnection-Objekt ($pc) ein, um Änderungen in seinen internen Zuständen zu protokollieren. Wenn Zustandsübergänge in der Verbindung (connectionstatechange), der ICE-Verbindung (iceconnectionstatechange), dem ICE-Gathering (icegatheringstatechange) oder der Signalisierung (signalingstatechange) auftreten, werden entsprechende Nachrichten in die Konsole ausgegeben. Dies ist nützlich für das Debugging oder die Beobachtung von Verbindungs-Lebenszyklusereignissen in Echtzeit während einer WebRTC-Sitzung.

Statistiken

WebRTC bietet detaillierte Statistiken über die Methode getStats() – ähnlich der JavaScript WebRTC API – die es Entwicklern ermöglicht, Medienstreams, Transporte und die Leistung der Codierung zu überprüfen.

//Stats
use React\EventLoop\Loop;

$loop = Loop::get();

$lastBytesSent = 0;
$lastBytesReceived = 0;

$loop->addPeriodicTimer(1, function () use ($pc, &$lastBytesSent, &$lastBytesReceived) {
    $stats = $pc->getStats();

    $bytesSent = 0;
    $bytesReceived = 0;

    foreach ($stats->getStats() as $stat) {
//      if ($stat instanceof RTCOutboundRTPStreamStats) {
//          $bytesSent += $stat->bytesSent;
//      }
//
//      if ($stat instanceof RTCInboundRTPStreamStats) {
//          $bytesReceived += $stat->packetsReceived;
//      }

        if ($stat instanceof RTCTransportStats) {
            $bytesSent += $stat->bytesSent;
            $bytesReceived += $stat->bytesReceived;
        }
    }

    echo sprintf(
        "\rUpload Bandwidth: %d Kbps | Download Bandwidth: %d Kbps",
        intval(($bytesSent - $lastBytesSent) / 1024),
        intval(($bytesReceived - $lastBytesReceived) / 1024)
    );

    $lastBytesSent = $bytesSent;
    $lastBytesReceived = $bytesReceived;
});
Tipp: In diesem Beispiel verwenden wir einen periodischen Timer, um wichtige Statistiken aus einer RTCPeerConnection zu sammeln. Insbesondere berechnen wir die aktuelle Upload- und Download-Bandbreite, indem wir die Byte-Anzahlen aus RTCTransportStats summieren. Sie können auch RTCOutboundRTPStreamStats und RTCInboundRTPStreamStats zur Bandbreitenberechnung verwenden. Sie können dies erweitern, um Round-Trip-Zeit, Jitter, Bildraten, Codec-Informationen und Paketverlust zu erfassen, indem Sie andere Statistiktypen wie RTCRemoteInboundRTPStreamStats und RTCRemoteOutboundRTPStreamStats untersuchen.

DataChannel

Wenn Sie die Verbindung initiieren, können Sie auch einen DataChannel vor dem Angebot erstellen:

DataChannel erstellen

$channel = $pc->createDataChannel("chat");

$channel->on("open", function () use ($channel) {
    $channel->send("Hello!");
});

$channel->on("message", function (string $msg) {
    echo "Received: $msg\n";
});
DataChannels bieten eine leistungsstarke Möglichkeit, beliebige Daten zwischen Peers mit geringer Latenz auszutauschen. Sie eignen sich perfekt für Chat-Anwendungen, Spielzustandssynchronisation, Dateiübertragungen und mehr.

Beispiele

Die folgenden Beispiele zeigen, wie PHP WebRTC als Anforderungssteller in einer echten WebRTC-Sitzung mit RTCPeerConnection verwendet wird.

Beispiel-Repository ansehen: https://github.com/PHP-WebRTC/examples

Screenshots

Hauptseite

Hauptseite

Echo-Beispiel

Hinweis: Zusätzliche Beispiele und Updates werden in den kommenden Wochen hinzugefügt.

Kommende und unsere Pläne für die Zukunft

Wir hören hier nicht auf. Wir entwickeln die PHP WebRTC-Pakete aktiv weiter.

Aktuell arbeiten wir privat an einer Selective Forwarding Unit (SFU)-Implementierung und einem Laravel-Paket, das alles bündelt, einschließlich dieses WebRTC-Pakets. Sobald das fertig ist, ist unser Ziel, eine minimale Videokonferenz-Web-App mit Laravel zu erstellen.

Wir verbessern PHP WebRTC ebenfalls aktiv, und in den kommenden Monaten stehen aufregende Updates an! Dazu gehören:

  • Erweiterte Dokumentation und Anleitungen zur Nutzung
  • Mehr Signalisierungsbeispiele (WebSocket, HTTP, UNIX-Sockets)
  • Medienverarbeitungswerkzeuge und Integrationen
  • Performance-Tuning und Benchmarks
  • Fortgeschrittene Themen wie Simulcast, Bundling und Congestion Control

Mitwirken und Zusammenarbeit

Wenn Sie daran interessiert sind, Echtzeitkommunikationstools in PHP zu entwickeln, wie eine Videokonferenz-App, sind Sie herzlich eingeladen, dem Projekt beizutreten. Forken Sie die Repositories, tragen Sie dazu bei und helfen Sie, diese Community wachsen zu lassen.

Bitte beachten Sie: Beiträge sollten sich primär auf die Behebung von Fehlern konzentrieren. Wenn Sie eine neue Funktion oder Methode hinzufügen möchten, muss diese dem Verhalten der ursprünglichen WebRTC API entsprechen. Wenn Sie beispielsweise eine Methode zur RTCPeerConnection-Klasse hinzufügen möchten, sollte sie in der ursprünglichen JavaScript WebRTC API existieren und demselben Namen und Zweck folgen.

Wenn Sie ein Mitwirkender oder Teamkollege werden möchten, würden wir uns freuen, von Ihnen zu hören. Dies ist ein Open-Source-, Non-Profit-Projekt, daher suchen wir hauptsächlich nach leidenschaftlichen Entwicklern.

Sie sollten mindestens ein Projekt haben, das Ihr Wissen und Ihre Fähigkeiten in PHP, Laravel und WebRTC demonstriert (eines davon ist auch ausreichend). Wenn das auf Sie zutrifft, könnte dies ein großartiger Ort sein, um sich zu engagieren.

Kontaktieren Sie uns gerne über dieses Formular mit Ihrem GitHub-Benutzernamen (zum Beispiel: github.com/your-username), und wir werden uns bald bei Ihnen melden.

Über die Git-Historie

Wir haben lange privat (auf unserem Git-Server) an dem WebRTC-Repository und vielen anderen PHP WebRTC-bezogenen Repositories (wie ICE, RTP, RTCP und mehr als 22 weiteren) gearbeitet, bevor wir sie Open Source gemacht haben (Wir haben unsere Pakete erst veröffentlicht, nachdem sie vollständig getestet und gründlich debuggt waren). Ursprünglich gab es eine lange Commit-Historie, die all unsere Arbeit widerspiegelte.

Wir haben uns jedoch entschieden, diese Historie im ersten öffentlichen Commit zu entfernen, um unsere Privatsphäre zu schützen. Die ursprünglichen Commits enthielten Details wie unsere Arbeitszeiten basierend auf den Commit-Zeiten und -Anzahlen, sowie unsere persönlichen E-Mail-Adressen, die wir nicht öffentlich teilen wollten.

Das Entfernen der Historie hilft uns, diese Informationen privat zu halten und etwas sicherer vor potenziellen Sicherheitsrisiken zu sein.

Unterstützen Sie uns

Wenn Sie dieses Projekt nützlich finden, unterstützen Sie uns bitte:

Gemeinsam können wir PHP zu einem erstklassigen Akteur in der Echtzeitkommunikation machen.