getByJanusId($janusRoomId); if (!$room) { sfuJsonErr('room not found', 404); } /* Create a fresh Janus session + handle for this participant */ $sid = $janus->createSession(); if (!$sid) { sfuJsonErr('Janus session failed'); } $hid = $janus->attachVideoRoom($sid); if (!$hid) { sfuJsonErr('Janus attach failed'); } /* Send join + offer to Janus */ $joinBody = [ 'request' => 'join', 'room' => $janusRoomId, 'ptype' => $role === 'publisher' ? 'publisher' : 'subscriber', 'display' => $user['email'] ?? 'anon', ]; $resp = $janus->sendJsep($sid, $hid, $joinBody, [ 'type' => $jsep['type'], 'sdp' => $jsep['sdp'], ]); /* Record participant in DB */ $participantId = $repo->joinRoom( (int) $room['id'], (int) $user['id'], $hid, $role ); /* Return negotiated JSEP answer + WS connection details */ $answer = $resp['jsep'] ?? null; sfuJsonOk([ 'session_id' => $sid, 'handle_id' => $hid, 'participant_id' => $participantId, 'jsep' => $answer, 'ws_url' => '/app/androidcast_project/sfu/ws', ]);