apars_media 1.0.3
apars_media: ^1.0.3 copied to clipboard
Flutter SDK for Apars Media live classes — exposes the HLS stream URL and real-time chat for students and co-teachers.
import 'package:flutter/material.dart';
import 'package:apars_media/apars_media.dart';
import 'live_class_screen.dart';
void main() {
// Initialize the default SDK instance.
// For multiple clients, create separate AparsMediaSDK instances instead.
AparsMediaSDK.init(
baseUrl: 'https://your-apars-media-server.com',
clientId: 'your_client_id',
authKey: 'your_auth_key',
);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Apars Media',
theme: ThemeData.dark(useMaterial3: true),
home: const JoinScreen(),
);
}
}
class JoinScreen extends StatefulWidget {
const JoinScreen({super.key});
@override
State<JoinScreen> createState() => _JoinScreenState();
}
class _JoinScreenState extends State<JoinScreen> {
final _roomIdCtrl = TextEditingController();
final _userIdCtrl = TextEditingController();
final _nameCtrl = TextEditingController();
bool _loading = false;
String? _error;
@override
void dispose() {
_roomIdCtrl.dispose();
_userIdCtrl.dispose();
_nameCtrl.dispose();
super.dispose();
}
Future<void> _join() async {
final roomId = _roomIdCtrl.text.trim();
final userId = _userIdCtrl.text.trim();
final userName = _nameCtrl.text.trim();
if (roomId.isEmpty || userId.isEmpty || userName.isEmpty) {
setState(() => _error = 'Please fill in all fields.');
return;
}
setState(() {
_loading = true;
_error = null;
});
try {
final room = await AparsMediaSDK.instance.joinRoom(
roomId: roomId,
userId: userId,
userName: userName,
);
if (!mounted) return;
Navigator.push(
context,
MaterialPageRoute(builder: (_) => LiveClassScreen(room: room)),
);
} on AparsMediaException catch (e) {
setState(() => _error = e.message);
} finally {
if (mounted) setState(() => _loading = false);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 400),
child: Padding(
padding: const EdgeInsets.all(24),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const Text(
'Apars Media',
style: TextStyle(fontSize: 32, fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
const SizedBox(height: 8),
const Text(
'Join your live class',
style: TextStyle(color: Colors.white54),
textAlign: TextAlign.center,
),
const SizedBox(height: 40),
TextField(
controller: _roomIdCtrl,
decoration: const InputDecoration(
labelText: 'Room ID',
border: OutlineInputBorder(),
),
),
const SizedBox(height: 16),
TextField(
controller: _userIdCtrl,
decoration: const InputDecoration(
labelText: 'User ID',
border: OutlineInputBorder(),
),
),
const SizedBox(height: 16),
TextField(
controller: _nameCtrl,
decoration: const InputDecoration(
labelText: 'Your Name',
border: OutlineInputBorder(),
),
),
if (_error != null) ...[
const SizedBox(height: 12),
Text(_error!, style: const TextStyle(color: Colors.redAccent)),
],
const SizedBox(height: 24),
FilledButton(
onPressed: _loading ? null : _join,
child: _loading
? const SizedBox(
height: 20,
width: 20,
child: CircularProgressIndicator(strokeWidth: 2),
)
: const Text('Join Class'),
),
],
),
),
),
),
);
}
}