Skip to main content

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.

Animated flow map

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.

Device session

Start RTSP Session

Complete capability and hotspot coordination.

Shared input

Receive RTSP URL

Retain the authoritative address for this session.

Platform view

Native Player

Attach the controller before issuing playback commands.

Flutter UI

Render Preview

Map native events into mounted presentation state.

Optional branch

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
Player state, streamer state, and the device session are independent; stop and dispose each owned resource explicitly.

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.xcframework and depends on AIBudsSDK/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

DART
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

SymptomLikely boundary
Command fails before playbackThe platform view is not attached yet.
Non-iOS placeholderThe plugin currently implements only iOS.
URL exists but no videoInspect player events, hotspot route, and physical-device reachability.
Silent RTMP destinationDiagnose streamer events independently of preview state.
Events continue after navigationCancel the subscription and dispose its native controller.
Duplicate symbolsRemove conflicting native dependency copies.