camview 0.2.0
camview: ^0.2.0 copied to clipboard
Live camera feed from the 4Brains Camera Controller over WebRTC — one widget, API-key auth, and auto-reconnect. Receive the stream on any device.
example/lib/main.dart
// Example: connect to a 4Brains Camera Controller and show the live feed.
//
// Enter the signaling server URL, room, and your API key, then Connect.
import 'package:flutter/material.dart';
import 'package:camview/camview.dart';
void main() => runApp(const ExampleApp());
class ExampleApp extends StatelessWidget {
const ExampleApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '4Brains Camera View',
theme: ThemeData(colorSchemeSeed: const Color(0xFFDB4D34), useMaterial3: true),
home: const ConnectPage(),
);
}
}
class ConnectPage extends StatefulWidget {
const ConnectPage({super.key});
@override
State<ConnectPage> createState() => _ConnectPageState();
}
class _ConnectPageState extends State<ConnectPage> {
final _server = TextEditingController(text: 'http://192.168.1.42:4000');
final _room = TextEditingController(text: 'camera');
final _apiKey = TextEditingController();
void _connect() {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => LivePage(
server: _server.text.trim(),
room: _room.text.trim(),
apiKey: _apiKey.text.trim(),
),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('4Brains Camera View')),
body: Center(
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 440),
child: ListView(
padding: const EdgeInsets.all(20),
shrinkWrap: true,
children: [
TextField(
controller: _server,
decoration: const InputDecoration(
labelText: 'Signaling server',
border: OutlineInputBorder(),
),
),
const SizedBox(height: 12),
TextField(
controller: _room,
decoration: const InputDecoration(
labelText: 'Room',
border: OutlineInputBorder(),
),
),
const SizedBox(height: 12),
TextField(
controller: _apiKey,
decoration: const InputDecoration(
labelText: 'API key',
border: OutlineInputBorder(),
),
),
const SizedBox(height: 20),
FilledButton(
onPressed: _connect,
child: const Padding(
padding: EdgeInsets.symmetric(vertical: 10),
child: Text('Connect'),
),
),
],
),
),
),
);
}
}
class LivePage extends StatelessWidget {
const LivePage({
super.key,
required this.server,
required this.room,
required this.apiKey,
});
final String server;
final String room;
final String apiKey;
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(title: const Text('Live')),
body: FourBrainsCameraView(
server: server,
room: room,
apiKey: apiKey,
fit: CameraFit.contain,
onStatus: (s) => debugPrint('status: $s'),
),
);
}
}