Make a Live Streaming App with Flutter
What This App Does
A Live Streaming app serves a specific need in today's mobile-first world. Building one with Flutter means you ship to iOS, Android, and the web from a single codebase, cutting development time dramatically while keeping a native-quality experience.
Main Features
| Feature | Why It Matters |
|---|---|
| Stream Setup | Configure bitrate, resolution, and camera source before going live |
| Real-Time Chat | WebSocket-based chat room with moderator controls and emoji |
| Donation Alerts | Overlay notifications that appear on stream when someone donates |
How to Make a Live Streaming App with Flutter
Real-Time Chat
class LiveChat extends StatefulWidget {
final String streamId;
const LiveChat({super.key, required this.streamId});
@override State createState() => _LiveChatState();
}
class _LiveChatState extends State {
final _messages = [];
final _ctrl = TextEditingController();
WebSocketChannel? _channel;
@override
void initState() {
super.initState();
_connect();
}
void _connect() {
_channel = WebSocketChannel.connect(
Uri.parse('wss://chat.example.com/stream/\${widget.streamId}'),
);
_channel!.stream.listen((data) {
final msg = ChatMessage.fromJson(jsonDecode(data as String));
setState(() => _messages.add(msg));
});
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Expanded(
child: ListView.builder(
reverse: true,
itemCount: _messages.length,
itemBuilder: (ctx, i) {
final msg = _messages[_messages.length - 1 - i];
return ListTile(
dense: true,
leading: CircleAvatar(
radius: 12,
child: Text(msg.username[0], style: const TextStyle(fontSize: 10)),
),
title: Text('\${msg.username}: \${msg.text}'),
);
},
),
),
Padding(
padding: const EdgeInsets.all(8),
child: Row(
children: [
Expanded(
child: TextField(
controller: _ctrl,
decoration: InputDecoration(
hintText: 'Type a message...',
border: OutlineInputBorder(borderRadius: BorderRadius.circular(20)),
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
),
),
),
IconButton(
icon: const Icon(Icons.send),
onPressed: () {
if (_ctrl.text.isNotEmpty) {
_channel?.sink.add(jsonEncode({'text': _ctrl.text}));
_ctrl.clear();
}
},
),
],
),
),
],
);
}
@override
void dispose() {
_channel?.sink.close();
super.dispose();
}
}
class ChatMessage {
final String username, text;
ChatMessage({required this.username, required this.text});
factory ChatMessage.fromJson(Map j) => ChatMessage(
username: j['username'], text: j['text']);
}
Recommended Libraries
| Package | Purpose |
|---|---|
| flutter_webrtc | RTMP broadcast from device camera |
| agora_rtc_engine | Low-latency streaming with audience interaction |
UI & UX Suggestions
Use a dark theme (#0d1117), purple accent for alerts, red for live indicator colour palette to match the app's purpose. Keep the navigation simple — a bottom nav bar or a single-scroll layout works best for this type of app. Make sure every interaction provides haptic or visual feedback so the app feels responsive and polished.