deewan 0.2.0
deewan: ^0.2.0 copied to clipboard
Deewan video meetings for Flutter. Embed an end-to-end encrypted meeting in one widget, or build your own interface with every participant feature.
deewan #
Deewan video meetings for Flutter — end-to-end encrypted, in Arabic and English. Two ways in:
| Embed | Your own interface | |
|---|---|---|
| You build | One widget | The whole UI |
| From your server | A join link | A media token |
| Features | All of Deewan's, ready-made | Everything a participant can do, as methods and streams |
| Strict encrypted rooms | Yes | Yes |
flutter pub add deewan
Embed Deewan's meeting #
Your server creates a join link (POST /rooms/{id}/join-links) for the signed-in person
and returns its url.
import 'package:deewan/deewan.dart';
DeewanMeetingView(
joinUrl: url,
onExit: (_) => Navigator.of(context).pop(),
onError: (message) => showError(message),
);
The view only loads https links on deewan.io, grants the camera and microphone only to
the meeting, and never navigates away from Deewan: when the person leaves or the meeting
ends, onExit is called instead.
Your own interface #
Your server calls POST /rooms/{id}/tokens and returns the response.
import 'package:deewan/custom.dart';
final meeting = await DeewanMeeting.join(
MeetingCredentials.fromJson(response),
microphone: true,
camera: true,
);
// meeting.room is a ChangeNotifier: rebuild with ListenableBuilder.
for (final person in meeting.participants) {
final video = meeting.videoTrack(person.id);
if (video != null) VideoTrackRenderer(video);
}
Everything a participant can do #
| You want to… | Call | Listen to |
|---|---|---|
| Camera and microphone | setCamera(on) · setMicrophone(on) |
meeting.room (ChangeNotifier) |
| Chat and reactions | sendMessage(text) · sendReaction(emoji) |
messages · reactions |
| Raise a hand | raiseHand(true) / raiseHand(false) |
handRaised, handRaisedAt |
| Answer a poll | polls() · vote(pollId, optionIds) |
pollChanges |
| Live captions for yourself | setCaptions(true) |
captions |
| Webinar Q&A | ask(text) · voteQuestion(id) · hosts: markQuestion(id, answered: true) |
questionChanges |
| Recording indicator | meeting.recording |
recordingChanges |
| Breakout announcements | — | announcements |
| Strict encryption | exchangeKey() before the token |
securityChanges: the code to compare |
| Leave | leave() |
left (why it ended) |
Each DeewanParticipant has id, name, isSelf, isHost, isCohost, isGuest,
micOn, camOn, isScreenSharing, isSpeaking, handRaised, handRaisedAt,
captionsOn, onStage and isAudience. Participant actions throw DeewanException
with the API's status and code. Host powers stay on your server, through the REST API.
Strict end-to-end encryption #
final key = exchangeKey(); // the private half never leaves the device
// Your server: POST /rooms/{id}/tokens with { "name": …, "exchange_key": key }
final meeting = await DeewanMeeting.join(MeetingCredentials.fromJson(response));
meeting.securityChanges.listen((s) => setState(() => code = s.code));
The code matches every other screen in the meeting, including Deewan's own web and mobile apps.
Permissions #
iOS: NSCameraUsageDescription and NSMicrophoneUsageDescription in Info.plist.
Android: CAMERA, RECORD_AUDIO, MODIFY_AUDIO_SETTINGS and INTERNET.
Security #
- Never put an API key in an app: your server issues the join link or token for the signed-in person and returns only that.
- Media, chat and reactions are encrypted on the device before they are sent; in strict rooms only the people in the meeting hold the key.
- Tokens are only sent over HTTPS/WSS (plain
httpis refused except to localhost).
Links #
- Guide: https://deewan.io/en/docs/mobile-sdks
- API reference: https://deewan.io/en/docs/reference
- Support: support@deewan.io
MIT © Deewan