Nosmai  Effects Nosmai  Moderation Nosmai Try-ons coming soon
Docs menu Flutter
How-to guide

Use Nosmai Effects with LiveKit in Flutter

Publish the processed Flutter camera feed to LiveKit on Android and iOS through the official Nosmai LiveKit bridge.

Platform Flutter SDK version Nosmai Flutter 1.0.2 · Bridge 0.1.0 · LiveKit Client 2.x Updated Aug 22, 2026 Time 8 min

Streaming path

Nosmai processes camera frames before LiveKit publishes them

Nosmai owns the camera and preview. The bridge creates a LiveKit video track from the processed native output, while LiveKit manages the room and transport.

Prerequisites

  • A working Flutter quickstart
  • A LiveKit server URL and participant token
  • iOS 15 or later, or Android API 24 or later
  • A physical arm64 device

Install the packages

dependencies:
  nosmai_effects_sdk: ^1.0.2
  nosmai_livekit_bridge:
    git:
      url: https://github.com/nosmai/nosmai_livekit_bridge.git
  livekit_client: ^2.6.4

The Android host application must still package the verified Nosmai AAR. The iOS host resolves the native SDK through CocoaPods.

Register the shared context first

Call registerShareContext before Nosmai initialization. This order lets the Android encoder read the textures produced by Nosmai. The call is a no-op on iOS.

await NosmaiLiveKitBridge.registerShareContext();

final initialized = await NosmaiFlutter.initialize(nosmaiLicenseKey);
if (!initialized) {
  throw StateError('Nosmai initialization was not accepted');
}

Keep one NosmaiCameraPreview mounted for the full session. Do not create a LiveKit camera track.

const NosmaiCameraPreview()

Publish the processed track

final room = Room(
  roomOptions: const RoomOptions(
    stopLocalTrackOnUnpublish: false,
    defaultVideoPublishOptions: VideoPublishOptions(simulcast: false),
  ),
);

await room.connect(liveKitUrl, liveKitToken);

final track = await NosmaiLiveKitBridge.createVideoTrack();
await room.localParticipant!.publishVideoTrack(track);

Apply and switch effects through NosmaiFlutter. Switch the camera through Nosmai as well, because LiveKit does not own capture on this path.

Stop in the correct order

await NosmaiLiveKitBridge.stopStreaming();
await room.disconnect();

Stop the bridge before disconnecting the room so it can release its native track and graphics resources safely.

Common errors

SymptomCauseFix
Local preview works but remote video is blackThe shared context was registered after Nosmai initializationAwait registerShareContext before NosmaiFlutter.initialize
No frames are publishedNosmaiCameraPreview is not mountedKeep one preview mounted throughout the session
Remote video is raw or the camera is busyLiveKit also created a camera trackPublish only the track returned by createVideoTrack
A second session freezesThe first bridge session was not stoppedPair each successful start with stopStreaming

Verify it worked

Apply a visible effect and join the room from a second participant. Confirm the remote video is filtered and remains stable after camera switch, stop, and rejoin.

Complete example

Use the maintained Nosmai LiveKit bridge example for the full screen, token configuration, filter picker, and teardown flow.

Next steps

References

Was this page helpful?

Your response helps us prioritize documentation improvements.

Nosmai

An AR and AI company. Founded on the idea that the next decade of software will be visual, and that the tools for it should be within reach of anyone building.

Newsletter

Product updates and release notes. No spam.

© 2026 nosmai, inc · all rights reserved