2026-07-07 11:07:59 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
feat: WebRTC MVP to Blax standard (namespace, README, tests, scaffolding)
- Rename namespace BlaxSoftware\LaravelWebRtc -> Blax\WebRtc (house standard) +
update kernel imports to Blax\ReactPhpKernel
- README rewritten to the Blax OSS package principles: OSS banner, title+badges,
emoji feature list, quick start, wire shape, config, architecture, star history
- Add PHPUnit suite (8 tests / 18 assertions, green): SignalingHandler routing
(offer/ice/record/connect/bridge/close/error paths via a fake engine) +
NullMediaEngine behaviour
- Add pint.json (laravel preset, applied), composer scripts, .gitattributes,
test.sh (nix), CHANGELOG
- Verified end-to-end: composer install resolves blax-software/reactphp-kernel
from Forgejo VCS and the suite runs green on it
rel learn-atc #1055 #1051 #1019
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 11:28:49 +00:00
|
|
|
namespace Blax\WebRtc\Contracts;
|
2026-07-07 11:07:59 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The media backend for a WebRTC call.
|
|
|
|
|
*
|
|
|
|
|
* PHP (this package) owns SIGNALING + orchestration; the MediaEngine owns the
|
|
|
|
|
* real-time media path (ICE, DTLS, SRTP, RTP, Opus — the per-20ms DSP). The
|
|
|
|
|
* production engine (Str0mMediaEngine) delegates that to a Rust core (str0m,
|
|
|
|
|
* sans-IO) exposed to PHP via ext-php-rs, so the timing-critical work never runs
|
|
|
|
|
* in PHP itself. See the package `rust/` directory.
|
|
|
|
|
*
|
|
|
|
|
* Because the engine terminates media server-side, it is also the single place
|
|
|
|
|
* that can:
|
|
|
|
|
* - RECORD each participant's audio (startRecording),
|
|
|
|
|
* - BRIDGE a participant to an external realtime model, hiding the provider
|
|
|
|
|
* (bridge — e.g. OpenAI Realtime over a WebSocket the browser never sees),
|
|
|
|
|
* - route audio between participants for party-to-party / group calls.
|
|
|
|
|
*/
|
|
|
|
|
interface MediaEngine
|
|
|
|
|
{
|
|
|
|
|
/** Human-readable engine id (diagnostics). */
|
|
|
|
|
public function name(): string;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Accept a browser's SDP offer for a peer and return the SDP answer. The
|
|
|
|
|
* engine sets up the peer connection and begins ICE.
|
|
|
|
|
*
|
|
|
|
|
* @param string $peerId caller-assigned id, unique within a room/call
|
|
|
|
|
* @param string $sdpOffer the browser's offer SDP
|
feat: WebRTC MVP to Blax standard (namespace, README, tests, scaffolding)
- Rename namespace BlaxSoftware\LaravelWebRtc -> Blax\WebRtc (house standard) +
update kernel imports to Blax\ReactPhpKernel
- README rewritten to the Blax OSS package principles: OSS banner, title+badges,
emoji feature list, quick start, wire shape, config, architecture, star history
- Add PHPUnit suite (8 tests / 18 assertions, green): SignalingHandler routing
(offer/ice/record/connect/bridge/close/error paths via a fake engine) +
NullMediaEngine behaviour
- Add pint.json (laravel preset, applied), composer scripts, .gitattributes,
test.sh (nix), CHANGELOG
- Verified end-to-end: composer install resolves blax-software/reactphp-kernel
from Forgejo VCS and the suite runs green on it
rel learn-atc #1055 #1051 #1019
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 11:28:49 +00:00
|
|
|
* @return string the answer SDP to send back through signaling
|
2026-07-07 11:07:59 +00:00
|
|
|
*/
|
|
|
|
|
public function offer(string $peerId, string $sdpOffer): string;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Feed a trickle-ICE candidate received from the browser for a peer.
|
|
|
|
|
*
|
|
|
|
|
* @param array<string,mixed> $candidate {candidate, sdpMid, sdpMLineIndex}
|
|
|
|
|
*/
|
|
|
|
|
public function addIceCandidate(string $peerId, array $candidate): void;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Start recording a peer's inbound audio to $path (e.g. an Opus/WAV file the
|
|
|
|
|
* app then attaches to a transmission row).
|
|
|
|
|
*/
|
|
|
|
|
public function startRecording(string $peerId, string $path): void;
|
|
|
|
|
|
|
|
|
|
/** Stop an in-progress recording for a peer (if any). */
|
|
|
|
|
public function stopRecording(string $peerId): void;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Route a peer's audio to/from another peer (party-to-party / group calls).
|
|
|
|
|
* For an N-party room this is called per pair the engine must forward.
|
|
|
|
|
*/
|
|
|
|
|
public function connectPeers(string $peerA, string $peerB): void;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Bridge a peer to an external realtime endpoint (e.g. OpenAI Realtime),
|
|
|
|
|
* hiding the provider from the browser. Options are engine-specific
|
|
|
|
|
* (model, voice, instructions, api credentials handle, ...).
|
|
|
|
|
*
|
|
|
|
|
* @param array<string,mixed> $options
|
|
|
|
|
*/
|
|
|
|
|
public function bridge(string $peerId, array $options): void;
|
|
|
|
|
|
|
|
|
|
/** Close and clean up a peer (stops recording/bridging, frees the RTC state). */
|
|
|
|
|
public function close(string $peerId): void;
|
|
|
|
|
}
|