Subscriber as primary (#8)
* Update protos * Signal client * Improve transport * First implementation * Fix publish * Update `PCTransport` for debounce negotiation * debounce func * reconnect & events * Update debounce func * engine events * make sure events don't emit after dispose * prefix flutter_webrtc * Cleaner `iceServers` update * don't mutate user provided params * fix tests * event manager * Fix: `Room.onDisconnected` gets fired multiple times * data publish in example * cleaner logic * safer events * un-prefix with LK * organize imports * Clean up * remove `Tuple` * `EventsEmitter` can now be directly listened to `EventsEmitter` extends `EventsListenable`
This commit is contained in:
+64
-35
@@ -1,6 +1,25 @@
|
||||
enum RTCIceTransportPolicy {
|
||||
all,
|
||||
relay,
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc;
|
||||
|
||||
import 'proto/livekit_rtc.pb.dart' as lk_rtc;
|
||||
import 'proto/livekit_models.pb.dart' as lk_models;
|
||||
|
||||
import 'types.dart';
|
||||
|
||||
extension IterableExt<E> on Iterable<E> {
|
||||
E? elementAtOrNull(int index) => (index >= 0 && index < length) ? elementAt(index) : null;
|
||||
}
|
||||
|
||||
extension RTCIceConnectionStateExt on rtc.RTCIceConnectionState {
|
||||
bool isConnected() => [
|
||||
rtc.RTCIceConnectionState.RTCIceConnectionStateConnected,
|
||||
rtc.RTCIceConnectionState.RTCIceConnectionStateCompleted,
|
||||
].contains(this);
|
||||
}
|
||||
|
||||
extension ObjectExt on Object {
|
||||
String get objectId => '${runtimeType}#${hashCode}';
|
||||
}
|
||||
|
||||
extension RTCIceTransportPolicyExt on RTCIceTransportPolicy {
|
||||
@@ -10,41 +29,51 @@ extension RTCIceTransportPolicyExt on RTCIceTransportPolicy {
|
||||
}[this]!;
|
||||
}
|
||||
|
||||
class RTCConfiguration {
|
||||
int? iceCandidatePoolSize;
|
||||
List<RTCIceServer>? iceServers;
|
||||
RTCIceTransportPolicy? iceTransportPolicy;
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
final iceServersMap = <Map<String, dynamic>>[
|
||||
if (iceServers != null)
|
||||
for (final element in iceServers!) element.toMap()
|
||||
];
|
||||
|
||||
return <String, dynamic>{
|
||||
// only supports unified plan
|
||||
'sdpSemantics': 'unified-plan',
|
||||
if (iceServersMap.isNotEmpty) 'iceServers': iceServersMap,
|
||||
if (iceCandidatePoolSize != null) 'iceCandidatePoolSize': iceCandidatePoolSize,
|
||||
if (iceTransportPolicy != null) 'iceTransportPolicy': iceTransportPolicy!.toStringValue(),
|
||||
};
|
||||
extension SessionDescriptionExt on lk_rtc.SessionDescription {
|
||||
rtc.RTCSessionDescription toSDKType() {
|
||||
return rtc.RTCSessionDescription(sdp, type);
|
||||
}
|
||||
}
|
||||
|
||||
class RTCIceServer {
|
||||
List<String> urls;
|
||||
String? username;
|
||||
String? credential;
|
||||
extension RTCSessionDescriptionExt on rtc.RTCSessionDescription {
|
||||
lk_rtc.SessionDescription toSDKType() {
|
||||
return lk_rtc.SessionDescription(type: type, sdp: sdp);
|
||||
}
|
||||
}
|
||||
|
||||
RTCIceServer({
|
||||
required this.urls,
|
||||
this.username,
|
||||
this.credential,
|
||||
});
|
||||
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?,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() => <String, dynamic>{
|
||||
'urls': urls,
|
||||
if (username != null) 'username': username,
|
||||
if (credential != null) 'credential': credential,
|
||||
};
|
||||
String toJson() => json.encode(toMap());
|
||||
}
|
||||
|
||||
extension ICEServerExt on lk_rtc.ICEServer {
|
||||
RTCIceServer toSDKType() => RTCIceServer(
|
||||
urls: urls,
|
||||
username: username.isNotEmpty ? username : null,
|
||||
credential: credential.isNotEmpty ? username : null,
|
||||
);
|
||||
}
|
||||
|
||||
// not so neat to directly expose protobuf types so we
|
||||
// define our own types (and convert methods)
|
||||
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 ReliabilityExt on Reliability {
|
||||
lk_models.DataPacket_Kind toPBType() => {
|
||||
Reliability.reliable: lk_models.DataPacket_Kind.RELIABLE,
|
||||
Reliability.lossy: lk_models.DataPacket_Kind.LOSSY,
|
||||
}[this]!;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user