Skip to content
Live Streaming

Quickstart

Add voxera_live_room_kit to a Flutter app and start a live room.

You need a project with live_stream enabled. If you don't have one, follow Get started first and choose Live Video Streaming. Without it, POST /api/v1/token returns 403 Type 'live_stream' is not enabled for this project.

Install

Add the package to pubspec.yaml:

dependencies:
  voxera_live_room_kit: ^2.1.2

Set up iOS and Android

The kit asks for camera and microphone permissions at runtime, so declare them.

iOS: add this to ios/Runner/Info.plist:

<key>NSCameraUsageDescription</key>
<string>Required to go live</string>
<key>NSMicrophoneUsageDescription</key>
<string>Required to go live</string>

Android: add this to android/app/src/main/AndroidManifest.xml:

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

Open a room

VoxeraLiveRoom(
  appId: '<voxera-app-id>',
  appKey: '<voxera-app-key>', // publishable, no token server needed
  userId: 'user123',
  userName: 'Jane',
  roomId: 'room456',
  roomOwnerId: 'owner789', // only the owner joins as the publishing host
  config: const VoxeraLiveRoomConfig(maxGuestTiles: 3),
);

The owner sees a camera preview and a Go Live button. Everyone else joins as a viewer who can watch and chat. To change that, see autoHostCamera and showGoLiveButton in the configuration.

Set up the audio engine

The native media engine is built once per process, and whatever touches it first decides its audio profile. The kit handles this itself. If your app touches WebRTC before the first room opens, call VoxeraMediaClient.initializeForRoom() first in main(). See Connect and publish.

Make the first join faster

Warm up during app startup, or before the user opens your room list. This doesn't mint a token, request permissions or turn on the camera.

await VoxeraRoomController.warmUp(
  tokenBaseUrl: 'https://stream.zavryn.online',
);

Then start the token request when navigation begins, and pass the same future to the widget:

final controller = VoxeraRoomController()
  ..initApi(appId: appId, appKey: appKey);
final token = controller.generateToken(
  identity: userId,
  roomName: roomId,
  roomOwnerId: roomOwnerId,
  name: userName,
  role: userId == roomOwnerId ? 'host' : 'audience',
);
 
final room = VoxeraLiveRoom(
  controller: controller,
  tokenProvider: () => token,
  appId: appId,
  appKey: appKey,
  userId: userId,
  userName: userName,
  roomId: roomId,
  roomOwnerId: roomOwnerId,
);