splive 2.0.2
splive: ^2.0.2 copied to clipboard
Flutter package for Specular.Live voice rooms with LiveKit voice, realtime room events, chat and microphone and speaker controls.
splive #
Flutter package for adding live voice rooms to your app with Specular.Live: realtime room events and chat over a WebSocket, and voice over LiveKit, with microphone and speaker controls.
You pay only for the voice minutes you use. See the pricing and the full quick start.
How it works #
your Flutter app ──(1) join request──▶ YOUR backend
│ (2) X-Specular-Key (server secret)
▼
Specular.Live
│ (3) short-lived tokens
your Flutter app ◀──────────────────────────┘
│ (4) connect with the tokens using this package
▼
voice room
- Your API key never goes into the app. Your backend keeps it and asks Specular.Live for a short-lived session for each user who wants to join.
- This package connects the app using those short-lived tokens.
Install #
dependencies:
splive: ^2.0.2
flutter pub get
Developer accounts, projects and API keys are managed in your developer dashboard. New verified accounts receive free trial minutes.
Connect to a room #
1. On your backend, request a session. Full details are in the quick start.
curl -X POST 'https://specular.live/api/developer/v1/voice/sessions' \
-H 'Accept: application/json' -H 'Content-Type: application/json' \
-H 'X-Specular-Key: YOUR_SERVER_KEY' \
-d '{"group_uuid":"...","room_uuid":"...","participant_id":"your-user-id","display_name":"Sara","can_publish":true}'
Return only the tokens from the answer to your app.
2. In your Flutter app:
import 'package:splive/splive.dart';
final sdk = SpliveSdk();
// 'session' is the JSON your backend returned.
await sdk.connectRoomSocket(
websocketUrl: session['websocket_url'],
roomId: session['websocket_room_id'],
token: session['websocket_token'],
);
await sdk.connect(SpliveSessionConfig(
serverUrl: session['media_url'],
accessToken: session['media_token'],
roomId: session['websocket_room_id'],
userId: currentUserId,
displayName: currentDisplayName,
));
await sdk.enableMicrophone();
Session tokens are short-lived (15 minutes by default). Ask your backend for a new one when it expires.
3. When the user leaves:
await sdk.disconnectRoomSocket();
await sdk.disconnect();
await sdk.dispose(); // when the SDK object itself is no longer needed
Voice #
| Member | What it does |
|---|---|
enableMicrophone(), disableMicrophone(), toggleMicrophone() |
Control your microphone |
isMicrophoneEnabled |
Whether your microphone is on |
setSpeakerOutput(bool) |
Switch speaker output |
participants |
Stream<List<SpliveParticipant>> of who is in the room and who is speaking |
currentParticipants() |
The current list |
connectionStates, connectionState, isConnected |
Voice connection state (connecting, connected, reconnecting, ...) |
mediaEvents |
Voice events such as reconnecting and active speakers |
sdk.participants.listen((list) {
for (final p in list) {
print('${p.displayName} speaking: ${p.isSpeaking}');
}
});
sdk.connectionStates.listen((state) {
if (state == SpliveConnectionState.reconnecting) {
// show a "reconnecting…" banner
}
});
Realtime events and chat #
| Member | What it does |
|---|---|
roomEvents |
Stream<Map<String, dynamic>> of every realtime room event |
roomMessages |
Stream<RoomChatMessage> of chat messages |
sendRoomMessage(roomId:, message:) |
Send a text message |
sendRoomEmoji(roomId:, emoji:) |
Send an emoji |
sendRoomEvent(type:, data:) |
Send your own event to the room |
isRoomSocketConnected |
Whether the realtime connection is open |
sdk.roomMessages.listen((message) => print(message));
await sdk.sendRoomMessage(roomId: session['websocket_room_id'], message: 'Hello!');
await sdk.sendRoomEmoji(roomId: session['websocket_room_id'], emoji: '🎉');
Use sendRoomEvent for anything specific to your app (game moves, reactions,
gift animations). The package only carries the events; what they mean is up
to your app.
Android and iOS setup #
Android — in android/app/src/main/AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
To keep a room's audio going when the app is in the background, run an Android
foreground service (for example with the flutter_foreground_task package).
iOS — in ios/Runner/Info.plist:
<key>NSMicrophoneUsageDescription</key>
<string>Voice rooms need your microphone.</string>
<key>UIBackgroundModes</key>
<array><string>audio</string></array>
Errors #
Failures throw SpliveException (or a StateError / ArgumentError for
missing arguments). Common causes when getting a session from your backend:
| Response | Meaning |
|---|---|
401 |
The key is missing, wrong or revoked |
402 developer_prepaid_balance_exhausted |
Your voice minutes are used up |
429 developer_concurrency_limit_reached |
Too many people connected at once for this environment; retry shortly |
503 developer_capacity_reached |
The platform is at capacity; retry shortly |
What this package does not do #
It is a transport for voice and realtime events. Accounts, payments, wallets, gifts, moderation rules and your app's own features belong in your app and your backend.
More #
- Quick start
- Pricing
- Changelog
License #
See LICENSE.