lunionmeet_flutter 0.1.1 copy "lunionmeet_flutter: ^0.1.1" to clipboard
lunionmeet_flutter: ^0.1.1 copied to clipboard

SDK Flutter de lunion.meet — appels audio et vidéo temps réel à intégrer dans votre application Flutter (iOS, Android, web). Se connecte au SFU mediasoup via un jeton émis par votre serveur (@lunionla [...]

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:lunionmeet_flutter/lunionmeet_flutter.dart';

void main() => runApp(const ExampleApp());

class ExampleApp extends StatelessWidget {
  const ExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'lunion.meet',
      theme: ThemeData.dark(useMaterial3: true),
      home: const JoinScreen(),
    );
  }
}

/// Saisie des paramètres renvoyés par votre serveur (access.url / room / token).
class JoinScreen extends StatefulWidget {
  const JoinScreen({super.key});

  @override
  State<JoinScreen> createState() => _JoinScreenState();
}

class _JoinScreenState extends State<JoinScreen> {
  final _url = TextEditingController(text: 'wss://visio.lunion-lab.com/sfu');
  final _room = TextEditingController();
  final _token = TextEditingController();
  final _name = TextEditingController(text: 'Awa');

  void _join() {
    if (_room.text.trim().isEmpty) return;
    Navigator.of(context).push(MaterialPageRoute(
      builder: (_) => CallScreen(
        url: _url.text.trim(),
        room: _room.text.trim(),
        token: _token.text.trim(),
        name: _name.text.trim().isEmpty ? 'Invité' : _name.text.trim(),
      ),
    ));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Rejoindre une réunion')),
      body: Padding(
        padding: const EdgeInsets.all(20),
        child: ListView(
          children: [
            TextField(controller: _name, decoration: const InputDecoration(labelText: 'Votre nom')),
            const SizedBox(height: 12),
            TextField(controller: _url, decoration: const InputDecoration(labelText: 'URL du SFU (access.url)')),
            const SizedBox(height: 12),
            TextField(controller: _room, decoration: const InputDecoration(labelText: 'Salle (access.room)')),
            const SizedBox(height: 12),
            TextField(controller: _token, decoration: const InputDecoration(labelText: 'Jeton (access.token)')),
            const SizedBox(height: 24),
            FilledButton(onPressed: _join, child: const Text('Rejoindre')),
          ],
        ),
      ),
    );
  }
}

class CallScreen extends StatefulWidget {
  const CallScreen({
    super.key,
    required this.url,
    required this.room,
    required this.token,
    required this.name,
  });

  final String url;
  final String room;
  final String token;
  final String name;

  @override
  State<CallScreen> createState() => _CallScreenState();
}

class _CallScreenState extends State<CallScreen> {
  late final LunionRoom _room = LunionRoom(
    sfuUrl: widget.url,
    room: widget.room,
    name: widget.name,
    token: widget.token.isEmpty ? null : widget.token,
  );

  @override
  void initState() {
    super.initState();
    _room.connect().catchError((_) {});
  }

  @override
  void dispose() {
    _room.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return ListenableBuilder(
      listenable: _room,
      builder: (context, _) {
        final tiles = <Widget>[
          _Tile(stream: _room.localStream, label: '${widget.name} (vous)', mirror: true),
          for (final p in _room.participants) _Tile(stream: p.stream, label: p.name),
        ];
        return Scaffold(
          body: SafeArea(
            child: _room.status == RoomStatus.connecting
                ? const Center(child: CircularProgressIndicator())
                : GridView.count(
                    crossAxisCount: 2,
                    childAspectRatio: 3 / 4,
                    padding: const EdgeInsets.all(8),
                    mainAxisSpacing: 8,
                    crossAxisSpacing: 8,
                    children: tiles,
                  ),
          ),
          bottomNavigationBar: BottomAppBar(
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              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.redAccent),
                  onPressed: () {
                    _room.leave();
                    Navigator.of(context).pop();
                  },
                ),
              ],
            ),
          ),
        );
      },
    );
  }
}

class _Tile extends StatelessWidget {
  const _Tile({required this.stream, required this.label, this.mirror = false});
  final dynamic stream;
  final String label;
  final bool mirror;

  @override
  Widget build(BuildContext context) {
    return ClipRRect(
      borderRadius: BorderRadius.circular(16),
      child: Stack(
        fit: StackFit.expand,
        children: [
          Container(color: Colors.black26),
          LunionVideoView(stream: stream, mirror: mirror),
          Positioned(
            left: 8,
            bottom: 8,
            child: Container(
              padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
              decoration: BoxDecoration(
                color: Colors.black54,
                borderRadius: BorderRadius.circular(8),
              ),
              child: Text(label, style: const TextStyle(fontSize: 12)),
            ),
          ),
        ],
      ),
    );
  }
}
0
likes
0
points
30
downloads

Publisher

unverified uploader

Weekly Downloads

SDK Flutter de lunion.meet — appels audio et vidéo temps réel à intégrer dans votre application Flutter (iOS, Android, web). Se connecte au SFU mediasoup via un jeton émis par votre serveur (@lunionlab/meet-server-sdk).

Homepage
Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter, flutter_webrtc, mediasoup_client_flutter, web_socket_channel

More

Packages that depend on lunionmeet_flutter