2.8 KiB
blax-software/laravel-webrtc
WebRTC for Laravel, built on the shared
blax-software/reactphp-kernel
backbone. PHP owns signaling + orchestration; a pluggable media engine
owns the real-time media (ICE/DTLS/SRTP/RTP/Opus) — with the production engine
backed by a Rust core (str0m) via ext-php-rs, so PHP never runs per-20ms
DSP.
reactphp-kernel shared backbone (loop, IPC, signals)
└─ laravel-webrtc (this) signaling on the kernel
├─ NullMediaEngine signaling-only (dev/tests)
└─ Str0mMediaEngine Rust/str0m core via ext-php-rs (rust/)
What it's for
One media path that terminates server-side unlocks all of:
- Record / intercept / log every participant's audio (human or AI).
- AI realtime, provider hidden — the engine bridges a caller to an external realtime model (e.g. OpenAI Realtime) over a server-side socket; the browser only ever talks to us, and the model is a server-side config swap.
- Party-to-party & group calls — instructor↔student, controller↔pilot, guest↔admin: participants are just peers the engine routes between.
Status
Scaffold. Signaling + the engine abstraction are real and runnable with
NullMediaEngine; the Str0mMediaEngine + rust/ core are the seam to build
next (see rust/README.md). This package is the home for the WebRTC half of the
blax realtime stack (rel learn-atc #1051/#1019).
Install
composer require blax-software/laravel-webrtc:dev-master
php artisan vendor:publish --tag=webrtc-config
It depends on blax-software/reactphp-kernel (resolved from git.blax.at via the
repositories entry in composer.json).
Run
php artisan webrtc:serve # signaling on config(webrtc.host:port)
With NullMediaEngine (default) signaling runs and the media engine refuses
offer() loudly. Build the Rust core and set
WEBRTC_MEDIA_ENGINE=BlaxSoftware\LaravelWebRtc\Media\Str0mMediaEngine for real
calls.
Signaling wire shape (JSON, newline-delimited)
{ "type": "offer", "peer": "p1", "sdp": "..." } // -> { "type": "answer", "peer": "p1", "sdp": "..." }
{ "type": "ice", "peer": "p1", "candidate": {...} } // (no reply)
{ "type": "record", "peer": "p1", "path": "..." } // -> { "type": "ack", ... }
{ "type": "connect", "peer": "p1", "other": "p2" } // party-to-party
{ "type": "bridge", "peer": "p1", "options": {...} } // dial an external realtime model
{ "type": "close", "peer": "p1" }
SignalingHandler is transport-agnostic — feed it frames from this package's raw
SignalingServer today, or from the laravel-websockets WS transport (for
browsers) later, without changing the media wiring.
License
MIT © Blax Software