@lunionlab/meet-flutter (lunionmeet_flutter)
SDK Flutter de lunion.meet : ajoutez des appels audio et vidéo temps réel à votre application Flutter (iOS, Android, web ; desktop macOS/Linux) en quelques lignes.
Comme sur le web, le principe est en deux temps :
- Votre serveur crée une salle et émet un jeton de connexion avec
@lunionlab/meet-server-sdk(createRoompuiscreateToken). - Votre app Flutter rejoint la salle avec ce jeton via
LunionRoom.
Le jeton est toujours émis côté serveur : votre clé d'API ne quitte jamais votre backend.
Installation
# pubspec.yaml
dependencies:
lunionmeet_flutter: ^1.2.0
1.2.0 :
RTCPeerConnectionstandard viaflutter_webrtc(^0.12). Android, iOS, Windows et desktop sont pris en charge (voir Notes).
Permissions
Android : 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" />
iOS : ios/Runner/Info.plist
<key>NSCameraUsageDescription</key>
<string>Pour les appels vidéo</string>
<key>NSMicrophoneUsageDescription</key>
<string>Pour les appels audio</string>
Desktop (Windows, macOS, Linux) : sur Windows et Linux, rien à déclarer. Sur macOS, ajoutez les
entitlements caméra et micro dans macos/Runner/*.entitlements :
<key>com.apple.security.device.camera</key>
<true/>
<key>com.apple.security.device.audio-input</key>
<true/>
Utilisation
import 'package:flutter/material.dart';
import 'package:lunionmeet_flutter/lunionmeet_flutter.dart';
class CallScreen extends StatefulWidget {
const CallScreen({super.key, required this.url, required this.room, required this.token});
final String url; // access.url (renvoyé par votre serveur)
final String room; // access.room
final String token; // access.token
@override
State<CallScreen> createState() => _CallScreenState();
}
class _CallScreenState extends State<CallScreen> {
late final LunionRoom _room = LunionRoom(
sfuUrl: widget.url,
room: widget.room,
name: 'Awa',
token: widget.token,
);
@override
void initState() {
super.initState();
_room.connect();
}
@override
void dispose() {
_room.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return ListenableBuilder(
listenable: _room,
builder: (context, _) => Scaffold(
body: GridView.count(
crossAxisCount: 2,
children: [
LunionVideoView(stream: _room.localStream, mirror: true),
for (final p in _room.participants)
LunionVideoView(stream: p.stream),
],
),
bottomNavigationBar: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
IconButton(
icon: Icon(_room.micEnabled ? Icons.mic : Icons.mic_off),
onPressed: _room.toggleMic,
),
IconButton(
icon: Icon(_room.cameraEnabled ? Icons.videocam : Icons.videocam_off),
onPressed: _room.toggleCamera,
),
IconButton(
icon: const Icon(Icons.call_end, color: Colors.red),
onPressed: () => _room.leave(),
),
],
),
),
);
}
}
Récupérer un jeton (côté serveur, Node)
import { RoomServiceClient } from "@lunionlab/meet-server-sdk";
const rooms = new RoomServiceClient("https://meet.lunion-lab.com/api/v1", process.env.LUNION_API_KEY!);
const room = await rooms.createRoom("Réunion produit");
const access = await rooms.createToken(room.slug, "user-42", { name: "Awa" });
// → renvoyez access.url, access.room, access.token à votre app Flutter
Chiffrement de bout en bout (E2EE)
Chiffrez le média par frame (AES-GCM) avec une clé partagée uniquement entre les pairs : le SFU relaie de l'opaque, la clé ne transite jamais par le serveur. Établissez-la hors-bande (fragment d'URL, QR…) et donnez la même clé à tous les participants.
final key = LunionE2ee.fromBase64url('Vk9...'); // 256 bits, partagés hors-bande
final room = LunionRoom(
sfuUrl: url, room: room, name: 'Awa', token: token,
e2ee: key,
);
Repose sur le FrameCryptor natif de flutter_webrtc. À valider sur appareil (tous les pairs
doivent partager la clé). Le SDK React Native ne propose pas encore l'E2EE (limite de
react-native-webrtc standard).
Nouveautés 1.2
Partage d'écran fiabilisé : stopScreenShare() libère réellement la capture
(ReplayKit/MediaProjection) et l'arrêt depuis le bandeau système est capté automatiquement ;
leave() et la reconnexion réseau ne laissent plus de capture orpheline.
Rappel 1.1 : reconnexion réseau auto (reconnect) · réception de la modération
(autoApplyModeration, onModerated) · locuteur actif (activeSpeaker) · enregistrement
(startRecording/stopRecording, onRecordingStatus) · mode récepteur pur (receiveOnly) ·
bascule caméra (switchCamera) · qualité par couche (setVideoLayerPolicy) · E2EE (e2ee).
Détails : CHANGELOG.
API
| Élément | Rôle |
|---|---|
LunionRoom |
Contrôleur de salle (ChangeNotifier) : connect(), localStream, participants, toggleMic(), toggleCamera(), switchCamera(), shareScreen()/stopScreenShare()/isScreenSharing, sendChat(), leave(). |
RemoteParticipant |
id, name, stream (flux audio + vidéo). |
RoomStatus |
idle · connecting · connected · reconnecting · error (via room.status). |
LunionE2ee · LunionReconnectConfig · LunionVideoLayer |
Configs : E2EE, reconnexion, qualité par couche. |
LunionVideoView |
Widget d'affichage d'un MediaStream. |
LunionSignaling |
Client de signalisation bas niveau (usage avancé : modération, enregistrement…). |
Partage d'écran
shareScreen() / stopScreenShare() fonctionnent tels quels sur desktop et web. Sur
Android/iOS, le partage exige une configuration native de l'app hôte (MediaProjection +
service au premier plan ; Broadcast Upload Extension + App Group). Guide complet :
docs/SCREEN-SHARE-NATIVE.md
— et des fichiers prêts à copier (manifeste Android, SampleHandler.swift, Info.plist) dans
docs/screen-share-native/.
L'arrêt depuis le bandeau système est capté automatiquement (track.onEnded →
stopScreenShare()), et depuis la 1.3.0 le partage survit à une coupure réseau (capture
ré-attachée et ré-étiquetée, sans nouvelle demande de consentement).
Notes
- Repose sur
flutter_webrtc(^0.12) enRTCPeerConnectionstandard. - Le protocole de signalisation est identique à celui du SDK web
@lunionlab/meet-client-js. - Compilez et testez dans un projet Flutter réel (caméra/micro requis).
Libraries
- lunionmeet_flutter
- SDK Flutter de lunion.meet — appels audio et vidéo temps réel sur le SFU
(
RTCPeerConnectionstandard viaflutter_webrtc).