livekit_client

2.13.2

Flutter Client SDK for LiveKit. Build real-time video and audio into your apps. Supports iOS, Android, and Web.

Download archive

Readme

pub package

LiveKit Flutter SDK

Use this SDK to add realtime video, audio and data features to your Flutter app. By connecting to LiveKit Cloud or a self-hosted server, you can quickly build applications such as multi-modal AI, live streaming, or video calls with just a few lines of code.

This package is published to pub.dev as livekit_client.

[!IMPORTANT] If you're building Voice AI, LiveKit Agents is the SDK for code-first realtime voice agents. STT, LLM, TTS, turn detection, expressive speech, keyterm accuracy, tool usage, and telephony all come bundled in the framework. It's available in both Python and Node.js.

# agent.py
from livekit import agents
from livekit.agents import Agent, AgentServer, AgentSession, STTContextOptions, TurnHandlingOptions, inference

server = AgentServer()


@server.rtc_session(agent_name="my-agent")
async def my_agent(ctx: agents.JobContext):
    session = AgentSession(
        stt=inference.STT(model="deepgram/nova-3", language="multi"),
        llm=inference.LLM(model="google/gemma-4-31b-it"),
        tts=inference.TTS(model="inworld/inworld-tts-2", voice="Ashley"),
        turn_handling=TurnHandlingOptions(turn_detection=inference.TurnDetector()),
        stt_context_options=STTContextOptions(keyterms=["LiveKit", "Acme Corp"]),
        expressive=True,
    )
    await session.start(room=ctx.room, agent=Agent(instructions="You are a helpful voice AI assistant."))
    await session.generate_reply(instructions="Greet the user and offer your assistance.")


if __name__ == "__main__":
    agents.cli.run_app(server)

Models come from LiveKit Inference with no per-provider API keys, and LiveKit Cloud handles deployment and observability. Visit the docs for more info at docs.livekit.io/agents.

Using a coding agent? Install the LiveKit skill with npx skills add livekit/agent-skills and add the docs MCP at https://docs.livekit.io/mcp/ (see coding agent support).

Docs

More Docs and guides are available at https://docs.livekit.io

Supported platforms

LiveKit client SDK for Flutter is designed to work across all platforms supported by Flutter:

  • Android
  • iOS
  • Web
  • macOS
  • Windows
  • Linux

Example app

We built a multi-user conferencing app as an example in the example/ folder. LiveKit is compatible cross-platform: you could join the same room using any of our supported realtime SDKs.

Online demo: https://livekit.github.io/client-sdk-flutter/

Installation

Include this package to your pubspec.yaml

---
dependencies:
  livekit_client: ^2.13.2

iOS

Camera and microphone usage need to be declared in your Info.plist file.

<dict>
  ...
  <key>NSCameraUsageDescription</key>
  <string>$(PRODUCT_NAME) uses your camera</string>
  <key>NSMicrophoneUsageDescription</key>
  <string>$(PRODUCT_NAME) uses your microphone</string>

Your application can still run the voice call when it is switched to the background if the background mode is enabled. Select the app target in Xcode, click the Capabilities tab, enable Background Modes, and check Audio, AirPlay, and Picture in Picture.

Your Info.plist should have the following entries.

<dict>
  ...
  <key>UIBackgroundModes</key>
  <array>
    <string>audio</string>
  </array>

Notes

Since xcode 14 no longer supports 32bit builds, and our latest version is based on libwebrtc m104+ the iOS framework no longer supports 32bit builds, we strongly recommend upgrading to flutter 3.3.0+. if you are using flutter 3.0.0 or below, there is a high chance that your flutter app cannot be compiled correctly due to the missing i386 and arm 32bit framework #132 #172.

You can try to modify your {projects_dir}/ios/Podfile to fix this issue.

post_install do |installer|
  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(target)

    target.build_configurations.each do |config|

      # Workaround for https://github.com/flutter/flutter/issues/64502
      config.build_settings['ONLY_ACTIVE_ARCH'] = 'YES' # <= this line

    end
  end
end

For iOS, the minimum supported deployment target is 12.1. You will need to add the following to your Podfile.

platform :ios, '12.1'

You may need to delete Podfile.lock and re-run pod install after updating deployment target.

Android

We require a set of permissions that need to be declared in your AppManifest.xml. These are required by Flutter WebRTC, which we depend on.

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.your.package">
  <uses-feature android:name="android.hardware.camera" />
  <uses-feature android:name="android.hardware.camera.autofocus" />
  <uses-permission android:name="android.permission.CAMERA" />
  <uses-permission android:name="android.permission.RECORD_AUDIO" />
  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
  <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
  <uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
  <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
  <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
  ...
</manifest>

For using the bluetooth headset correctly on the android device, you need to add permission_handler to your project. And call the following code after launching your app for the first time.

import 'package:permission_handler/permission_handler.dart';

Future<void> _checkPermissions() async {
  var status = await Permission.bluetooth.request();
  if (status.isPermanentlyDenied) {
    print('Bluetooth Permission disabled');
  }
  status = await Permission.bluetoothConnect.request();
  if (status.isPermanentlyDenied) {
    print('Bluetooth Connect Permission disabled');
  }
}

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await _checkPermissions();
  runApp(MyApp());
}

Audio Modes

By default LiveKit uses the communication audio mode on Android, which works best for two-way voice communication.

If your app is media playback oriented and does not need the device's microphone, apply the media session yourself. This switches AudioManager to manual mode, where your app owns the session.

await AudioManager.instance.setAudioSessionOptions(
  const AudioSessionOptions.media(),
);

See the audio session guide for more.

Desktop support

In order to enable Flutter desktop development, please follow instructions here.

On Windows VS 2019 is needed (link in flutter docs will download VS 2022).

Usage

Connecting to a room, publish video & audio

final roomOptions = RoomOptions(
  adaptiveStream: true,
  dynacast: true,
  // ... your room options
)

final room = Room();

// you can use `prepareConnection` to speed up connection.
await room.prepareConnection(url, token);

await room.connect(url, token, roomOptions: roomOptions);

try {
  // video will fail when running in ios simulator
  await room.localParticipant.setCameraEnabled(true);
} catch (error) {
  print('Could not publish video, error: $error');
}

await room.localParticipant.setMicrophoneEnabled(true);

Certificate pinning

Certificate pinning is available for native platforms through RoomOptions.networkOptions. It applies to SDK-owned WSS signaling and internal HTTPS requests. It does not apply to WebRTC media, TURN, or application-owned token endpoints.

Certificate pinning is not supported on Flutter web because browsers do not expose certificate material to application code. Configuring it on web is treated as a misconfiguration and fails fast: Room.connect throws UnsupportedError instead of silently connecting without pinning. Only enable certificatePinning on web builds if you want that behavior, otherwise leave it unset when targeting web.

On native platforms, validation runs during TLS connection setup after the peer certificate is available and before the SDK writes HTTP or WSS request bytes. If validation fails, request headers and bodies are not sent.

Rules are selected by host. Exact hosts like project.livekit.cloud, single-label wildcards like *.livekit.cloud, multi-label wildcards like **.livekit.cloud, and * are supported. *.livekit.cloud matches project.livekit.cloud, but not a.b.livekit.cloud. **.livekit.cloud matches both. Rules with empty hosts apply to every SDK-owned TLS connection.

Hosts that match no rule are connected with platform trust only, and the SDK logs a warning. Keep in mind the SDK also connects to hosts you did not write yourself: LiveKit Cloud region failover uses server-provided regional hostnames like project.region.production.livekit.cloud, which carry more labels than your project URL. Use **.livekit.cloud so pinning also covers those hosts, and make sure the pin set includes the keys the regional endpoints serve.

All rules that match the connection host are applied. Within one check type, any configured value may match. Across check types, each configured type must pass. For example, two matching SPKI rules are treated as one accepted pin set, while SPKI pins plus exact leaf certificates require both the SPKI check and the exact leaf certificate check to pass.

Use SPKI SHA-256 pins when possible. primaryPins and backupPins are both accepted. Backup pins are useful for certificate rotation because the SDK accepts either set.

SPKI pins are matched against the leaf certificate's public key only. Unlike OkHttp or HPKP, the rest of the chain is not checked because Dart does not expose it, so pinning an intermediate or root CA key never matches and fails every connection. Pin leaf keys, and use backup pins for the future leaf keys you plan to rotate to.

final roomOptions = RoomOptions(
  networkOptions: NetworkOptions(
    certificatePinning: CertificatePinningOptions(
      rules: [
        CertificatePinningRule(
          hosts: ['**.livekit.cloud'],
          primaryPins: ['sha256/current-public-key-pin'],
          backupPins: [
            'sha256/next-public-key-pin-1',
            'sha256/next-public-key-pin-2',
          ],
        ),
      ],
    ),
  ),
);

final room = Room(roomOptions: roomOptions);
await room.connect(url, token);

To generate an SPKI pin:

openssl s_client -connect your-host:443 -servername your-host </dev/null 2>/dev/null \
  | openssl x509 -pubkey -noout \
  | openssl pkey -pubin -outform der \
  | openssl dgst -sha256 -binary \
  | openssl base64

Prefix the output with sha256/ before passing it to primaryPins or backupPins.

Certificate rules can also enforce exact leaf certificates or a custom TLS trust store.

Use pinnedLeafCertificates to require an exact peer leaf certificate after TLS trust validation succeeds. Renewing or changing the leaf certificate requires shipping updated pinned certificates.

By itself, pinnedLeafCertificates does not trust private or self-signed certificates. For private PKI, also configure trustedCertificates with the leaf, intermediate, or root certificate that should anchor TLS validation.

final certificate = await CertificateBytes.fromAsset(
  'assets/livekit_leaf_cert.pem',
);

final roomOptions = RoomOptions(
  networkOptions: NetworkOptions(
    certificatePinning: CertificatePinningOptions(
      rules: [
        CertificatePinningRule(
          hosts: ['my-project.livekit.cloud'],
          pinnedLeafCertificates: [certificate],
          trustedCertificates: [certificate],
        ),
      ],
    ),
  ),
);

Use trustedCertificates to validate TLS against a custom trust store, similar to SecurityContext.setTrustedCertificatesBytes. The SDK builds a per-connection trust store from these certificates and does not include the platform trusted roots for that host. The bytes can contain a leaf, intermediate, or root certificate.

final certificate = await CertificateBytes.fromAsset(
  'assets/livekit_intermediate_ca.pem',
);

final roomOptions = RoomOptions(
  networkOptions: NetworkOptions(
    certificatePinning: CertificatePinningOptions(
      rules: [
        CertificatePinningRule(
          hosts: ['**.livekit.cloud'],
          trustedCertificates: [certificate],
        ),
      ],
    ),
  ),
);

When a pinning rule matches a host, the SDK owns TLS setup for that connection and HttpOverrides.global or HttpClient.badCertificateCallback are not consulted. An app that relies on a bad certificate callback to accept a self-signed server certificate will see a HandshakeException once pinning is enabled for that host. Use trustedCertificates to trust the self-signed or private CA certificate instead.

Screen sharing

Screen sharing is supported across all platforms. You can enable it with:

room.localParticipant.setScreenShareEnabled(true);

Android

On Android, you will have to use a media projection foreground service.

In our example, we use the flutter_background package to handle this. In the app's AndroidManifest.xml file, declare the service with the appropriate types and permissions as follows:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
  <!-- Required permissions for screen share -->
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" />
  <application>
    ...
    <service
        android:name="de.julianassmann.flutter_background.IsolateHolderService"
        android:enabled="true"
        android:exported="false"
        android:foregroundServiceType="mediaProjection" />
  </application>
</manifest>

Before starting the background service and enabling screen share, you must call Helper.requestCapturePermission() from flutter_webrtc, and only proceed if it returns true. Refer to our example implementation for details.

iOS

On iOS, a broadcast extension is needed in order to capture screen content from other apps. See setup guide for instructions.

Desktop(Windows/macOS)

On desktop you can use ScreenSelectDialog to select the window or screen you want to share.

try {
  final source = await showDialog<DesktopCapturerSource>(
    context: context,
    builder: (context) => ScreenSelectDialog(),
  );
  if (source == null) {
    print('cancelled screenshare');
    return;
  }
  print('DesktopCapturerSource: ${source.id}');
  var track = await LocalVideoTrack.createScreenShareTrack(
    ScreenShareCaptureOptions(
      sourceId: source.id,
      maxFrameRate: 15.0,
    ),
  );
  await room.localParticipant.publishVideoTrack(track);
} catch (e) {
  print('could not publish screen sharing: $e');
}

End to End Encryption

LiveKit supports end-to-end encryption for audio/video data sent over the network. By default, the native platform can support E2EE without any settings, but for flutter web, you need to use the following steps to create e2ee.worker.dart.js file.

# for example app
dart compile js web/e2ee.worker.dart -o example/web/e2ee.worker.dart.js -m
# for your project
export YOUR_PROJECT_DIR=your_project_dir
git clone https://github.com/livekit/client-sdk-flutter.git
cd client-sdk-flutter && flutter pub get
dart compile js web/e2ee.worker.dart -o ${YOUR_PROJECT_DIR}/web/e2ee.worker.dart.js -m

Advanced track manipulation

The setCameraEnabled/setMicrophoneEnabled helpers are wrappers around the Track API.

You can also manually create and publish tracks:

var localVideo = await LocalVideoTrack.createCameraTrack();
await room.localParticipant.publishVideoTrack(localVideo);

Rendering video

Each track can be rendered separately with the provided VideoTrackRenderer widget.

VideoTrack? track;

@override
Widget build(BuildContext context) {
  if (track != null) {
    return VideoTrackRenderer(track);
  } else {
    return Container(
      color: Colors.grey,
    );
  }
}

Audio handling

Audio tracks are played automatically as long as you are subscribed to them.

LiveKit owns the platform audio session through AudioManager. A call is managed automatically with no setup. Speaker routing and, when you need it, manual session control go through the same object. See the audio session guide for examples covering the automatic and manual modes, speaker routing, per platform overrides, and migration from the older Hardware APIs.

// A call is managed automatically. Route to the speaker when you want.
await AudioManager.instance.setSpeakerOutputPreferred(true);

Handling changes

LiveKit client makes it simple to build declarative UI that reacts to state changes. It notifies changes in two ways

  • ChangeNotifier - generic notification of changes. This is useful when you are building reactive UI and only care about changes that may impact rendering.
  • EventsListener<Event> - listener pattern to listen to specific events (see events.dart).

This example will show you how to use both to react to room events.

class RoomWidget extends StatefulWidget {
  final Room room;

  RoomWidget(this.room);

  @override
  State<StatefulWidget> createState() {
    return _RoomState();
  }
}

class _RoomState extends State<RoomWidget> {
  late final EventsListener<RoomEvent> _listener = widget.room.createListener();

  @override
  void initState() {
    super.initState();
    // used for generic change updates
    widget.room.addListener(_onChange);

    // used for specific events
    _listener
      ..on<RoomDisconnectedEvent>((_) {
        // handle disconnect
      })
      ..on<ParticipantConnectedEvent>((e) {
        print("participant joined: ${e.participant.identity}");
      })
  }

  @override
  void dispose() {
    // be sure to dispose listener to stop listening to further updates
    _listener.dispose();
    widget.room.removeListener(_onChange);
    super.dispose();
  }

  void _onChange() {
    // perform computations and then call setState
    // setState will trigger a build
    setState(() {
      // your updates here
    });
  }

  @override
  Widget build(BuildContext context) {
    // your build function
  }
}

Similarly, you could do the same when rendering participants. Reacting to changes makes it possible to handle tracks published/unpublished or re-ordering participants in your UI.

class VideoView extends StatefulWidget {
  final Participant participant;

  VideoView(this.participant);

  @override
  State<StatefulWidget> createState() {
    return _VideoViewState();
  }
}

class _VideoViewState extends State<VideoView> {
  TrackPublication? videoPub;

  @override
  void initState() {
    super.initState();
    widget.participant.addListener(this._onParticipantChanged);
    // trigger initial change
    _onParticipantChanged();
  }

  @override
  void dispose() {
    widget.participant.removeListener(this._onParticipantChanged);
    super.dispose();
  }

  @override
  void didUpdateWidget(covariant VideoView oldWidget) {
    oldWidget.participant.removeListener(_onParticipantChanged);
    widget.participant.addListener(_onParticipantChanged);
    _onParticipantChanged();
    super.didUpdateWidget(oldWidget);
  }

  void _onParticipantChanged() {
    var subscribedVideos = widget.participant.videoTracks.values.where((pub) {
      return pub.kind == TrackType.VIDEO &&
          !pub.isScreenShare &&
          pub.subscribed;
    });

    setState(() {
      if (subscribedVideos.length > 0) {
        var videoPub = subscribedVideos.first;
        // when muted, show placeholder
        if (!videoPub.muted) {
          this.videoPub = videoPub;
          return;
        }
      }
      this.videoPub = null;
    });
  }

  @override
  Widget build(BuildContext context) {
    var videoPub = this.videoPub;
    if (videoPub != null) {
      return VideoTrackRenderer(videoPub.track as VideoTrack);
    } else {
      return Container(
        color: Colors.grey,
      );
    }
  }
}

Mute, unmute local tracks

On LocalTrackPublications, you can control whether the track is muted by setting its muted property. Changing the mute status will emit a TrackMutedEvent or TrackUnmutedEvent for the local participant. Other participants will receive the status change as well.

// mute track
trackPub.muted = true;

// unmute track
trackPub.muted = false;

Subscriber controls

When subscribing to remote tracks, the client has precise control over status of its subscriptions. You could subscribe or unsubscribe to a track, change its quality, or disabling the track temporarily.

These controls are accessible on the RemoteTrackPublication object.

For more info, see Subscribing to tracks.

Diagnosing connection issues

ConnectionCheck runs a set of connection diagnostics against a LiveKit server — the same checks that power livekit.io/connection-test. Run it proactively at app start, or reactively when room.connect() fails, to determine why a connection cannot be established (firewall, VPN, blocked TURN, etc.).

final connectionCheck = ConnectionCheck(url, token);
final listener = connectionCheck.createListener();
listener.on<ConnectionCheckUpdateEvent>((event) {
  print('${event.info.name}: ${event.info.status.name}');
  for (final log in event.info.logs) {
    print('  $log');
  }
});

// the recommended minimum set of checks
await connectionCheck.checkWebsocket();
await connectionCheck.checkWebRTC();
await connectionCheck.checkTURN();

// additional checks
await connectionCheck.checkReconnect();
await connectionCheck.checkPublishAudio(); // requires microphone permission
await connectionCheck.checkPublishVideo(); // requires camera permission
await connectionCheck.checkConnectionProtocol();
await connectionCheck.checkCloudRegion(); // LiveKit Cloud only

print('all checks passed: ${connectionCheck.isSuccess}');

await listener.dispose();
await connectionCheck.dispose();

Getting help / Contributing

Please join us on Slack to get help from our devs / community members. We welcome your contributions(PRs) and details can be discussed there.

License

Apache License 2.0

Thanks

A huge thank you to flutter-webrtc for making it possible to use WebRTC in Flutter.

Changelog

CHANGELOG

2.13.2

  • Security: Bump flutter_webrtc to 1.6.3 and WebRTC-SDK to 150.7871.04. The bundled TURN/TLS roots no longer include AAA Certificate Services, which cross-signs the compromised eMudhra intermediate CAs (CVE-2026-111943)

2.13.1

  • Changed: Bump flutter_webrtc to 1.6.2+hotfix.4, which fixes a crash on iOS and macOS when a video renderer is disposed while frames are still arriving
  • Changed: Scale the video start bitrate hint by connection setup time: the 1 Mbps camera cap now applies to connections that set up within 1.5 s and ramps linearly down to 300 kbps at 3.5 s or slower; screen share stays uncapped
  • Fixed: Associate inbound RTP receiver stats with the referenced codec report rather than the first codec
  • Fixed: A failed publisher negotiation (for example a setLocalDescription rejection) is now routed to the reconnect path instead of escaping as an unhandled NegotiationError
  • Fixed: Prevent overlapping stats polls when a receiver takes longer than the monitoring interval
  • Fixed: The video start bitrate hint is now one connection-level value written once per publisher connection, capped at 1 Mbps for camera tracks (screen share stays uncapped so its content is legible immediately) and skipped below a 300 kbps target. libwebrtc applies this hint to the whole peer connection, so a per-track value rewritten on every offer resolved to last-writer-wins on m-section order, and an unpublished track could still seed the connection through the section it left behind. The target is also taken from the sum of the simulcast encodings rather than the lowest layer alone

2.13.0

  • Changed: Bump libwebrtc to m150(flutter-webrtc 1.6.2), added enableWARP and zeroPlayoutDelay options to LiveKitClient.initialize
  • Changed: Bump flutter-webrtc to 1.6.2+hotfix.1, fixed crash on Linux/Windows and fix resource leak by releasing event channel on Darwin
  • Changed: Bump flutter_webrtc to 1.6.2+hotfix.3
  • Fixed: Session migration (server Leave{action: RESUME}) now resumes the session instead of escalating to a full reconnect, so remote participants are no longer dropped and re-added
  • Fixed: Reconnect requests are no longer dropped when one attempt is already running, and a reason that requires a full reconnect is no longer lost when a later request replaces it
  • Fixed: A resume whose signal connection drops before it completes is retried instead of being reported as reconnected
  • Fixed: Fail over to other Cloud regions when the initial connection is rejected with 403

2.12.0

  • Added: Add AudioSessionException for iOS audio session failures
  • Changed: Microphone permission and audio session failures now throw TrackCreateException / AudioSessionException instead of AudioProcessingException
  • Changed: Raise minimum supported versions to Flutter 3.38 / Dart 3.10, the floor for stable native assets support
  • Changed: Update json_annotation to 4.12 and regenerate serialization code with json_serializable 6.14
  • Fixed: BaseKeyProvider.create now honors the discardFrameWhenCryptorNotReady option instead of always using the default
  • Fixed: Pre-connect audio buffer returns to a reusable state when recording fails to start, instead of ignoring retries and leaking the agent timeout
  • Fixed: Subscriber data channel state events now report the subscriber channel state and correct reliability type, and no longer leak listeners
  • Fixed: CachingTokenSource.fetch now awaits its result, so errors surface and the in-flight entry is cleared correctly
  • Fixed: sendText declares the UTF-8 byte length in the stream header, fixing rejected text streams containing non-ASCII characters
  • Fixed: Android: a failed local recording pre-warm no longer aborts microphone capture with AudioProcessingException(applyFailed)
  • Fixed: iOS: the audio session is configured from engine state even before a policy is pushed (pre-connect audio, pre-join mic, playout-only), fixing audio engine error -9001
  • Fixed: iOS/macOS: request microphone permission before audio capture starts, failing fast with TrackCreateException while the app is not in the foreground
  • Fixed: Fix use-after-free crash in TaskRunnerLinux::EnqueueTask when the runner is destroyed before the main loop dispatches a queued task

2.11.0

  • Added: New DisconnectReason members for newer server disconnect reasons, previously reported as unknown
  • Added: Add DevelopmentTokenSource, the new name for the now-deprecated SandboxTokenSource
  • Changed: Default video degradation preference is now based on the track source (camera maintains framerate, screen share maintains resolution, others balanced) and is applied to the backup codec's sender as well
  • Changed: Update generated protocol definitions to v1.50.4
  • Changed: Unrecognized protobuf enum values from newer servers now fall back to safe defaults, for example a new DisconnectReason maps to unknown
  • Changed: Update dependencies: device_info_plus to 13.x, connectivity_plus 7.3.1, dart_webrtc 1.8.1, synchronized 3.4.1, uuid 4.6.0
  • Changed: Modernize the example app with a redesigned connect page, connection history, room header, focus layout, and an in-room messages panel
  • Fixed: Room.connect no longer ignores the roomOptions argument passed to it
  • Fixed: Room.getSid() now resolves when the room sid is issued after the join response
  • Fixed: Backup codec state is cleared on unpublish and full reconnect, so republishing no longer acts on senders from a torn down connection
  • Fixed: DegradationPreference.disabled now maps to maintainFramerateAndResolution, as WebRTC defines it

2.10.0

  • Added: Swift Package Manager support for iOS and macOS. CocoaPods remains fully supported.
  • Added: Add ScreenSelectDialog.show and Hardware.requestCapturePermission so apps can start screen share without importing flutter_webrtc
  • Fixed: Omit data stream totalLength when size is unknown
  • Fixed: Fix compile errors on Dart 3.13 where nullable publish options are no longer promoted across await
  • Fixed: Harden the example RPC tester

2.9.0

  • Added: Add native certificate pinning for SDK-owned connections
  • Added: Add RPC v2 (data-stream-based payloads) with v1 fallback
  • Added: Audio engine availability and externalCallSystem mode for CallKit
  • Added: AudioManager audio session options with engine-driven native lifecycle and platform routing controls
  • Added: Add ConnectionCheck utility for diagnosing connection issues (port of the client-sdk-js connection helper)
  • Added: Audio frame capture on Linux/Windows
  • Added: Microphone mute mode control on iOS/macOS
  • Added: Runtime audio processing controls for local audio tracks
  • Added: Widget Placeholder added for VideoTrackRenderer
  • Changed: Default VideoTrackRenderer renderMode to auto, which currently resolves to texture rendering
  • Fixed: Apply Android media audio attributes during WebRTC initialization
  • Fixed: Use initialization audio options as the default Android session policy
  • Fixed: Avoid sticky Android speaker routing when updating route preference
  • Fixed: Clean up local audio tracks when recording start fails
  • Fixed: Throw platformUnavailable when runtime audio processing is unsupported
  • Fixed: Apply create-time audio processing when local recording is prepared
  • Fixed: Remove non-public buttonPressed: selector from broadcast picker activation
  • Fixed: Allow selectAudioOutput on Android
  • Fixed: Support platform video rendering on macOS
  • Fixed: Emit a single disconnected event when connecting fails
  • Fixed: Handle switching video render modes without stale renderers
  • Docs: Add AGENTS.md with agent/contributor guidelines

2.8.1

  • Added: Add agent deployment targeting to token source options
  • Fixed: Android plugin compatibility with AGP 9 built-in Kotlin
  • Fixed: Use maintain-resolution as the default video degradation preference for local video publishing

2.8.0

  • Added: Session API support for simpler E2EE setup
  • Changed: Manual video quality selection can be used with adaptive stream enabled
  • Changed: Generated protocol definitions for LiveKit protocol v1.45.8
  • Fixed: waitForBufferStatusLow busy-waiting after engine close
  • Fixed: Simulcast lower layers exceeding the top layer
  • Fixed: forceRelay log message interpolation
  • Fixed: sendSyncState error handling so sync-state preparation failures are not swallowed
  • Fixed: Screen share simulcast default low layer alignment
  • Fixed: Region failover null-provider dereference
  • Fixed: Android builds with dependencies that require compileSdk 36
  • Fixed: Deferred track listener leaks across reconnects
  • Fixed: Adaptive stream dimensions on high-density displays
  • Fixed: Session.start() reentrancy during concurrent calls
  • Fixed: Connected server address resolving from the wrong peer connection
  • Fixed: Reconnect counter null assertion on the first reconnect attempt
  • Fixed: Premature publication disposal during unpublish

2.7.0

  • Added: Add setVideoDimensions for remote track publications
  • Added: Add audio renderer API for receiving raw audio frames
  • Changed: Bump flutter-webrtc to 1.4.0 and upgrade to libwebrtc m144
  • Fixed: Add signal RTT tracking via pingReq/pongResp
  • Fixed: Add jitter to reconnect retry delays
  • Fixed: Fix missing params in CameraCaptureOptions.copyWith
  • Fixed: Fix missing RoomReconnectedEvent and incorrect SyncState timing during signal-only reconnection
  • Fixed: Fix VP9/SVC dynacast layer handling
  • Fixed: Stop processor on track end
  • Fixed: Include last server offer in SyncState during reconnection

2.6.5

  • Added: Send reconnect reason to server during WebSocket reconnection
  • Fixed: setProcessor() now uses VideoProcessorOptions for video tracks instead of AudioProcessorOptions
  • Fixed: Fix wildcard variable lint warnings to improve pub.dev score
  • Fixed: Preserve Bluetooth and AirPlay options when forcing speaker output on iOS
  • Fixed: MissingPluginException when stopping audio visualizer on Android/iOS
  • Fixed: Fix microphone stopping after pre-connect audio completes
  • Fixed: Duplicate tracks published when setCameraEnabled called rapidly

2.6.4

  • Added: Add web support for pre-connect audio buffer
  • Fixed: Remove duplicate sendLeave
  • Fixed: Fix setVideoInputDevice not switching camera
  • Fixed: Web pre-connect audio buffer using wrong sample rate
  • Fixed: Fix iOS audio renderer resource leak and remove Android 32-bit dead code
  • Fixed: Fix web audio capture not starting on Safari due to suspended AudioContext
  • Performance: Send raw PCM bytes in audio renderer instead of boxed int arrays

2.6.3

  • Fixed: Fix publisher connection causing redundant renegotiations on lower-end devices
  • Fixed: Use explicit show clauses for foundation imports
  • Fixed: Fix concurrent modification on collection iteration during async operations
  • Fixed: Fix crash when writing to closed data stream controllers
  • Fixed: Fix region URL provider cache using wrong time unit and wrong field check for regions in leave event
  • Chore: Update protobuf to v1.44.0

2.6.2

  • Added: Bitrate priority control APIs
  • Fixed: Windows: stop camera after unpublishing video track
  • Fixed: Keep mute state in sync with server
  • Fixed: Fix example prejoin device dropdown handling
  • Chore: Mark LocalVideoTrack constructor as internal for consistency with LocalAudioTrack
  • Chore: Update protobuf dependency to v6.0.0
  • Chore: Skip iOS platform download in CI

2.6.1

  • Fixed: Enable E2EE for VP9 codec
  • Fixed: Correct spelling in E2EE log and error messages
  • Fixed: Ensure all dispose functions are executed even if one throws
  • Fixed: Fix microphone label typo in example app prejoin audio settings
  • Docs: Fix typos and inconsistencies in README and CHANGELOG

2.6.0

  • Session API
  • Allow customizing screen share dialog labels for localization

2.5.4

  • Added pre-connect audio buffering
  • Added token source API with caching and endpoint helpers
  • Enabled software AEC/NS/AGC for Linux
  • Added event logging with public/internal tagging
  • Migrated manual JSON serialization to json_serializable code generation
  • Re-enabled Flutter lint warnings and fixed existing issues
  • Improved reliable data channel buffering, sequencing, and added integration tests
  • Fixed race condition with pending tracks

2.5.3

  • Feat: Data Packet Cryptor (#873)
  • Feat: Add E2EE support for H265 (#864)
  • Fix: fix async call for update participant info (#897)
  • Move the accessToken to header (#891)
  • Bumpup and clamp connection timeout, fix the comment (#893)
  • Fix events emit order (#902)

2.5.2

  • Fix missing properties for TextStreamInfo (#881)
  • Enum for TextStreamOperationType (#882)
  • Fix stream progress (#884)

2.5.1

  • Fix Publication's track property initialization (#867)
  • Fix Missing attributes in data stream (#865)
  • Fix Internal WebRTC pod version conflict (#876)

2.5.0+hotfix.3

  • fix: Fix @internal conflicting imports from package meta or flutter/foundation.

2.5.0+hotfix.2

  • hotfix: bump libwebrtc to m137.7151.03 to support H.265 (#837)
  • feat: Expose ParticipantState (#848)
  • chore: Update protobuf to v1.39.2 (#847)

2.5.0+hotfix.1

  • fix: Switch to livekit fork of noise for 16KB page support (#839)
  • hotfix: bump libwebrtc to m137.7151.01 for android (#837)
  • fix: tighten VideoTrackRenderer Widget (#695)

2.5.0

  • Bump flutter-webrtc to 1.0.0.
  • Upgrade libwebrtc to m137.7151
  • fix: E2EE bug for Chrome. (#832)
  • fix(web, firefox): backup old values before overwriting them (#819)
  • fix: memory leak visualizer stop android (#831)
  • fix: ensure engine always has correct device id if switching camera fails (#820)
  • fix: Always emit RoomDisconnectedEvent when the reason is clientInitiated. (#821)
  • fix: sif frame enqueuing with e2ee (#822)
  • fix: update camera deviceId when track is null (#814)
  • feat: Audio Visualizer for Windows/Linux. (#739)

2.4.9

  • Added: Attribute typings for agent and transcription (#811)
  • Changed: Enum for VideoView.fit (#806)
  • Chore: Update protobuf protocol to v1.39.2 (#812)

2.4.8

  • fix: fix room.disconnect when pending reconnect. (#802)
  • fix: fix bitrate display for remote video track. (#801)
  • feat: add a flag to skip auto native audio config (#797)
  • fix: sif detection for e2ee (#788)
  • chore: Update protobuf dep (#790)

2.4.7

  • fix: interop for encode and decode function in e2ee cryptor (#785)
  • chore: Unorder the lossy data channel (#783)
  • chore: bump flutter-webrtc to 0.14.1.
  • fix: mitigate reconnect loop (#780)

2.4.6

  • feat: Add smoothTransition option for AudioVisualizer. (#773)
  • fix: Fix deadlock when creating a frame cryptor on iOS/macOS.
  • fix: add task runner for linux to fix crashes.

2.4.5

  • feat: noise filter for flutter web. (#762)

2.4.4

  • feat: data stream
  • fix: calling setSourceEnabled should not affect the current output settings (#754)
  • fix: Calling connect on a disconnected room instance should reset _isClosed. (#752)
  • fix: Fix for Chrome getUserMedia "ideal" Constraint Change.
  • fix: fix duplicate fmtp for vp9 on some old Android devices. (#758)

2.4.3

  • feat: Automatically configure audio mode for Android. (#746)

2.4.2+hotfix.2

  • fix: Fix creation timing for local participant. (#749)
  • fix: Filter out non-video codecs for fast video track publication. (#747)

2.4.2+hotfix.1

  • fix: fixed bug for fast track publish.

2.4.2

  • fix: Fixed the echo issue on some specific models of Android devices.
  • chore: Bbmp version for flutter-webrtc.
  • fix: Improve browser version detection, fix issue #730 (#738)
  • feat: Fast track publication. (#720)
  • chore: Remove bypassVoiceProcessing = true settings for connect page. (#693)
  • fix: [bug] Crash when join room on Windows.
  • fix: Disable selectAudioInput for mobile platforms.

2.4.1

  • feat: VideoRenderer support cache renderer. (#723)
  • feat: Visualizer for web. (#718)
  • fix: Fix bar Visualizer overflow for Android. (#717)
  • fix: disconnect reason inconsistent. (#715)
  • fix: remove stats video data print from logs (#716)

2.4.0

  • feat: RPC. (#682)
  • fix: Properly handle broadcast capture state (#705)

2.3.6

  • Emit a final empty AudioVisualizerEvent after track stops (#701)
  • fix: Improve speaker switching logic for iOS. (#692)

2.3.5

  • feat: add TrackProcessor support. (#657)
  • fix: bug for mute/unmute and speaker switch. (#684)

2.3.4+hotfix.2

  • fix: side effects for stop remote track.

2.3.4+hotfix.1

  • fix: bug for speakerPhone switch. (#672)

2.3.4

  • fix bypass voice processing not work. (#668)
  • fix track.stop for remote track. (#669)
  • fix Visualizer block UI. (#667)

2.3.3

  • Support FocusMode/ExposureMode for camera capture options. (#658)
  • Fix Swift compilation errors (#662)
  • Improve reconnect logic. (#654)
  • Fixed bug for Screen Share on iOS/Android.

2.3.2

  • Add support for audio visualizer.

2.3.1+hotfix.1

  • Fix version mismatch for CocoaPods (#648)
  • Android AGP upgrade (#649)

2.3.0

  • fix: Fixed speaker cannot be switched on iOS. (#617)
  • feat: Increase default audio bitrate. (#616)

2.2.8

  • Fix TrackStreamStateUpdatedEvent not emitted. (#612)

2.2.7

  • feat: support bypass voice processing. (#595)
  • fix: Dispose LocalParticipant when room.disconnect. (#609)
  • Fix spelling error in method name: _checkPremissions to_checkPermissions (#605)
  • fix: fix speaker switching behavior for android. (#604)
  • fix: Optimize stats display (#602)
  • fix: Handle disconnect reasons correctly. (#594)

2.2.6

  • fix: android build failure. (#587)
  • Update README.md for Android Screenshare (#583)

2.2.5

  • upgrade flutter-webrtc to 0.11.7
  • upgrade web to 1.0.0
  • feat: Add timestamps to TranscriptionSegment. (#577)
  • feat: Prepare connection/region pinning. (#574)

2.2.4

  • fix bug for PlatformView on iOS (#570)
  • Deprecated connectOptions in Room constructor.
  • Deprecated roomOptions int room.connect.
  • Added screenShareEncoding for VideoPublishOptions.
  • Change CameraCaptureOptions.params.encoding to optional. It is recommended to use VideoPublishOptions.videoEncoding/screenShareEncoding to control the video sending bitrate.

2.2.3

  • add PlatformView for iOS (#509)
  • update lints to 4.0.0. (#563)

2.2.2

  • feat: expose DegradationPreference for publish options. (#556)
  • fix room.disconnect issue. (#559)
  • fix: use getSettings() to get actual dimensions for mobile (#560)
  • Add support for participant attributes (#558)

2.2.1

  • fix: fix crash for windows
  • feat: bump version for flutter-webrtc.
  • fix: ratchet on a single frame until ratchetWindowSize (#544)
  • fix: fix mediaStreamTrack.getSettings() on Flutter Web.

2.2.0

  • feat: add Transcription Event. (#531)
  • feat: Expose Participant.Kind. (#532)
  • fix: ignore unable to parse frames completely (#530)

2.1.6

  • Framecryptor decrypting fixes (#520)
  • feat: add voiceIsolation support (#523)
  • fix: audio session control for ios.

2.1.5

fix: audio devcie ids consistency (#513) feat: provide option to skip stop/restartTrack for mute/unmute (#516)

2.1.4

  • bump version of flutter-webrtc with privacy manifest files

2.1.3

  • upgrade to connectivity plus 6.x.
  • bump dart_webrtc to 1.4.3.

2.1.2

  • fix: Expose keyRingSize/discardFrameWhenCryptorNotReady parameters for KeyProvider

2.1.1

  • update to package:web (#484)
  • feat: add keyRingSize/discardFrameWhenCryptorNotReady to KeyProviderOptions. (#493)

2.1.0

  • Fix: bug for sync state (#491)

2.0.3

  • Read capabilities from RtcRTPReceiver instead of from sender. (#488)
  • Update screenshare logic for svc publishing (#487)
  • Prevent screen-sharing on flutter web mobile. (#486)
  • feat: add setKey variant, setRawKey (#482)

2.0.2

  • Add Android 14 media projection perm to docs (#470)
  • fix package of MainActivity.kt (#472)
  • Fix: Remember last settings for republish all tracks (full-reconnect). (#475)
  • Fix: Add screenshareAudioEnabled method (#473)
  • Fix: use latest key index for new rtp nodes (#476)

2.0.1

  • bug fix for sync streams.

2.0.0

Breaking Changes

There are several breaking changes between v1 and v2. Please consult our migration guide when upgrading to v2.

  • Room.participants was renamed to Room.remoteParticipants
  • Room.{audio/video}Tracks was renamed to Room.{audio/video}TrackPublications
  • LocalParticipant.publishData now uses participant identity as destinations instead of participant sids.
  • Room.sid now changed to await room.getSid();.
  • Removed VideoQuality.OFF from VideoQuality enum.

Removal of previously deprecated APIs

  • LiveKitClient.connect - Please use var room = Room(...) and room.connect instead.
  • track in TrackMutedEvent/TrackUnmutedEvent - Use publication instead
  • TrackStreamStateUpdatedEvent.trackPublication - Use TrackStreamStateUpdatedEvent.publication instead
  • RemotePublication.videoQuality - Use RemotePublication.setVideoQuality(quality) instead
  • RemotePublication.subscribed - Use RemotePublication.subscribe() or unsubscribe() instead
  • RemotePublication.enabled - Use RemotePublication.enable() or disable() instead
  • Participant.unpublishTrack - Use Participant.removePublishedTrack instead
  • Removed AudioPublishOptions.stopMicTrackOnMute

Other changes

  • Do not emit Reconnecting event during connection resume. (#459)
  • Cleanup when remove remote participants. (#460)
  • Support change key index for encryptors. (#457)
  • Bug fixes for e2ee (Web/Firefox). (#453)
  • Add lost quality (Protocol v11). (#443)
  • [E2EE] Add key handler for web worker. (#449)
  • E2EE improvement. (#461)

1.5.6

  • Set different rendering methods for web and native.
  • Improve reconnection events, add RoomAttemptReconnectEvent.
  • upgrade protocol.

1.5.5

  • Improve reconnect logic for websocket (#406)
  • Fix: Prevent ReplayKitChannel related code from being executed on non-iOS platforms. (#432)

1.5.4

  • Add AudioSourceStats.
  • Fix: invalid muted state for local publication.
  • Add MediaConnectException.
  • Fix preview bug for desktop screen share.
  • Fix errors caused by window close handler for web.
  • Add topic for search optimization in pub.dev.
  • Fix safari screen sharing failure.
  • Fix e2ee worker compile for flutter web.
  • Fix video renderer issue.
  • Fix: video renderer dispose issue and correctly handle metadataMuted for TrackPublication.
  • Fix getStats for remote track.
  • Fix set setScreenShareEnabled when detect replaykit state changed.
  • Improve room/participants metadata update.
  • Simplify backupCodec setting.

1.5.3

  • Handling of incompatible published codecs.
  • Fix/unpublish screen audio track when stop screen share.
  • Upgrade connectivity_plus version.
  • Fix: low-resolution screen sharing for safari 17.
  • Update build.gradle for gradle 8.0.0 namespace.
  • Fix captureScreenAudio conditional.
  • Fix iOSBroadcastExtension always false after copyWith invoked.
  • Fix: VP9 svc screenshare.
  • Fix iOS example compilation after upgrading to XCode 15.
  • Fix: Crop video output size to target settings (iOS/macOS).
  • Fix: Fix bluetooth sco not stopping after room disconnect (Android).

1.5.2

  • Non-functional update, forcing the versions in 'ios/livekit_client.podspec', 'macos/livekit_client.podspec', 'lib/src/livekit.dart' consistent with pubspec.yaml

1.5.1

  • Fixed Renderer bug for Windows.
  • E2EE Improvements.
  • Fixed error when sending events on non-platform thread [iOS/macOS].

1.5.0

  • Update default bitrates according to VMAF guide
  • Support multi-codec simulcast.
  • Support SVC publishing with AV1/VP9.
  • More robustness for E2EE.
  • Configurable Audio Modes for Android.

1.4.3

  • Fix: remove js_bindings and use the built-in AudioContext for js interop to support flutter 3.13.0.

1.4.2

  • Fix: fix the speakerPhone switch issue for Android.
  • Fix: fix iOS cannot publish the audio track correctly.
  • Fix: fix crash when re-publish video track on Windows/Linux.
  • Fix: set preferCurrentTab to false by default

1.4.1

  • Fix: fix Android earpiece not being replaced after wired headset is disconnected.
  • Fix: SpeakerPhone switch for Android.
  • Feat: expose Android audio modes.
  • Fix: Correctly save speakerOn state and restore in AudioManagement.

1.4.0

  • Upgrade flutter-webrtc to 0.9.36 (libwebrtc m114).
  • Fix: Skip decryption when ratchet exceeded.
  • Fix SpeakerPhone switch for mobile.
  • Fix: Fix data channel cannot be opened due to events loss.

1.3.5

  • Fix: Fix ScreenShareCaptureOptions not passed correctly.
  • Fix: facingMode for mobile web.
  • Fix: add name to AudioPublishOptions.
  • Fix: track not stop stats monitor correctly.
  • Feat: add preferCurrentTab support for flutter web.
  • Fix incorrect 4:3 preset bitrates
  • Fix: fix wrong override when options is not null when LocalTrack.create.

1.3.4

  • Fix: Frame drops for Android.

1.3.3

  • Fix: issue for get user audio on Android.

1.3.2

  • Fix: Improve iOS/macOS H264 encoder.
  • Fix: Default capture/publish options for fast connect.

1.3.1

  • Feat: add linux support.
  • Fix: audio play bug for ios safari.
  • Fix: fix bluetooth device enumerate on android.
  • Fix: Do not operate on inactive tracks.
  • Fix: use the correct transceiver id.
  • Fix: Support restart camera for windows/linux.
  • Fix: Move the call of capturer.stopCapture() outside the main thread to avoid blocking of flutter method call.
  • Fix: Handle exceptions for framerate settings for darwin.

1.3.0

  • Fix resolution/framerate/bitrate issue for publishVideoTrack.
  • End-to-end encryption support.

1.2.2

  • Feat: Support setVideoFPS for subscribe.
  • Feat: topic for data-channel.
  • Feat: support metadata update.
  • Feat: handle reconnect response to re-configuration PCs.
  • Docs: readme manager initial setup.
  • Feat: upgrade protocol version to v9.
  • Chore: Use participantIdentity instead of Sid for track permissions.
  • Feat: Bump flutter-webrtc to 0.9.25.
  • Fix: Fix empty label for Wired Headset on Android.
  • Fix: ICE Connectivity doesn't establish with DualSIM iPhones.

1.2.1

  • Fix: fix memory leak for screen capture (macOS).
  • Feat: web/native device consistency management (native/web).
  • Fix: fix renderer issue for Safari/Firefox.
  • Fix: set forceRelay if server response is enabled.
  • Feat: Forward leave reason of disconnected events.
  • Feat: expose logger level api.
  • Feat: expose Room recording event.

1.2.0

  • Fix: re-publish tracks after re connect
  • Fix the bug for firefox.
  • Fix crash when using virtual camera (OBS) for osx.
  • Fix crash when screen sharing with simulcast on macOS
  • Feat: support fast switch camera for LocalVideoTrack.

1.1.12

  • Fix: Audio output list is empty in android (#231)
  • Update flutter-webrtc to 0.9.19
    • As a result of this, the BLUETOOTH_CONNECT permission for Android is no longer needed.

1.1.11

  • Fix: fix connection fails for firefox. (#222, close #221)

1.1.10

  • Fix: Disconnect from room before app closes.
  • Fix: Correctly throws final error when connection fails.

1.1.9

  • Bump flutter-webrtc to 0.9.17
  • Enable BroadCastExtension for iOS in example.

1.1.8

  • Fix resume/full-reconnect.
  • Support stop audio track on mute(turn off the mic indicator).

1.1.7

  • Fixed ice config issues. (#192).
  • Make timeouts configurable.
  • Fixed Hardware.setSpeakerphoneOn() not working on iOS.
  • Fixed track not being correctly passed to localParticipant in FastConnectOptions, causing the camera to apply twice and not be released.
  • Clean up pingIntervalTimer when closing SignalClient.

1.1.6

  • Supports getting the connected remote address.

1.1.5

  • Make MediaDevice data class.
  • Add simulate for candidate protocol switch.
  • Fix VideoTrackRenderer for local has been blacked when toggle video status #166

1.1.4

  • Fixed timestamp type error in ping/pong.

1.1.3

  • Add sid for reconnecting. (#168)
  • Add force relay config. (#169)
  • Bump flutter_webrtc version to 0.9.7.

1.1.2

  • feat: Support for capturing audio for chrome tab.
  • Expose dataChannel for e2e testing.
  • Expose RTPReceiver for getting track statistics.
  • fix: Do not set mandatory & optional parameters, when used in web (#164)
  • fix: fix setSpeakerphoneOn, close #167.

1.1.1-hotfix

  • Fix compilation error caused by webrtc-interface version jumping.

1.1.1

  • Add hardware api for camera and audio input/output selection.
  • Fixed UI stuck when get thumbnails on screen sharing. (#149)

1.1.0-hotfix

  • Align the version in .podspec with the package version (fix compilation errors under ios/mac).

1.1.0

  • Set subscription to allowed when subscribed.
  • Handle combined participant update.
  • Downgrade version settings to support flutter 2.8.0+.
  • Fix: camera release.
  • Feat: iOS screen share.
  • Feat: Screen sharing for desktop.
  • Feat: protocol v8.

1.0.1

  • Re-send tracks permissions after reconnected.
  • Add audioBitrate option for publishAudioTrack.
  • Bump version for flutter_webrtc (up to 0.8.9).
  • Fix: SIGTERM / Crash on connection (Windows) #121
  • Fix: Microphone not published on windows build #64

1.0.0

  • Ready for Flutter 3.
  • mirrorMode for VideoTrackRenderer.
  • Fix url building logic for validation mode.
  • Changed AVAudioSessionCategory switch timing to publish / unpublish.
  • Support for Bluetooth on Android 11.

0.5.9

  • Fix: iOS audio issue which prevents AVAudioSessionCategory to switch correctly.

0.5.8

  • Support for protocol 7, remote unpublish.
  • Fixes simulcast issues with Android devices.
  • Adds ability to select capture device by id.
  • serverRegion property on Room.
  • Minor optimizations.

0.5.7

  • Using WebRTC version M97.
  • New track subscription permissions API.
  • Improvements to reconnect logic.
  • Room metadata update event.

0.5.6

  • Using WebRTC version M93.
  • New dynacast option to RoomOptions. Dynacast dynamically pauses video layers that are not being consumed by any subscribers, significantly reducing publishing CPU and bandwidth usage. (currently defaults to off)
  • Rename optimizeVideo to adaptiveStream and improve stability. AdaptiveStream lets LiveKit automatically manage quality of subscribed video tracks to optimize for bandwidth and CPU.
  • Ensure data channel is ready state when LocalParticipant.publishData api is called.

0.5.5

  • Default capture options for setCameraEnabled, setMicrophoneEnabled
  • Track stream update events
  • Send video layers to server for more video optimization
  • Room instance can be created without connecting
  • Release Camera/Mic when track is muted
  • Better type handling
  • Option to unpublish without stopping track
  • Fixed RemoteTrackPublication mute events
  • Fixed data channel publish bug
  • Initial Windows support

0.5.4

  • Screen sharing support for Android
  • Fixed TrackPublication/Track mute status
  • Fixed bug with updateTrack
  • Fixed being able to apply capture resolution constraints
  • Initial macOS support

0.5.3

  • Connection quality information
  • Automatic video optimizations
  • Simplified track APIs
  • Fix ios camera switch issue
  • Looser podspec constraint for WebRTC-SDK to avoid build issues
  • Better URL parsing

0.5.2

  • change ios audio session defaults to support voice isolation
  • fix explicit subscribe/unsubscribe issue
  • fix WebRTC-SDK resolve issue

0.5.1

  • include plugins for Android and Web

0.5.0

  • major update with new event system
  • supports simulcast for iOS
  • support for background audio for iOS
  • support for protocol 3, subscriber as primary connection
  • improved audio management for iOS, mic indicator only when audio tracks published
  • fires TrackUnpublished for local tracks
  • fixed occasional crashes during publishing

0.4.1

  • fixed video rendering blank after widget changes

0.4.0

  • fixed audio track playback for web
  • fixed publishing tracks for web
  • updated constants to be lowerCamelCase
  • updated style & formatting guide

0.3.0

  • replaceTrack API to switch camera sources
  • example app works on Android

0.2.0

  • pass more detailed connect error message
  • bugfixes with publishing duplicate video tracks
  • removed use of media stream during publishing

0.1.1

  • Minor improvements to error handling

0.1.0

  • Initial beta release.

Installing

export PUB_HOSTED_URL=https://pub.mirror.p-hatan.com
flutter pub add livekit_client
pubspec.yaml
# Copyright 2024 LiveKit, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

name: livekit_client
description: Flutter Client SDK for LiveKit. Build real-time video and audio
  into your apps. Supports iOS, Android, and Web.
version: 2.13.2
homepage: https://github.com/livekit/client-sdk-flutter

# Test fixture keys for certificate pinning tests, not real secrets.
false_secrets:
  - /test/support/certificate_pinning_io_test.dart

environment:
  # Flutter 3.38 / Dart 3.10 is the floor for stable native assets
  # (build hooks), which the upcoming Rust core is delivered through.
  sdk: ">=3.10.0 <4.0.0"
  flutter: ">=3.38.0"

dependencies:
  flutter_web_plugins:
    sdk: flutter
  flutter:
    sdk: flutter
  asn1lib: ^1.6.5
  async: ^2.13.0
  collection: ^1.19.1
  connectivity_plus: ^7.0.0
  crypto: ^3.0.0
  fixnum: ^1.1.1
  meta: ^1.17.0
  http: ^1.6.0
  logging: ^1.3.0
  uuid: ^4.5.3
  synchronized: ^3.4.0
  protobuf: ^6.0.0
  device_info_plus: '>=12.3.0 <14.0.0'
  sdp_transform: ^0.3.2
  web: ^1.1.1
  mime_type: ^1.0.1
  path: ^1.9.1
  dart_jsonwebtoken: ^3.3.2
  json_annotation: ^4.12.0

  # Fix version to avoid version conflicts between WebRTC-SDK pods, which both this package and flutter_webrtc depend on.
  flutter_webrtc: 1.6.3
  dart_webrtc: ^1.8.0

dev_dependencies:
  flutter_test:
    sdk: flutter
  lints: ^6.0.0
  mockito: ^5.3.2
  import_sorter: ^4.6.0
  yaml: ^3.1.2
  build_runner: ^2.4.13
  # Narrow pin so committed codegen stays deterministic across machines
  json_serializable: ">=6.14.1 <6.15.0"

import_sorter:
  comments: false
  ignored_files:
    # Ignore proto files
    - \/lib\/src\/proto\/*

flutter:
  plugin:
    platforms:
      ios:
        pluginClass: LiveKitPlugin
      android:
        package: io.livekit.plugin
        pluginClass: LiveKitPlugin
      macos:
        pluginClass: LiveKitPlugin
      windows:
        pluginClass: LiveKitPlugin
      linux:
        pluginClass: LiveKitPlugin
      web:
        pluginClass: LiveKitWebPlugin
        fileName: livekit_client_web.dart

topics:
  - webrtc
  - voip
  - video
  - livestream
  - conference

Version history

VersionPublishedArchiveSHA-256
0.1.0On demandDownload1420dca1…46bdca
0.1.1On demandDownloadea3934e5…55b55b
0.2.0On demandDownloadbe3aed4c…494ab9
0.3.0On demandDownload7d04f3ac…161767
0.4.0On demandDownload7a25b0ef…6b3d63
0.5.0On demandDownload70857d63…ec6f26
0.5.1On demandDownload549d03d6…ee7495
0.5.2On demandDownload83cccdbb…103314
0.5.3On demandDownload75e4a07d…d58c8a
0.5.4On demandDownload3321b137…399cfe
0.5.5On demandDownload1baa0565…250382
0.5.6On demandDownload3aa32e09…5aa0b3
0.5.7On demandDownloadda23dfe0…609d9f
0.5.8On demandDownload7783518d…b0b761
0.5.9On demandDownloadf68c547b…45ca16
1.0.0On demandDownload73a224d5…2ad7e4
1.0.1On demandDownloadd5b3e227…d095f7
1.1.0-hotfixOn demandDownload82d1fd5b…5c7d1c
1.1.0On demandDownload03800b42…f208be
1.1.1-hotfixOn demandDownload0bc682a2…304a19
1.1.1On demandDownloadeab9bcee…6bfdc6
1.1.2On demandDownload1793850e…350f4e
1.1.3On demandDownload68e0d4c5…0f0619
1.1.4On demandDownload53486442…e12939
1.1.5On demandDownload404ce189…4c2689
1.1.6On demandDownload466178b9…6d2974
1.1.7On demandDownload7fc97e8c…120003
1.1.8On demandDownload6be82d13…159481
1.1.9On demandDownloade0c9a051…02127c
1.1.10On demandDownload9b1b3ebb…2a8d41
1.1.11On demandDownload74d23045…16a3e9
1.1.12On demandDownloadf3d06c80…dfc494
1.2.0On demandDownload4be96f6a…9510eb
1.2.1On demandDownload08120623…5aae06
1.2.2On demandDownload7f0ebc49…4e0e2e
1.3.0On demandDownloade5a44c0f…728022
1.3.1On demandDownloadd6930cde…64c737
1.3.2On demandDownload66682530…9f82e1
1.3.3On demandDownload80f9c4bb…86b150
1.3.4On demandDownloadcba40ce9…42c241
1.3.5On demandDownload19c1b3a7…acee4d
1.4.0On demandDownload8f27ca7e…bb881b
1.4.1On demandDownloadd7a8416a…d76e2b
1.4.2On demandDownload1773b93f…fb2dd5
1.4.3On demandDownloadcd51e47f…7f89bd
1.5.0On demandDownload8b6342ae…582de8
1.5.1On demandDownload5d02fe9a…e28ae8
1.5.2On demandDownload6529fc48…840db6
1.5.3On demandDownloadef268a43…5cc34c
1.5.4On demandDownload240b58bb…058e82
1.5.5On demandDownloadf794ab0b…f2d412
1.5.6On demandDownloade56294ac…5bff3e
2.0.0On demandDownload604f8a78…6df0fd
2.0.1On demandDownload80cf2d7f…f2e650
2.0.2On demandDownload04036683…3848f1
2.0.3On demandDownload6c906047…83cce3
2.1.0On demandDownload39d21e33…837b59
2.1.1On demandDownloade2c83bb6…6fafe4
2.1.2On demandDownload002c7ee0…0e73e5
2.1.3On demandDownload9b7e4715…89ddbb
2.1.4On demandDownload63568260…9e875b
2.1.5On demandDownload3792c433…a9d150
2.1.6On demandDownloade743aadc…a00a3b
2.2.0On demandDownloade4e301c2…ca4b95
2.2.1On demandDownload0c369b25…393e2b
2.2.2On demandDownloade6b1e8a3…ad82f3
2.2.3On demandDownloadbe2a3375…90b3de
2.2.4On demandDownloadfc86a8b6…dd3155
2.2.5On demandDownload5df9b6f1…e58f44
2.2.6On demandDownload449f1f4f…ea61d7
2.2.7On demandDownloade1157434…c54c72
2.2.8On demandDownload15dbf333…3db757
2.3.0On demandDownloadad550454…b21a05
2.3.1On demandDownload442c228f…4e4f3e
2.3.1+hotfix.1On demandDownloade1e2524c…d3408b
2.3.2On demandDownload7802b5de…90bc2d
2.3.3On demandDownloada3ff529f…abc739
2.3.4On demandDownload7cdeb3ea…b2770b
2.3.4+hotfix.1On demandDownloadbe62e169…53a850
2.3.4+hotfix.2On demandDownloada19bcf86…12450d
2.3.5On demandDownload02b4653d…9988de
2.3.6On demandDownload0cfb2f48…7fdb52
2.4.0On demandDownload753bbf48…e2609d
2.4.1On demandDownload7f489fa4…139376
2.4.2On demandDownload18ba0039…af3b53
2.4.2+hotfix.1On demandDownloadcaff0135…91225c
2.4.2+hotfix.2On demandDownload9ffd7385…bf05e6
2.4.3On demandDownload79154da1…499e96
2.4.4On demandDownload3714cd13…7842b2
2.4.5On demandDownloadb50f478a…3f8df3
2.4.6On demandDownload54ef0bfd…38d6c3
2.4.7On demandDownloaddc8fe829…7bdf09
2.4.8On demandDownloadc270720a…257913
2.4.9On demandDownload5d182f40…f2fcce
2.5.0On demandDownload2babccbc…19ffd0
2.5.0+hotfix.1On demandDownloadb3db2d8a…9a40fb
2.5.0+hotfix.2On demandDownload70f6a137…b013c6
2.5.0+hotfix.3On demandDownload011affc0…e904c7
2.5.1On demandDownload4c1663c1…e30cd2
2.5.2On demandDownloadc70dc6a1…9d33a6
2.5.3On demandDownloadddb4467d…c96897
2.5.4On demandDownload4b8ef07d…b53962
2.6.0On demandDownload1931b639…c7fdab
2.6.1On demandDownloadb9282856…045a50
2.6.2On demandDownloadf47bc27c…edae7d
2.6.3On demandDownload23bfefc9…f85750
2.6.4On demandDownload51d97a45…061521
2.6.5On demandDownload35cbf59d…2d91a2
2.7.0On demandDownload23a71bf6…6b4126
2.8.0On demandDownloade1ab69a6…d17ec5
2.8.1On demandDownloadbd68a1e2…08fc23
2.9.0-dev.0On demandDownloada840817f…b714ab
2.9.0On demandDownload8f8dd46f…14b35b
2.10.0On demandDownload9160950f…d0fca9
2.11.0On demandDownload165d04b0…828c04
2.12.0On demandDownloadcda5dbb6…bdf3a7
2.13.0On demandDownloada410348e…58f449
2.13.1On demandDownload1d2ae53a…cdf325
2.13.2Cached · Upstream SHA-256 matchedDownloadc63211bd…2a1bc1

Dependencies

asn1lib "^1.6.5"

async "^2.13.0"

collection "^1.19.1"

connectivity_plus "^7.0.0"

crypto "^3.0.0"

dart_jsonwebtoken "^3.3.2"

dart_webrtc "^1.8.0"

device_info_plus "\u003e=12.3.0 \u003c14.0.0"

fixnum "^1.1.1"

flutter { "sdk": "flutter" }

flutter_web_plugins { "sdk": "flutter" }

flutter_webrtc "1.6.3"

http "^1.6.0"

json_annotation "^4.12.0"

logging "^1.3.0"

meta "^1.17.0"

mime_type "^1.0.1"

path "^1.9.1"

protobuf "^6.0.0"

sdp_transform "^0.3.2"

synchronized "^3.4.0"

uuid "^4.5.3"

web "^1.1.1"