metered_realtime

Flutter WebRTC SDK for video & voice calls, screen sharing, and realtime pub/sub messaging. Peer-to-peer media with built-in signaling, presence, auto-reconnect, and TURN — over flutter_webrtc, on Android, iOS, web, macOS, Windows, and Linux.

Powered by the Metered Realtime Messaging service. The Dart sibling of the @metered-ca/realtime browser SDK — same wire protocol, so a Flutter peer and a browser peer can share a channel.

Full documentation: metered.ca/docs/realtime-messaging/sdk-flutter.

Building with AI? Point Claude Code, Cursor, or Copilot at the SDK's machine-readable reference — llms-realtime-messaging-flutter-sdk.txt — and see Build with AI for ready-to-use prompt templates.

Features

  • 1:N video calls with no signalling backend to buildjoin a channel, addStream your camera, render every onStreamAdded.
  • Messaging on the same connection — channel broadcasts (send) and per-peer direct messages (sendTo / remote.send), surfaced on onData.
  • Resilient by default — automatic reconnect with backoff; transient drops preserve your RemotePeer references and re-establish media behind them (state: connected → reconnecting → connected).
  • Per-track/stream metadata — stamp a bag ({'role': 'camera'}) at addStream/addTrack; receivers get it on onTrack/onStreamAdded before the media arrives.
  • replaceTrack — swap camera ↔ screen share without renegotiation, with per-peer partial-failure reporting.
  • DataChannel wrapper — typed streams + backpressure-aware send() over the raw channel escape hatch.
  • Typed errors, injectable seams — every failure mode is a typed exception; WebSocket + RTCPeerConnection factories are injectable, so the whole engine is unit-testable with fakes.

Install

dependencies:
  metered_realtime: ^0.1.0
  flutter_webrtc: ^1.4.1

flutter_webrtc provides the WebRTC engine and the RTCVideoRenderer / RTCVideoView you render remote media with — add it directly. Then complete the per-platform camera/microphone setup.

Quick start — a video call

import 'package:flutter_webrtc/flutter_webrtc.dart';
import 'package:metered_realtime/metered_realtime.dart';

final peer = MeteredPeer(MeteredPeerOptions(apiKey: 'pk_live_...'));

// Render every remote stream. Re-bind on EVERY onStreamAdded — after a
// transient drop the SDK surfaces a fresh stream object with the same id.
peer.onPeerJoined.listen((remote) {
  remote.onStreamAdded.listen((ev) {
    final native = (ev.stream as FlutterWebrtcMediaStream).native;
    myRenderer.srcObject = native; // an RTCVideoRenderer you created
  });
});

await peer.join('my-room');

// Publish the local camera + mic to everyone (current and future peers).
final local = await navigator.mediaDevices
    .getUserMedia({'audio': true, 'video': true});
await peer.addStream(wrapMediaStream(local), metadata: {'role': 'camera'});

Messaging rides the same connection:

peer.onData.listen((m) => print('${m.senderPeerId}: ${m.data}'));
await peer.send({'hello': 'everyone'});          // channel broadcast
await peer.sendTo(somePeerId, {'hello': 'you'}); // direct to one peer

The runnable example app is the full version of the above — two devices on the same channel see each other's camera. (pub.dev also shows it on this package's Example tab.)

Authentication

  • Development: a publishable key — MeteredPeerOptions(apiKey: 'pk_...').
  • Production: mint short-lived tokens on your backend and hand the SDK a provider; it refreshes them automatically across reconnects:
MeteredPeer(MeteredPeerOptions(
  tokenProvider: () async => fetchTokenFromYourBackend(),
));

Documentation

Full reference: metered.ca/docs/realtime-messaging/sdk-flutter

Design

The protocol / signalling / orchestration core is free of any Flutter import and sits behind small injectable seams — a WebSocketLike factory and an RtcPeerConnectionLike factory — so the bulk of the SDK is testable with fakes, with flutter_webrtc bound at a single boundary.

Layout

lib/
  metered_realtime.dart      # the only public export point (the SemVer surface)
  src/
    protocol/            # wire types, strict parser, frame builders
    internal/            # url, scrub, credential, ice-servers, websocket seam
    signalling/          # SignallingClient (WS pub/sub + reconnect engine)
    webrtc/              # PeerConnection + flutter_webrtc binding + mapping
    peer/                # MeteredPeer / RemotePeer orchestrator
    util/                # logger, byte-length, StateChange
test/                    # mirrors lib/, shared harness + fakes under test/helpers/
example/                 # runnable 1:N video-call app

Development

flutter pub get
flutter test       # the unit suite (CI gate)
flutter analyze
dart format .

CI runs the same gates plus the example's web build.

License

MIT © Metered Inc. — see the LICENSE file (shown on the pub.dev License tab).

Libraries

metered_realtime
Flutter/Dart SDK for the Metered Realtime Messaging service — WebSocket pub/sub + WebRTC peer-to-peer. The Dart sibling of the @metered-ca/realtime JavaScript SDK; both speak the same wire protocol.