utd_live_room_kit 1.4.0
utd_live_room_kit: ^1.4.0 copied to clipboard
LiveKit-based video live room for Flutter: host camera plus up to three guest tiles, go-live requests, host media control, chat, and minimize/PiP.
UTD Live Room Kit #
A Flutter package for building video live-room experiences, powered by LiveKit and the UTD Stream Engine. It puts a host camera on a full-bleed stage with up to 3 invited co-publisher tiles — give it the required data and you get a fully interactive live room with no extra UI code.
The engine treats a live room as the live_stream product type: an unbounded,
seatless stage. There is no seat grid and no participant cap — anyone can
watch. The host invites co-publishers onto the stage (audio/video publish),
while the room owner promotes moderators. The kit only caps how many guest
tiles it draws (maxGuestTiles, default 3); the engine itself is
uncapped.
Roles are server-authoritative. Only the verified room owner joins as the publishing
host; everyone else joins asaudience(watch + chat). The engine clamps any non-owner's claimed role toaudience— a client cannot self-grant publish or moderation. Publishing and moderation are decoupled: being added to the stage grants publish only; being promoted toadmingrants moderation only (admins are never on camera).
Features #
- Drop-in live-room UI — host camera + up to 3 co-publisher video tiles from required data alone.
- Stage flow — the host invites viewers onto the stage to co-publish;
viewers raise-hand (
stage/request) and the host adds them. No server-side queue — a request is a transient_stage_requestnotification to host/admins. - Owner-promoted moderators — the owner promotes configured
adminIdstoadmin(moderate-only, not on camera) via the engine role endpoint. - Host force-control — host can mute/unmute or stop a co-publisher's camera/mic, and remove them from the stage.
- Media controls — microphone & camera with reactive state (Bluetooth-preferring audio routing).
- Real-time chat — data-channel messages with batching and dedup.
- Reconnection — tiered: light sync (<15s), full sync (<60s), default force-exit (>60s).
- Minimize / PiP — minimize to a floating overlay; optional Android OS Picture-in-Picture.
- Video effects — pairs with
utd_video_effects_kitviaUTDLiveRoomConfig.buildVideoProcessor(a LiveKitTrackProcessor) for live filters & beauty effects.
Getting started #
Add the dependency:
dependencies:
utd_live_room_kit: ^1.4.0
Credentials — pass your appKey (no backend required) #
Ship
appId+appKey(the project's publishable app key, from the UTD console). The kit mints tokens directly from the engine withX-App-Key; the engine signs the returned per-useruser_tokenwith the projectserver_secretserver-side, so the secret never ships in the app. The kit uses thatuser_tokenas theAuthorization: Bearerfor all in-room calls. No token server to stand up.appKeycan't sign tokens or call the S2S API and rotates on its own.
import 'package:utd_live_room_kit/utd_live_room_kit.dart';
UTDLiveRoom(
appId: '<utd-app-id>',
appKey: '<utd-app-key>', // publishable; the kit mints tokens itself, no backend needed
userId: 'user123',
userName: 'Jane',
roomId: 'room456',
roomOwnerId: 'owner789',
// Identities the OWNER will promote to `admin` (moderators) once they join.
// Optional. The engine clamps non-owners to `audience`, so these are only
// honored because the owner promotes them server-side after join.
adminIds: const {'mod1', 'mod2'},
config: const UTDLiveRoomConfig(maxGuestTiles: 3),
);
The live room is
type: live_stream. The kit mints its token withtype: live_streamand sends no seat parameters (seat_count,seat_mode,host_seatare ignored for a live stream — the room is uncapped). The project must havelive_streamin itsenabled_typesin the UTD console, otherwisePOST /api/v1/tokenreturns403 "Type 'live_stream' is not enabled for this project". The sameappId/appKeyworks for every product type the project has enabled — the type is a per-request field, not a separate credential.
See the exported API in
lib/utd_live_room_kit.dart — UTDLiveRoom,
UTDRoomController, UTDStageApi, UTDMediaController, UTDChatController, and
the room/role/participant models.
Stage & roles #
A live room has four server-authoritative roles:
| Role | Publishes | Moderates | How you get it |
|---|---|---|---|
host |
✅ | ✅ | The verified room owner (userId == roomOwnerId). Force-upgraded by the engine. |
guest |
✅ | ❌ | Host/admin invites you onto the stage. |
admin |
❌ | ✅ | The owner promotes you (moderate-only, never on camera). |
audience |
❌ | ❌ | Default for everyone non-owner — watch + chat. |
Going on stage (co-publish). A viewer raises their hand
(POST /api/v1/rooms/:name/stage/request), which fires a transient
_stage_request data message to the host/admins (there is no persisted queue).
A host/admin then adds them (.../stage/add → role becomes guest, publish
granted). Removal (.../stage/remove) or self step-down (.../stage/leave)
sends them back to audience. The current publisher set is
GET /api/v1/rooms/:name/stage → { members: [{ identity, name, role }] }, and
roster changes broadcast a _stage_update data message. These endpoints are
live_stream-only (a seated room returns 400).
The kit surfaces the stage through UTDRoomController — inviteToSpeak,
requestToSpeak, approveSpeakerRequest, rejectSpeakerRequest — and the raw
endpoints via controller.stageApi (UTDStageApi).
Promoting a moderator. Moderation uses the owner-only role endpoint
PUT /api/v1/rooms/:name/participants/:identity/role with { role: 'admin' }.
The kit does this for you: pass adminIds (or adminIdsResolver /
adminIdsNow), and the host client promotes those identities as they join via
controller.changeRole. In a stage room this grants moderation but not
publish, and the engine refuses (409) an attempt to add an admin to the
stage — the two capabilities stay disjoint.
maxGuestTilesis a UI-only cap. It sizes the on-screen tile strip (host + N co-publishers); the engine stage itself is unbounded. There is no seat grid — the host video is the full-bleed background and co-publishers are floating tiles above it.
Config #
UTDLiveRoomConfig controls the live experience. Notable fields:
maxGuestTiles(default3) — how many co-publisher tiles to draw (UI cap only; the engine is uncapped).autoHostCamera(defaultfalse) — publish on connect vs. self-preview → "Go Live".showGoLiveButton(defaulttrue) — render the built-in "Go Live" button during host preview, or let the app driveUTDMediaController.goLive.frontCameraOnJoin/mirrorLocalVideo/hostFit/guestFit— camera & video-fit options.buildVideoProcessor— a LiveKitTrackProcessorfactory for live filters & beauty effects (pairs withutd_video_effects_kit).- Section/tile overrides —
headerWidget,messagesWidget,controlsBarWidget,hostTileBuilder,guestTileBuilder,guestTileFooterBuilder,onStageTap.
Requirements #
- A LiveKit server + UTD Stream Engine token endpoint, with
live_streamin the project'senabled_types. - Camera & microphone runtime permissions (handled via
permission_handler).