laravel-webrtc/README.md

99 lines
5.2 KiB
Markdown

[![Blax Software OSS](https://raw.githubusercontent.com/blax-software/laravel-workkit/master/art/oss-initiative-banner.svg)](https://github.com/blax-software)
# Laravel WebRTC
[![PHP Version](https://img.shields.io/badge/php-%5E8.1-blue?style=flat-square)](https://php.net)
[![Laravel](https://img.shields.io/badge/laravel-10.x--12.x-orange?style=flat-square)](https://laravel.com)
[![Built on](https://img.shields.io/badge/on-reactphp--kernel-4b275f?style=flat-square)](https://github.com/blax-software/reactphp-kernel)
[![Tests](https://img.shields.io/badge/tests-8%20passing-success?style=flat-square)](#testing)
[![Assertions](https://img.shields.io/badge/assertions-18-blue?style=flat-square)](#testing)
[![License](https://img.shields.io/badge/license-MIT-green?style=flat-square)](LICENSE)
WebRTC for Laravel on the shared [`reactphp-kernel`](https://github.com/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.
## Features
- 🎙️ **Record / intercept / log** — the engine terminates media server-side, so every participant's audio (human or AI) can be captured
- 🤖 **AI realtime, provider hidden** — bridge a caller to an external realtime model (e.g. OpenAI Realtime) over a server-side socket; the browser only ever talks to *you*, and the model is a config swap
- 👥 **Party-to-party & group calls** — instructor↔student, controller↔pilot, guest↔admin are just peers the engine routes between
- 🧩 **On the shared kernel** — signaling runs on `reactphp-kernel` alongside your WebSockets, one process, one loop
- 🔌 **Pluggable `MediaEngine`**`NullMediaEngine` for signaling-only dev; `Str0mMediaEngine` for the real Rust-backed media
- 🦀 **Rust media core**`str0m` (sans-IO WebRTC) via `ext-php-rs`, shipped in `rust/`
- 🎛️ **Transport-agnostic signaling** — route browser frames from this package's raw server or from `laravel-websockets` into the same handler
## Installation
```bash
composer require blax-software/laravel-webrtc
php artisan vendor:publish --tag="webrtc-config"
```
It depends on [`blax-software/reactphp-kernel`](https://github.com/blax-software/reactphp-kernel), resolved from git.blax.at via the `repositories` entry in `composer.json`.
## Quick Start
Run the signaling server (on the shared kernel):
```bash
php artisan webrtc:serve
```
With the default `NullMediaEngine`, signaling runs and the engine refuses `offer()` loudly. Build the Rust core (see [`rust/README.md`](rust/README.md)) and switch the engine for real calls:
```dotenv
WEBRTC_MEDIA_ENGINE="Blax\WebRtc\Media\Str0mMediaEngine"
```
### Signaling wire shape (newline-delimited JSON)
```jsonc
{ "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 the built-in raw `SignalingServer` today, or from the `laravel-websockets` WS transport (for browsers) later, without changing the media wiring.
## Configuration
`config/webrtc.php` covers the signaling bind (`host`/`port`/`tls`), the `media_engine` binding, `recording` disk/path, advertised `ice_servers`, and the external `bridge` (e.g. OpenAI model + key). Swapping the realtime model — or the whole provider — is a server-side config change the browser never sees.
## Status
**MVP scaffold.** Signaling + the engine abstraction are real, tested, and runnable with `NullMediaEngine`; the `Str0mMediaEngine` + `rust/` core are the seam to build next. This is the WebRTC half of the blax realtime stack.
## Architecture
```
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/)
```
## Testing
```bash
composer install
composer test
```
The signaling router and engines are unit-tested against a fake media engine — no browser, sockets, or external services required.
## License
MIT. See [LICENSE](LICENSE).
## Star History
<a href="https://www.star-history.com/?repos=blax-software%2Flaravel-webrtc&type=date&legend=top-left">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=blax-software/laravel-webrtc&type=date&theme=dark&legend=top-left" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=blax-software/laravel-webrtc&type=date&legend=top-left" />
<img alt="Star History Chart" src="https://api.star-history.com/chart?repos=blax-software/laravel-webrtc&type=date&legend=top-left" />
</picture>
</a>