Live Streaming for Flutter
aibuds_live_stream_flutter bridges native AIBudsLiveStream middleware into Flutter. It provides an iOS platform view for playback and a separate controller for relaying RTSP input to an RTMP destination.
This page covers Flutter/native ownership. Device capability checks, hotspot setup, and RTSP URL acquisition remain in RTSP Live Streaming.
Device stream and Flutter consumers
One device RTSP session produces an address that can feed native preview, optional relay, or both under one host lifecycle owner.
Start RTSP Session
Complete capability and hotspot coordination.
Receive RTSP URL
Retain the authoritative address for this session.
Native Player
Attach the controller before issuing playback commands.
Render Preview
Map native events into mounted presentation state.
RTMP Relay
Publish through a separately owned streamer lifecycle.
- Start RTSP Sessioncontinues toReceive RTSP URL
- Receive RTSP URLpreviewNative Player
- Native Playercontinues toRender Preview
- Receive RTSP URLoptional relayRTMP Relay
Platform and Packaging Boundary
- iOS is supported; Android is not implemented.
- Dart 3.3+, Flutter 3.19+, and iOS 13+ are required.
- The plugin wraps
AIBudsLiveStreamFlutterPlugin.xcframeworkand depends onAIBudsSDK/LiveStream. - Validate RTSP and RTMP on a physical iOS device.
Keep supplied XCFrameworks and resources in the plugin target's iOS packaging flow. Resolve linkage there instead of introducing conflicting copies into the Runner target.
Runtime Architecture
One player controller represents one native platform view. Commands are unavailable until AIBudsLiveStreamPlayerView has been created and attached. A streamer controller owns a separate native relay lifecycle.
Own View, Events, and Controller Together
class LivePreviewState extends State<LivePreview> {
final player = AIBudsLiveStreamPlayerController();
StreamSubscription<AIBudsLiveStreamPlayerEvent>? events;
@override
void initState() {
super.initState();
events = player.events.listen((event) {
if (!mounted) return;
setState(() { /* map native event to presentation state */ });
});
}
@override
Widget build(BuildContext context) => AIBudsLiveStreamPlayerView(
controller: player,
options: const AIBudsLiveStreamPlayerOptions(
format: AIBudsLiveStreamFormat.rtsp,
gravityMode: AIBudsLiveStreamGravityMode.resizeAspect,
),
);
@override
void dispose() {
events?.cancel();
player.disposePlayer();
super.dispose();
}
}Wait until both the platform view and device RTSP URL are ready; either can arrive first. Do not reuse one controller across simultaneously mounted views.
Separate Device and Player State
LiveStreamingAPI owns the device/hotspot session. The Flutter player owns native rendering. Player success does not prove device-session health, and device start does not prove that a frame rendered. Track device session, network route, player, and UI state separately.
On stop or navigation away, prevent new actions, stop player/streamer, stop the device session, cancel Dart subscriptions, dispose native controllers, and clear the retained URL. Make cleanup safe if an interruption already stopped one side.
RTSP-to-RTMP Relay
Treat AIBudsLiveStreamStreamerController as an independent operational feature:
- validate destination authorization outside the callback path;
- subscribe to events before starting;
- choose bitrate, dimensions, frame rate, audio, timeout, adaptive bitrate, and reconnect policy for the target network;
- do not infer publication success from preview success;
- stop and dispose the streamer when the device session ends;
- never embed publishing credentials in Dart source or diagnostics.
If preview and relay share an RTSP source, test resource and reconnect behavior on the lowest supported device.
Performance and Recovery
- Avoid rebuilding the platform view for ordinary status changes.
- Throttle high-frequency events before
setState. - Treat backgrounding, hotspot loss, disconnect, and view disposal as separate interruptions.
- Bound automatic reconnect and provide user-controlled retry.
- Recreate the full device-to-player pipeline when the old session is no longer authoritative.
Troubleshooting
| Symptom | Likely boundary |
|---|---|
| Command fails before playback | The platform view is not attached yet. |
| Non-iOS placeholder | The plugin currently implements only iOS. |
| URL exists but no video | Inspect player events, hotspot route, and physical-device reachability. |
| Silent RTMP destination | Diagnose streamer events independently of preview state. |
| Events continue after navigation | Cancel the subscription and dispose its native controller. |
| Duplicate symbols | Remove conflicting native dependency copies. |