voltkit_rtc 0.9.11
voltkit_rtc: ^0.9.11 copied to clipboard
Flutter SDK for VoltKit RTC: realtime audio and video rooms, in-room and standalone chat, and live broadcast publishing over WHIP.
example/example.dart
// The three things this package does, in the order most apps meet them.
//
// This file is compiled by `flutter analyze`, so what it shows cannot drift
// from the API. Every token and URL here comes from YOUR backend, which mints
// them with the server SDK -- the API secret never reaches the device.
import 'package:voltkit_rtc/voltkit_rtc.dart';
/// A room: everyone in it can be given the right to speak.
Future<StreamClient> joinRoom({required String wsUrl, required String token}) async {
final client = StreamClient(wsUrl: wsUrl, token: token);
// Wire the events BEFORE connecting: connect() subscribes to everyone who is
// already publishing, and those tracks arrive during the call.
client.onTrack.listen((t) {
// t.stream goes on an RTCVideoRenderer; t.identity says whose it is.
});
client.onMessage.listen((m) {
// Chat rides the room's own connection. Render m.text as text.
});
client.onClosed.listen((reason) {
// Terminal. Leave the screen.
});
final join = await client.connect();
if (join.role.canPublish) {
await client.publish(); // camera + mic, simulcast
}
await client.sendMessage('hello everyone');
return client;
}
/// Chat with no media, for an audience that is only watching.
Future<ChatClient> joinChat({required String wsUrl, required String token}) async {
final chat = ChatClient(wsUrl: wsUrl, token: token);
chat.onMessage.listen((m) {});
// A dropped connection comes back by itself. Fetch what was missed.
chat.onReconnected.listen((_) => chat.getMessages(limit: 50));
final joined = await chat.connect();
// joined.messages is recent history, oldest first.
if (!joined.muted) await chat.sendMessage('first!');
return chat;
}
/// A broadcast: one publisher, an audience of any size.
Future<BroadcastPublisher> goLive({required String whipUrl}) async {
// whipUrl carries the publish token. Treat it like a password.
final publisher = BroadcastPublisher(whipUrl: whipUrl);
publisher.onState.listen((state) {
// connecting -> live; interrupted and failed are worth showing.
});
publisher.onWarning.listen((message) {});
try {
await publisher.start();
} on WhipError catch (e) {
// isRefused: the URL was not accepted. Ask your backend for a new one.
if (!e.isRefused) rethrow;
}
return publisher;
}