26947e96d6
* chore: e2ee. * update. * update. * update. * update. * chore: Use feat/frame-encryption branch of flutter-webrtc. * chore: Add E2EEKEY defines for dart environment, and e2ee switch. * Add encodedInsertableStreams to RTCConfiguration. * update. * feat: Add e2ee indicator for Participant. * feat: add e2ee worker js for flutter web. * dart format. * remove unused file. * fix flutter analyze . * update. * update. * add: indicate for decryption failure, and string key. * remove .lock files. * update. * update. * update e2ee.worker for web. * feat: support setCodecPreferences. * state TrackE2EEStateEvent. * fix wrong import interface from dart_webrtc. * update. * update. * update. * update. * update pubspec.lock. * chore: update protocol and add EncryptionType for Participant. * Update lib/src/e2ee/options.dart Co-authored-by: Théo Monnom <theo.monnom@outlook.com> * fix typo. * revert changes for internal import. * Add _cleanUp() for previous room. * Add e2ee supports detection method for native/web. * Remove redundant overriding methods. * dart format. * Add e2ee.worker code and deployment docs. * chore: remove duplicate words. * chore: using Pbkdf2 derive the key. * Update pubspec.yaml * fix e2ee for safari. * fix key length. * update e2ee.worker.dart.js. * fix. * update proto. * update. * chore: add simulate for rachetKey. * update. * chore: key ratchet for flutter web. * update. * update. * update. * chore: key ratchet export for web. * bump version for xframeworks. * update. * chore: some changes for key safety ratcheting. * update. * fix typo. * update. * rename. * magic bytes for web. * bump version for flutter-webrtc. * fix analyzer. --------- Co-authored-by: Théo Monnom <theo.monnom@outlook.com>
198 lines
6.5 KiB
Dart
198 lines
6.5 KiB
Dart
import 'dart:convert';
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc;
|
|
import 'package:livekit_client/livekit_client.dart';
|
|
|
|
import 'proto/livekit_models.pb.dart' as lk_models;
|
|
import 'proto/livekit_rtc.pb.dart' as lk_rtc;
|
|
|
|
extension DataPacketKindExt on lk_models.DataPacket_Kind {
|
|
Reliability toSDKType() => {
|
|
lk_models.DataPacket_Kind.RELIABLE: Reliability.reliable,
|
|
lk_models.DataPacket_Kind.LOSSY: Reliability.lossy,
|
|
}[this]!;
|
|
}
|
|
|
|
extension LiveKitEventExt on Iterable<EventsEmitter<LiveKitEvent>> {
|
|
void emit(LiveKitEvent event) => forEach((emitter) => emitter.emit(event));
|
|
}
|
|
|
|
extension ICEServerExt on lk_rtc.ICEServer {
|
|
RTCIceServer toSDKType() => RTCIceServer(
|
|
urls: urls,
|
|
username: username.isNotEmpty ? username : null,
|
|
credential: credential.isNotEmpty ? credential : null,
|
|
);
|
|
}
|
|
|
|
extension IterableExt<E> on Iterable<E> {
|
|
E? elementAtOrNull(int index) =>
|
|
(index >= 0 && index < length) ? elementAt(index) : null;
|
|
}
|
|
|
|
extension ObjectExt on Object {
|
|
String get objectId => '${runtimeType}#${hashCode}';
|
|
}
|
|
|
|
extension ProtocolVersionExt on ProtocolVersion {
|
|
String toStringValue() => {
|
|
ProtocolVersion.v2: '2',
|
|
ProtocolVersion.v3: '3',
|
|
ProtocolVersion.v4: '4',
|
|
ProtocolVersion.v5: '5',
|
|
ProtocolVersion.v6: '6',
|
|
ProtocolVersion.v7: '7',
|
|
ProtocolVersion.v8: '8',
|
|
ProtocolVersion.v9: '9',
|
|
}[this]!;
|
|
}
|
|
|
|
extension ReliabilityExt on Reliability {
|
|
lk_models.DataPacket_Kind toPBType() => {
|
|
Reliability.reliable: lk_models.DataPacket_Kind.RELIABLE,
|
|
Reliability.lossy: lk_models.DataPacket_Kind.LOSSY,
|
|
}[this]!;
|
|
}
|
|
|
|
extension RTCDataChannelExt on rtc.RTCDataChannel {
|
|
lk_rtc.DataChannelInfo toLKInfoType() => lk_rtc.DataChannelInfo(
|
|
id: id,
|
|
label: label,
|
|
);
|
|
}
|
|
|
|
extension RTCIceCandidateExt on rtc.RTCIceCandidate {
|
|
static rtc.RTCIceCandidate fromJson(String jsonString) {
|
|
final map = json.decode(jsonString) as Map<String, dynamic>;
|
|
return rtc.RTCIceCandidate(
|
|
map['candidate'] as String?,
|
|
map['sdpMid'] as String?,
|
|
map['sdpMLineIndex'] as int?,
|
|
);
|
|
}
|
|
|
|
String toJson() => json.encode(toMap());
|
|
}
|
|
|
|
extension RTCPeerConnectionStateExt on rtc.RTCPeerConnectionState {
|
|
bool isConnected() =>
|
|
this == rtc.RTCPeerConnectionState.RTCPeerConnectionStateConnected;
|
|
|
|
bool isClosed() =>
|
|
this == rtc.RTCPeerConnectionState.RTCPeerConnectionStateClosed;
|
|
|
|
bool isDisconnectedOrFailed() => [
|
|
rtc.RTCPeerConnectionState.RTCPeerConnectionStateDisconnected,
|
|
rtc.RTCPeerConnectionState.RTCPeerConnectionStateFailed,
|
|
].contains(this);
|
|
}
|
|
|
|
extension RTCIceTransportPolicyExt on RTCIceTransportPolicy {
|
|
String toStringValue() => {
|
|
RTCIceTransportPolicy.all: 'all',
|
|
RTCIceTransportPolicy.relay: 'relay',
|
|
}[this]!;
|
|
}
|
|
|
|
// not so neat to directly expose protobuf types so we
|
|
// define our own types (and convert methods)
|
|
extension RTCSessionDescriptionExt on rtc.RTCSessionDescription {
|
|
lk_rtc.SessionDescription toPBType() {
|
|
return lk_rtc.SessionDescription(type: type, sdp: sdp);
|
|
}
|
|
}
|
|
|
|
extension SessionDescriptionExt on lk_rtc.SessionDescription {
|
|
rtc.RTCSessionDescription toSDKType() {
|
|
return rtc.RTCSessionDescription(sdp, type);
|
|
}
|
|
}
|
|
|
|
extension ConnectionQualityExt on lk_models.ConnectionQuality {
|
|
ConnectionQuality toLKType() =>
|
|
{
|
|
lk_models.ConnectionQuality.POOR: ConnectionQuality.poor,
|
|
lk_models.ConnectionQuality.GOOD: ConnectionQuality.good,
|
|
lk_models.ConnectionQuality.EXCELLENT: ConnectionQuality.excellent,
|
|
}[this] ??
|
|
ConnectionQuality.unknown;
|
|
}
|
|
|
|
extension PBTrackSourceExt on lk_models.TrackSource {
|
|
TrackSource toLKType() =>
|
|
<lk_models.TrackSource, TrackSource>{
|
|
lk_models.TrackSource.CAMERA: TrackSource.camera,
|
|
lk_models.TrackSource.MICROPHONE: TrackSource.microphone,
|
|
lk_models.TrackSource.SCREEN_SHARE: TrackSource.screenShareVideo,
|
|
lk_models.TrackSource.SCREEN_SHARE_AUDIO: TrackSource.screenShareAudio,
|
|
}[this] ??
|
|
TrackSource.unknown;
|
|
}
|
|
|
|
extension LKTrackSourceExt on TrackSource {
|
|
lk_models.TrackSource toPBType() =>
|
|
<TrackSource, lk_models.TrackSource>{
|
|
TrackSource.camera: lk_models.TrackSource.CAMERA,
|
|
TrackSource.microphone: lk_models.TrackSource.MICROPHONE,
|
|
TrackSource.screenShareVideo: lk_models.TrackSource.SCREEN_SHARE,
|
|
TrackSource.screenShareAudio: lk_models.TrackSource.SCREEN_SHARE_AUDIO,
|
|
}[this] ??
|
|
lk_models.TrackSource.UNKNOWN;
|
|
}
|
|
|
|
extension PBStreamStateExt on lk_rtc.StreamState {
|
|
StreamState toLKType() =>
|
|
<lk_rtc.StreamState, StreamState>{
|
|
lk_rtc.StreamState.ACTIVE: StreamState.active,
|
|
}[this] ??
|
|
StreamState.paused;
|
|
}
|
|
|
|
extension VideoQualityExt on lk_models.VideoQuality {
|
|
String toRid() => {
|
|
lk_models.VideoQuality.HIGH: 'f',
|
|
lk_models.VideoQuality.MEDIUM: 'h',
|
|
lk_models.VideoQuality.LOW: 'q',
|
|
}[this]!;
|
|
}
|
|
|
|
extension ParticipantTrackPermissionExt on ParticipantTrackPermission {
|
|
lk_rtc.TrackPermission toPBType() => lk_rtc.TrackPermission(
|
|
participantIdentity: participantIdentity,
|
|
allTracks: allTracksAllowed,
|
|
trackSids: allowedTrackSids,
|
|
);
|
|
}
|
|
|
|
extension WidgetsBindingCompatible on WidgetsBinding {
|
|
// always return optional type for compatibility with flutter v2 and v3
|
|
static WidgetsBinding? get instance => WidgetsBinding.instance;
|
|
}
|
|
|
|
extension EncryptionTypeExt on lk_models.Encryption_Type {
|
|
EncryptionType toLkType() => {
|
|
lk_models.Encryption_Type.NONE: EncryptionType.kNone,
|
|
lk_models.Encryption_Type.GCM: EncryptionType.kGcm,
|
|
lk_models.Encryption_Type.CUSTOM: EncryptionType.kCustom,
|
|
}[this]!;
|
|
}
|
|
|
|
extension DisconnectReasonExt on lk_models.DisconnectReason {
|
|
DisconnectReason toSDKType() => {
|
|
lk_models.DisconnectReason.UNKNOWN_REASON: DisconnectReason.unknown,
|
|
lk_models.DisconnectReason.CLIENT_INITIATED:
|
|
DisconnectReason.clientInitiated,
|
|
lk_models.DisconnectReason.DUPLICATE_IDENTITY:
|
|
DisconnectReason.duplicateIdentity,
|
|
lk_models.DisconnectReason.SERVER_SHUTDOWN:
|
|
DisconnectReason.serverShutdown,
|
|
lk_models.DisconnectReason.PARTICIPANT_REMOVED:
|
|
DisconnectReason.participantRemoved,
|
|
lk_models.DisconnectReason.ROOM_DELETED: DisconnectReason.roomDeleted,
|
|
lk_models.DisconnectReason.STATE_MISMATCH:
|
|
DisconnectReason.stateMismatch,
|
|
lk_models.DisconnectReason.JOIN_FAILURE: DisconnectReason.joinFailure,
|
|
}[this]!;
|
|
}
|