Fix LiveKit connect flow and polish meeting room media UI.
Deploy Ladill Meet / deploy (push) Successful in 1m2s
Deploy Ladill Meet / deploy (push) Successful in 1m2s
Use the official LiveKit PHP SDK for tokens, harden client connect/publish timing, keep the Room outside Alpine reactivity, and replace emoji toolbar controls with synced mic/camera toggles and avatar tiles for audio-only participants. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -2,6 +2,10 @@
|
||||
|
||||
namespace App\Services\Meet\Media;
|
||||
|
||||
use Agence104\LiveKit\AccessToken;
|
||||
use Agence104\LiveKit\AccessTokenOptions;
|
||||
use Agence104\LiveKit\VideoGrant;
|
||||
|
||||
class LiveKitProvider implements MediaProviderInterface
|
||||
{
|
||||
public function createRoom(string $roomName, array $options = []): void
|
||||
@@ -23,25 +27,26 @@ class LiveKitProvider implements MediaProviderInterface
|
||||
$apiKey = (string) config('meet.media.livekit.api_key');
|
||||
$apiSecret = (string) config('meet.media.livekit.api_secret');
|
||||
|
||||
$now = time();
|
||||
$payload = [
|
||||
'iss' => $apiKey,
|
||||
'sub' => $identity,
|
||||
'iat' => $now,
|
||||
'nbf' => $now,
|
||||
'exp' => $now + 3600,
|
||||
'name' => $displayName,
|
||||
'video' => [
|
||||
'roomJoin' => true,
|
||||
'room' => $roomName,
|
||||
'canPublish' => $grants['can_publish'] ?? true,
|
||||
'canSubscribe' => $grants['can_subscribe'] ?? true,
|
||||
'canPublishData' => $grants['can_publish_data'] ?? true,
|
||||
'roomAdmin' => $grants['room_admin'] ?? false,
|
||||
],
|
||||
];
|
||||
$tokenOptions = (new AccessTokenOptions())
|
||||
->setIdentity($identity)
|
||||
->setName($displayName)
|
||||
->setTtl(3600);
|
||||
|
||||
return $this->encodeJwt($payload, $apiSecret);
|
||||
$videoGrant = (new VideoGrant())
|
||||
->setRoomJoin()
|
||||
->setRoomName($roomName)
|
||||
->setCanPublish($grants['can_publish'] ?? true)
|
||||
->setCanSubscribe($grants['can_subscribe'] ?? true)
|
||||
->setCanPublishData($grants['can_publish_data'] ?? true);
|
||||
|
||||
if ($grants['room_admin'] ?? false) {
|
||||
$videoGrant->setRoomAdmin();
|
||||
}
|
||||
|
||||
return (new AccessToken($apiKey, $apiSecret))
|
||||
->init($tokenOptions)
|
||||
->setGrant($videoGrant)
|
||||
->toJwt();
|
||||
}
|
||||
|
||||
public function isConfigured(): bool
|
||||
@@ -55,23 +60,4 @@ class LiveKitProvider implements MediaProviderInterface
|
||||
{
|
||||
return (string) config('meet.media.livekit.url');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $payload
|
||||
*/
|
||||
protected function encodeJwt(array $payload, string $secret): string
|
||||
{
|
||||
$header = $this->base64UrlEncode(json_encode(['alg' => 'HS256', 'typ' => 'JWT'], JSON_THROW_ON_ERROR));
|
||||
$body = $this->base64UrlEncode(json_encode($payload, JSON_THROW_ON_ERROR));
|
||||
$signature = $this->base64UrlEncode(
|
||||
hash_hmac('sha256', "{$header}.{$body}", $secret, true)
|
||||
);
|
||||
|
||||
return "{$header}.{$body}.{$signature}";
|
||||
}
|
||||
|
||||
protected function base64UrlEncode(string $data): string
|
||||
{
|
||||
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user