speakpro_meet_flutter_sdk 1.0.0
speakpro_meet_flutter_sdk: ^1.0.0 copied to clipboard
Flutter SDK for Speak Pro - A comprehensive video conferencing solution
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:speakpro_meet_flutter_sdk/speakpro_meet_flutter_sdk.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Speak Pro Meet Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Speak Pro Meet Example'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final TextEditingController _roomController = TextEditingController();
final TextEditingController _serverUrlController = TextEditingController();
final TextEditingController _displayNameController = TextEditingController();
final TextEditingController _emailController = TextEditingController();
bool _isAudioMuted = false;
bool _isVideoMuted = false;
final List<String> _participants = [];
@override
void initState() {
super.initState();
_roomController.text = 'SpeakProRoom${DateTime.now().millisecondsSinceEpoch}';
_serverUrlController.text = 'https://meet.speakpro.com';
_displayNameController.text = 'Flutter User';
_emailController.text = '[email protected]';
}
@override
void dispose() {
_roomController.dispose();
_serverUrlController.dispose();
_displayNameController.dispose();
_emailController.dispose();
super.dispose();
}
void _joinMeeting() {
final speakProMeet = SpeakProMeet();
final options = SpeakProMeetConferenceOptions(
serverURL: _serverUrlController.text.isNotEmpty ? _serverUrlController.text : null,
room: _roomController.text,
configOverrides: {
'startWithAudioMuted': _isAudioMuted,
'startWithVideoMuted': _isVideoMuted,
'subject': 'Speak Pro Meeting with Flutter',
},
featureFlags: {
'unsaferoomwarning.enabled': false,
'welcomepage.enabled': false,
},
userInfo: SpeakProMeetUserInfo(
displayName: _displayNameController.text,
email: _emailController.text,
),
);
final listener = SpeakProMeetEventListener(
conferenceJoined: (url) {
debugPrint('Conference joined: $url');
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Conference joined!')),
);
},
conferenceTerminated: (url, error) {
debugPrint('Conference terminated: $url, error: $error');
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Conference ended: ${error ?? 'No error'}')),
);
},
conferenceWillJoin: (url) {
debugPrint('Conference will join: $url');
},
participantJoined: (email, name, role, participantId) {
debugPrint('Participant joined: $name ($email) - $role - $participantId');
setState(() {
_participants.add('$name ($email)');
});
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('$name joined the meeting')),
);
},
participantLeft: (participantId) {
debugPrint('Participant left: $participantId');
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('A participant left the meeting')),
);
},
audioMutedChanged: (muted) {
debugPrint('Audio muted changed: $muted');
setState(() {
_isAudioMuted = muted;
});
},
videoMutedChanged: (muted) {
debugPrint('Video muted changed: $muted');
setState(() {
_isVideoMuted = muted;
});
},
endpointTextMessageReceived: (senderId, message) {
debugPrint('Endpoint message from $senderId: $message');
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Message: $message')),
);
},
screenShareToggled: (participantId, sharing) {
debugPrint('Screen share toggled by $participantId: $sharing');
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Screen sharing ${sharing ? 'started' : 'stopped'}')),
);
},
chatMessageReceived: (senderId, message, isPrivate, timestamp) {
debugPrint('Chat message from $senderId: $message (private: $isPrivate)');
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Chat: $message')),
);
},
chatToggled: (isOpen) {
debugPrint('Chat toggled: $isOpen');
},
participantsInfoRetrieved: (participantsInfo) {
debugPrint('Participants info: $participantsInfo');
},
readyToClose: () {
debugPrint('Ready to close');
Navigator.of(context).pop();
},
);
speakProMeet.join(options, listener);
}
void _toggleAudio() {
final speakProMeet = SpeakProMeet();
speakProMeet.setAudioMuted(!_isAudioMuted);
}
void _toggleVideo() {
final speakProMeet = SpeakProMeet();
speakProMeet.setVideoMuted(!_isVideoMuted);
}
void _hangUp() {
final speakProMeet = SpeakProMeet();
speakProMeet.hangUp();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
TextField(
controller: _roomController,
decoration: const InputDecoration(
labelText: 'Room Name',
border: OutlineInputBorder(),
),
),
const SizedBox(height: 16),
TextField(
controller: _serverUrlController,
decoration: const InputDecoration(
labelText: 'Server URL (optional)',
border: OutlineInputBorder(),
),
),
const SizedBox(height: 16),
TextField(
controller: _displayNameController,
decoration: const InputDecoration(
labelText: 'Display Name',
border: OutlineInputBorder(),
),
),
const SizedBox(height: 16),
TextField(
controller: _emailController,
decoration: const InputDecoration(
labelText: 'Email',
border: OutlineInputBorder(),
),
),
const SizedBox(height: 16),
Row(
children: [
Expanded(
child: CheckboxListTile(
title: const Text('Start with audio muted'),
value: _isAudioMuted,
onChanged: (value) {
setState(() {
_isAudioMuted = value ?? false;
});
},
),
),
Expanded(
child: CheckboxListTile(
title: const Text('Start with video muted'),
value: _isVideoMuted,
onChanged: (value) {
setState(() {
_isVideoMuted = value ?? false;
});
},
),
),
],
),
const SizedBox(height: 24),
ElevatedButton(
onPressed: _joinMeeting,
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(vertical: 16),
),
child: const Text('Join Meeting'),
),
const SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton(
onPressed: _toggleAudio,
child: Text(_isAudioMuted ? 'Unmute Audio' : 'Mute Audio'),
),
ElevatedButton(
onPressed: _toggleVideo,
child: Text(_isVideoMuted ? 'Unmute Video' : 'Mute Video'),
),
ElevatedButton(
onPressed: _hangUp,
child: const Text('Hang Up'),
),
],
),
const SizedBox(height: 24),
const Text(
'Participants:',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 8),
Expanded(
child: ListView.builder(
itemCount: _participants.length,
itemBuilder: (context, index) {
return ListTile(
leading: const Icon(Icons.person),
title: Text(_participants[index]),
);
},
),
),
],
),
),
);
}
}