Connection quality (#27)
* update protos * signal event * implemented * format * implement example * protocol 5 * icon size
This commit is contained in:
@@ -125,6 +125,7 @@ class _ParticipantWidgetState extends State<ParticipantWidget> {
|
||||
title: widget.participant.identity,
|
||||
audioAvailable: firstAudioPub?.muted == false &&
|
||||
firstAudioPub?.subscribed == true,
|
||||
connectionQuality: widget.participant.connectionQuality,
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
import 'package:eva_icons_flutter/eva_icons_flutter.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:livekit_client/livekit_client.dart';
|
||||
|
||||
class ParticipantInfoWidget extends StatelessWidget {
|
||||
//
|
||||
final String? title;
|
||||
final bool audioAvailable;
|
||||
final ConnectionQuality connectionQuality;
|
||||
|
||||
const ParticipantInfoWidget({
|
||||
this.title,
|
||||
this.audioAvailable = true,
|
||||
this.connectionQuality = ConnectionQuality.unknown,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@@ -38,6 +41,21 @@ class ParticipantInfoWidget extends StatelessWidget {
|
||||
size: 16,
|
||||
),
|
||||
),
|
||||
if (connectionQuality != ConnectionQuality.unknown)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 5),
|
||||
child: Icon(
|
||||
connectionQuality == ConnectionQuality.poor
|
||||
? EvaIcons.wifiOffOutline
|
||||
: EvaIcons.wifi,
|
||||
color: {
|
||||
ConnectionQuality.excellent: Colors.green,
|
||||
ConnectionQuality.good: Colors.orange,
|
||||
ConnectionQuality.poor: Colors.red,
|
||||
}[connectionQuality],
|
||||
size: 16,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -189,6 +189,18 @@ class ParticipantMetadataUpdatedEvent with RoomEvent, ParticipantEvent {
|
||||
});
|
||||
}
|
||||
|
||||
/// [Pariticpant]'s [ConnectionQuality] has updated.
|
||||
/// Emitted by [Room] and [Participant].
|
||||
class ParticipantConnectionQualityUpdatedEvent
|
||||
with RoomEvent, ParticipantEvent {
|
||||
final Participant participant;
|
||||
final ConnectionQuality connectionQuality;
|
||||
const ParticipantConnectionQualityUpdatedEvent({
|
||||
required this.participant,
|
||||
required this.connectionQuality,
|
||||
});
|
||||
}
|
||||
|
||||
/// Data received from [RemoteParticipant].
|
||||
/// Data packets provides the ability to use LiveKit to send/receive arbitrary
|
||||
/// payloads.
|
||||
@@ -310,6 +322,13 @@ class SignalParticipantUpdateEvent with SignalEvent, EngineEvent {
|
||||
});
|
||||
}
|
||||
|
||||
class SignalConnectionQualityUpdateEvent with SignalEvent, EngineEvent {
|
||||
final List<lk_rtc.ConnectionQualityInfo> updates;
|
||||
const SignalConnectionQualityUpdateEvent({
|
||||
required this.updates,
|
||||
});
|
||||
}
|
||||
|
||||
class SignalLocalTrackPublishedEvent with SignalEvent {
|
||||
final String cid;
|
||||
final lk_models.TrackInfo track;
|
||||
|
||||
@@ -41,6 +41,7 @@ extension ProtocolVersionExt on ProtocolVersion {
|
||||
ProtocolVersion.protocol2: '2',
|
||||
ProtocolVersion.protocol3: '3',
|
||||
ProtocolVersion.protocol4: '4',
|
||||
ProtocolVersion.protocol5: '5',
|
||||
}[this]!;
|
||||
}
|
||||
|
||||
@@ -91,3 +92,13 @@ extension SessionDescriptionExt on lk_rtc.SessionDescription {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import '../managers/event.dart';
|
||||
import '../proto/livekit_models.pb.dart' as lk_models;
|
||||
import '../support/disposable.dart';
|
||||
import '../track/track_publication.dart';
|
||||
import '../types.dart';
|
||||
import 'remote_participant.dart';
|
||||
|
||||
/// Represents a Participant in the room, notifies changes via delegates as
|
||||
@@ -43,6 +44,8 @@ abstract class Participant extends DisposableChangeNotifier
|
||||
lk_models.ParticipantInfo? _participantInfo;
|
||||
bool _isSpeaking = false;
|
||||
|
||||
ConnectionQuality _connectionQuality = ConnectionQuality.unknown;
|
||||
|
||||
// suppport for multiple event listeners
|
||||
final EventsEmitter<RoomEvent> roomEvents;
|
||||
|
||||
@@ -66,6 +69,9 @@ abstract class Participant extends DisposableChangeNotifier
|
||||
|
||||
bool get hasVideo => videoTracks.isNotEmpty;
|
||||
|
||||
/// Connection quality of the participant
|
||||
ConnectionQuality get connectionQuality => _connectionQuality;
|
||||
|
||||
/// tracks that are subscribed to
|
||||
List<TrackPublication> get subscribedTracks =>
|
||||
trackPublications.values.where((e) => e.subscribed).toList();
|
||||
@@ -120,6 +126,16 @@ abstract class Participant extends DisposableChangeNotifier
|
||||
}
|
||||
}
|
||||
|
||||
@internal
|
||||
void updateConnectionQuality(ConnectionQuality quality) {
|
||||
if (_connectionQuality == quality) return;
|
||||
_connectionQuality = quality;
|
||||
[events, roomEvents].emit(ParticipantConnectionQualityUpdatedEvent(
|
||||
participant: this,
|
||||
connectionQuality: _connectionQuality,
|
||||
));
|
||||
}
|
||||
|
||||
/// for internal use
|
||||
/// {@nodoc}
|
||||
@internal
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// source: livekit_models.proto
|
||||
//
|
||||
// @dart = 2.12
|
||||
// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_this,unused_import,unused_shown_name
|
||||
// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name
|
||||
|
||||
import 'dart:core' as $core;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// source: livekit_models.proto
|
||||
//
|
||||
// @dart = 2.12
|
||||
// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_this,unused_import,unused_shown_name
|
||||
// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name
|
||||
|
||||
// ignore_for_file: UNDEFINED_SHOWN_NAME
|
||||
import 'dart:core' as $core;
|
||||
@@ -75,6 +75,36 @@ class TrackSource extends $pb.ProtobufEnum {
|
||||
const TrackSource._($core.int v, $core.String n) : super(v, n);
|
||||
}
|
||||
|
||||
class ConnectionQuality extends $pb.ProtobufEnum {
|
||||
static const ConnectionQuality POOR = ConnectionQuality._(
|
||||
0,
|
||||
const $core.bool.fromEnvironment('protobuf.omit_enum_names')
|
||||
? ''
|
||||
: 'POOR');
|
||||
static const ConnectionQuality GOOD = ConnectionQuality._(
|
||||
1,
|
||||
const $core.bool.fromEnvironment('protobuf.omit_enum_names')
|
||||
? ''
|
||||
: 'GOOD');
|
||||
static const ConnectionQuality EXCELLENT = ConnectionQuality._(
|
||||
2,
|
||||
const $core.bool.fromEnvironment('protobuf.omit_enum_names')
|
||||
? ''
|
||||
: 'EXCELLENT');
|
||||
|
||||
static const $core.List<ConnectionQuality> values = <ConnectionQuality>[
|
||||
POOR,
|
||||
GOOD,
|
||||
EXCELLENT,
|
||||
];
|
||||
|
||||
static final $core.Map<$core.int, ConnectionQuality> _byValue =
|
||||
$pb.ProtobufEnum.initByValue(values);
|
||||
static ConnectionQuality? valueOf($core.int value) => _byValue[value];
|
||||
|
||||
const ConnectionQuality._($core.int v, $core.String n) : super(v, n);
|
||||
}
|
||||
|
||||
class ParticipantInfo_State extends $pb.ProtobufEnum {
|
||||
static const ParticipantInfo_State JOINING = ParticipantInfo_State._(
|
||||
0,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// source: livekit_models.proto
|
||||
//
|
||||
// @dart = 2.12
|
||||
// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,deprecated_member_use_from_same_package,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_this,unused_import,unused_shown_name
|
||||
// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,deprecated_member_use_from_same_package,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name
|
||||
|
||||
import 'dart:core' as $core;
|
||||
import 'dart:convert' as $convert;
|
||||
@@ -36,6 +36,19 @@ const TrackSource$json = const {
|
||||
/// Descriptor for `TrackSource`. Decode as a `google.protobuf.EnumDescriptorProto`.
|
||||
final $typed_data.Uint8List trackSourceDescriptor = $convert.base64Decode(
|
||||
'CgtUcmFja1NvdXJjZRILCgdVTktOT1dOEAASCgoGQ0FNRVJBEAESDgoKTUlDUk9QSE9ORRACEhAKDFNDUkVFTl9TSEFSRRAD');
|
||||
@$core.Deprecated('Use connectionQualityDescriptor instead')
|
||||
const ConnectionQuality$json = const {
|
||||
'1': 'ConnectionQuality',
|
||||
'2': const [
|
||||
const {'1': 'POOR', '2': 0},
|
||||
const {'1': 'GOOD', '2': 1},
|
||||
const {'1': 'EXCELLENT', '2': 2},
|
||||
],
|
||||
};
|
||||
|
||||
/// Descriptor for `ConnectionQuality`. Decode as a `google.protobuf.EnumDescriptorProto`.
|
||||
final $typed_data.Uint8List connectionQualityDescriptor = $convert.base64Decode(
|
||||
'ChFDb25uZWN0aW9uUXVhbGl0eRIICgRQT09SEAASCAoER09PRBABEg0KCUVYQ0VMTEVOVBAC');
|
||||
@$core.Deprecated('Use roomDescriptor instead')
|
||||
const Room$json = const {
|
||||
'1': 'Room',
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
// source: livekit_models.proto
|
||||
//
|
||||
// @dart = 2.12
|
||||
// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,deprecated_member_use_from_same_package,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_this,unused_import,unused_shown_name
|
||||
// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,deprecated_member_use_from_same_package,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name
|
||||
|
||||
export 'livekit_models.pb.dart';
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// source: livekit_rtc.proto
|
||||
//
|
||||
// @dart = 2.12
|
||||
// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_this,unused_import,unused_shown_name
|
||||
// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name
|
||||
|
||||
import 'dart:core' as $core;
|
||||
|
||||
@@ -294,6 +294,7 @@ enum SignalResponse_Message {
|
||||
mute,
|
||||
speakersChanged,
|
||||
roomUpdate,
|
||||
connectionQuality,
|
||||
notSet
|
||||
}
|
||||
|
||||
@@ -310,6 +311,7 @@ class SignalResponse extends $pb.GeneratedMessage {
|
||||
9: SignalResponse_Message.mute,
|
||||
10: SignalResponse_Message.speakersChanged,
|
||||
11: SignalResponse_Message.roomUpdate,
|
||||
12: SignalResponse_Message.connectionQuality,
|
||||
0: SignalResponse_Message.notSet
|
||||
};
|
||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(
|
||||
@@ -321,7 +323,7 @@ class SignalResponse extends $pb.GeneratedMessage {
|
||||
? ''
|
||||
: 'livekit'),
|
||||
createEmptyInstance: create)
|
||||
..oo(0, [1, 2, 3, 4, 5, 6, 8, 9, 10, 11])
|
||||
..oo(0, [1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12])
|
||||
..aOM<JoinResponse>(
|
||||
1,
|
||||
const $core.bool.fromEnvironment('protobuf.omit_field_names')
|
||||
@@ -382,6 +384,12 @@ class SignalResponse extends $pb.GeneratedMessage {
|
||||
? ''
|
||||
: 'roomUpdate',
|
||||
subBuilder: RoomUpdate.create)
|
||||
..aOM<ConnectionQualityUpdate>(
|
||||
12,
|
||||
const $core.bool.fromEnvironment('protobuf.omit_field_names')
|
||||
? ''
|
||||
: 'connectionQuality',
|
||||
subBuilder: ConnectionQualityUpdate.create)
|
||||
..hasRequiredFields = false;
|
||||
|
||||
SignalResponse._() : super();
|
||||
@@ -396,6 +404,7 @@ class SignalResponse extends $pb.GeneratedMessage {
|
||||
MuteTrackRequest? mute,
|
||||
SpeakersChanged? speakersChanged,
|
||||
RoomUpdate? roomUpdate,
|
||||
ConnectionQualityUpdate? connectionQuality,
|
||||
}) {
|
||||
final _result = create();
|
||||
if (join != null) {
|
||||
@@ -428,6 +437,9 @@ class SignalResponse extends $pb.GeneratedMessage {
|
||||
if (roomUpdate != null) {
|
||||
_result.roomUpdate = roomUpdate;
|
||||
}
|
||||
if (connectionQuality != null) {
|
||||
_result.connectionQuality = connectionQuality;
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
factory SignalResponse.fromBuffer($core.List<$core.int> i,
|
||||
@@ -600,6 +612,20 @@ class SignalResponse extends $pb.GeneratedMessage {
|
||||
void clearRoomUpdate() => clearField(11);
|
||||
@$pb.TagNumber(11)
|
||||
RoomUpdate ensureRoomUpdate() => $_ensure(9);
|
||||
|
||||
@$pb.TagNumber(12)
|
||||
ConnectionQualityUpdate get connectionQuality => $_getN(10);
|
||||
@$pb.TagNumber(12)
|
||||
set connectionQuality(ConnectionQualityUpdate v) {
|
||||
setField(12, v);
|
||||
}
|
||||
|
||||
@$pb.TagNumber(12)
|
||||
$core.bool hasConnectionQuality() => $_has(10);
|
||||
@$pb.TagNumber(12)
|
||||
void clearConnectionQuality() => clearField(12);
|
||||
@$pb.TagNumber(12)
|
||||
ConnectionQualityUpdate ensureConnectionQuality() => $_ensure(10);
|
||||
}
|
||||
|
||||
class AddTrackRequest extends $pb.GeneratedMessage {
|
||||
@@ -1954,3 +1980,159 @@ class RoomUpdate extends $pb.GeneratedMessage {
|
||||
@$pb.TagNumber(1)
|
||||
$0.Room ensureRoom() => $_ensure(0);
|
||||
}
|
||||
|
||||
class ConnectionQualityInfo extends $pb.GeneratedMessage {
|
||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(
|
||||
const $core.bool.fromEnvironment('protobuf.omit_message_names')
|
||||
? ''
|
||||
: 'ConnectionQualityInfo',
|
||||
package: const $pb.PackageName(
|
||||
const $core.bool.fromEnvironment('protobuf.omit_message_names')
|
||||
? ''
|
||||
: 'livekit'),
|
||||
createEmptyInstance: create)
|
||||
..aOS(
|
||||
1,
|
||||
const $core.bool.fromEnvironment('protobuf.omit_field_names')
|
||||
? ''
|
||||
: 'participantSid')
|
||||
..e<$0.ConnectionQuality>(
|
||||
2,
|
||||
const $core.bool.fromEnvironment('protobuf.omit_field_names')
|
||||
? ''
|
||||
: 'quality',
|
||||
$pb.PbFieldType.OE,
|
||||
defaultOrMaker: $0.ConnectionQuality.POOR,
|
||||
valueOf: $0.ConnectionQuality.valueOf,
|
||||
enumValues: $0.ConnectionQuality.values)
|
||||
..hasRequiredFields = false;
|
||||
|
||||
ConnectionQualityInfo._() : super();
|
||||
factory ConnectionQualityInfo({
|
||||
$core.String? participantSid,
|
||||
$0.ConnectionQuality? quality,
|
||||
}) {
|
||||
final _result = create();
|
||||
if (participantSid != null) {
|
||||
_result.participantSid = participantSid;
|
||||
}
|
||||
if (quality != null) {
|
||||
_result.quality = quality;
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
factory ConnectionQualityInfo.fromBuffer($core.List<$core.int> i,
|
||||
[$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
|
||||
create()..mergeFromBuffer(i, r);
|
||||
factory ConnectionQualityInfo.fromJson($core.String i,
|
||||
[$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
|
||||
create()..mergeFromJson(i, r);
|
||||
@$core.Deprecated('Using this can add significant overhead to your binary. '
|
||||
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
|
||||
'Will be removed in next major version')
|
||||
ConnectionQualityInfo clone() =>
|
||||
ConnectionQualityInfo()..mergeFromMessage(this);
|
||||
@$core.Deprecated('Using this can add significant overhead to your binary. '
|
||||
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
|
||||
'Will be removed in next major version')
|
||||
ConnectionQualityInfo copyWith(
|
||||
void Function(ConnectionQualityInfo) updates) =>
|
||||
super.copyWith((message) => updates(message as ConnectionQualityInfo))
|
||||
as ConnectionQualityInfo; // ignore: deprecated_member_use
|
||||
$pb.BuilderInfo get info_ => _i;
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static ConnectionQualityInfo create() => ConnectionQualityInfo._();
|
||||
ConnectionQualityInfo createEmptyInstance() => create();
|
||||
static $pb.PbList<ConnectionQualityInfo> createRepeated() =>
|
||||
$pb.PbList<ConnectionQualityInfo>();
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static ConnectionQualityInfo getDefault() => _defaultInstance ??=
|
||||
$pb.GeneratedMessage.$_defaultFor<ConnectionQualityInfo>(create);
|
||||
static ConnectionQualityInfo? _defaultInstance;
|
||||
|
||||
@$pb.TagNumber(1)
|
||||
$core.String get participantSid => $_getSZ(0);
|
||||
@$pb.TagNumber(1)
|
||||
set participantSid($core.String v) {
|
||||
$_setString(0, v);
|
||||
}
|
||||
|
||||
@$pb.TagNumber(1)
|
||||
$core.bool hasParticipantSid() => $_has(0);
|
||||
@$pb.TagNumber(1)
|
||||
void clearParticipantSid() => clearField(1);
|
||||
|
||||
@$pb.TagNumber(2)
|
||||
$0.ConnectionQuality get quality => $_getN(1);
|
||||
@$pb.TagNumber(2)
|
||||
set quality($0.ConnectionQuality v) {
|
||||
setField(2, v);
|
||||
}
|
||||
|
||||
@$pb.TagNumber(2)
|
||||
$core.bool hasQuality() => $_has(1);
|
||||
@$pb.TagNumber(2)
|
||||
void clearQuality() => clearField(2);
|
||||
}
|
||||
|
||||
class ConnectionQualityUpdate extends $pb.GeneratedMessage {
|
||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(
|
||||
const $core.bool.fromEnvironment('protobuf.omit_message_names')
|
||||
? ''
|
||||
: 'ConnectionQualityUpdate',
|
||||
package: const $pb.PackageName(
|
||||
const $core.bool.fromEnvironment('protobuf.omit_message_names')
|
||||
? ''
|
||||
: 'livekit'),
|
||||
createEmptyInstance: create)
|
||||
..pc<ConnectionQualityInfo>(
|
||||
1,
|
||||
const $core.bool.fromEnvironment('protobuf.omit_field_names')
|
||||
? ''
|
||||
: 'updates',
|
||||
$pb.PbFieldType.PM,
|
||||
subBuilder: ConnectionQualityInfo.create)
|
||||
..hasRequiredFields = false;
|
||||
|
||||
ConnectionQualityUpdate._() : super();
|
||||
factory ConnectionQualityUpdate({
|
||||
$core.Iterable<ConnectionQualityInfo>? updates,
|
||||
}) {
|
||||
final _result = create();
|
||||
if (updates != null) {
|
||||
_result.updates.addAll(updates);
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
factory ConnectionQualityUpdate.fromBuffer($core.List<$core.int> i,
|
||||
[$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
|
||||
create()..mergeFromBuffer(i, r);
|
||||
factory ConnectionQualityUpdate.fromJson($core.String i,
|
||||
[$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
|
||||
create()..mergeFromJson(i, r);
|
||||
@$core.Deprecated('Using this can add significant overhead to your binary. '
|
||||
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
|
||||
'Will be removed in next major version')
|
||||
ConnectionQualityUpdate clone() =>
|
||||
ConnectionQualityUpdate()..mergeFromMessage(this);
|
||||
@$core.Deprecated('Using this can add significant overhead to your binary. '
|
||||
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
|
||||
'Will be removed in next major version')
|
||||
ConnectionQualityUpdate copyWith(
|
||||
void Function(ConnectionQualityUpdate) updates) =>
|
||||
super.copyWith((message) => updates(message as ConnectionQualityUpdate))
|
||||
as ConnectionQualityUpdate; // ignore: deprecated_member_use
|
||||
$pb.BuilderInfo get info_ => _i;
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static ConnectionQualityUpdate create() => ConnectionQualityUpdate._();
|
||||
ConnectionQualityUpdate createEmptyInstance() => create();
|
||||
static $pb.PbList<ConnectionQualityUpdate> createRepeated() =>
|
||||
$pb.PbList<ConnectionQualityUpdate>();
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static ConnectionQualityUpdate getDefault() => _defaultInstance ??=
|
||||
$pb.GeneratedMessage.$_defaultFor<ConnectionQualityUpdate>(create);
|
||||
static ConnectionQualityUpdate? _defaultInstance;
|
||||
|
||||
@$pb.TagNumber(1)
|
||||
$core.List<ConnectionQualityInfo> get updates => $_getList(0);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// source: livekit_rtc.proto
|
||||
//
|
||||
// @dart = 2.12
|
||||
// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_this,unused_import,unused_shown_name
|
||||
// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name
|
||||
|
||||
// ignore_for_file: UNDEFINED_SHOWN_NAME
|
||||
import 'dart:core' as $core;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// source: livekit_rtc.proto
|
||||
//
|
||||
// @dart = 2.12
|
||||
// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,deprecated_member_use_from_same_package,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_this,unused_import,unused_shown_name
|
||||
// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,deprecated_member_use_from_same_package,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name
|
||||
|
||||
import 'dart:core' as $core;
|
||||
import 'dart:convert' as $convert;
|
||||
@@ -213,6 +213,15 @@ const SignalResponse$json = const {
|
||||
'9': 0,
|
||||
'10': 'roomUpdate'
|
||||
},
|
||||
const {
|
||||
'1': 'connection_quality',
|
||||
'3': 12,
|
||||
'4': 1,
|
||||
'5': 11,
|
||||
'6': '.livekit.ConnectionQualityUpdate',
|
||||
'9': 0,
|
||||
'10': 'connectionQuality'
|
||||
},
|
||||
],
|
||||
'8': const [
|
||||
const {'1': 'message'},
|
||||
@@ -221,7 +230,7 @@ const SignalResponse$json = const {
|
||||
|
||||
/// Descriptor for `SignalResponse`. Decode as a `google.protobuf.DescriptorProto`.
|
||||
final $typed_data.Uint8List signalResponseDescriptor = $convert.base64Decode(
|
||||
'Cg5TaWduYWxSZXNwb25zZRIrCgRqb2luGAEgASgLMhUubGl2ZWtpdC5Kb2luUmVzcG9uc2VIAFIEam9pbhI1CgZhbnN3ZXIYAiABKAsyGy5saXZla2l0LlNlc3Npb25EZXNjcmlwdGlvbkgAUgZhbnN3ZXISMwoFb2ZmZXIYAyABKAsyGy5saXZla2l0LlNlc3Npb25EZXNjcmlwdGlvbkgAUgVvZmZlchIzCgd0cmlja2xlGAQgASgLMhcubGl2ZWtpdC5Ucmlja2xlUmVxdWVzdEgAUgd0cmlja2xlEjQKBnVwZGF0ZRgFIAEoCzIaLmxpdmVraXQuUGFydGljaXBhbnRVcGRhdGVIAFIGdXBkYXRlEkoKD3RyYWNrX3B1Ymxpc2hlZBgGIAEoCzIfLmxpdmVraXQuVHJhY2tQdWJsaXNoZWRSZXNwb25zZUgAUg50cmFja1B1Ymxpc2hlZBItCgVsZWF2ZRgIIAEoCzIVLmxpdmVraXQuTGVhdmVSZXF1ZXN0SABSBWxlYXZlEi8KBG11dGUYCSABKAsyGS5saXZla2l0Lk11dGVUcmFja1JlcXVlc3RIAFIEbXV0ZRJFChBzcGVha2Vyc19jaGFuZ2VkGAogASgLMhgubGl2ZWtpdC5TcGVha2Vyc0NoYW5nZWRIAFIPc3BlYWtlcnNDaGFuZ2VkEjYKC3Jvb21fdXBkYXRlGAsgASgLMhMubGl2ZWtpdC5Sb29tVXBkYXRlSABSCnJvb21VcGRhdGVCCQoHbWVzc2FnZQ==');
|
||||
'Cg5TaWduYWxSZXNwb25zZRIrCgRqb2luGAEgASgLMhUubGl2ZWtpdC5Kb2luUmVzcG9uc2VIAFIEam9pbhI1CgZhbnN3ZXIYAiABKAsyGy5saXZla2l0LlNlc3Npb25EZXNjcmlwdGlvbkgAUgZhbnN3ZXISMwoFb2ZmZXIYAyABKAsyGy5saXZla2l0LlNlc3Npb25EZXNjcmlwdGlvbkgAUgVvZmZlchIzCgd0cmlja2xlGAQgASgLMhcubGl2ZWtpdC5Ucmlja2xlUmVxdWVzdEgAUgd0cmlja2xlEjQKBnVwZGF0ZRgFIAEoCzIaLmxpdmVraXQuUGFydGljaXBhbnRVcGRhdGVIAFIGdXBkYXRlEkoKD3RyYWNrX3B1Ymxpc2hlZBgGIAEoCzIfLmxpdmVraXQuVHJhY2tQdWJsaXNoZWRSZXNwb25zZUgAUg50cmFja1B1Ymxpc2hlZBItCgVsZWF2ZRgIIAEoCzIVLmxpdmVraXQuTGVhdmVSZXF1ZXN0SABSBWxlYXZlEi8KBG11dGUYCSABKAsyGS5saXZla2l0Lk11dGVUcmFja1JlcXVlc3RIAFIEbXV0ZRJFChBzcGVha2Vyc19jaGFuZ2VkGAogASgLMhgubGl2ZWtpdC5TcGVha2Vyc0NoYW5nZWRIAFIPc3BlYWtlcnNDaGFuZ2VkEjYKC3Jvb21fdXBkYXRlGAsgASgLMhMubGl2ZWtpdC5Sb29tVXBkYXRlSABSCnJvb21VcGRhdGUSUQoSY29ubmVjdGlvbl9xdWFsaXR5GAwgASgLMiAubGl2ZWtpdC5Db25uZWN0aW9uUXVhbGl0eVVwZGF0ZUgAUhFjb25uZWN0aW9uUXVhbGl0eUIJCgdtZXNzYWdl');
|
||||
@$core.Deprecated('Use addTrackRequestDescriptor instead')
|
||||
const AddTrackRequest$json = const {
|
||||
'1': 'AddTrackRequest',
|
||||
@@ -492,3 +501,47 @@ const RoomUpdate$json = const {
|
||||
/// Descriptor for `RoomUpdate`. Decode as a `google.protobuf.DescriptorProto`.
|
||||
final $typed_data.Uint8List roomUpdateDescriptor = $convert.base64Decode(
|
||||
'CgpSb29tVXBkYXRlEiEKBHJvb20YASABKAsyDS5saXZla2l0LlJvb21SBHJvb20=');
|
||||
@$core.Deprecated('Use connectionQualityInfoDescriptor instead')
|
||||
const ConnectionQualityInfo$json = const {
|
||||
'1': 'ConnectionQualityInfo',
|
||||
'2': const [
|
||||
const {
|
||||
'1': 'participant_sid',
|
||||
'3': 1,
|
||||
'4': 1,
|
||||
'5': 9,
|
||||
'10': 'participantSid'
|
||||
},
|
||||
const {
|
||||
'1': 'quality',
|
||||
'3': 2,
|
||||
'4': 1,
|
||||
'5': 14,
|
||||
'6': '.livekit.ConnectionQuality',
|
||||
'10': 'quality'
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/// Descriptor for `ConnectionQualityInfo`. Decode as a `google.protobuf.DescriptorProto`.
|
||||
final $typed_data.Uint8List connectionQualityInfoDescriptor = $convert.base64Decode(
|
||||
'ChVDb25uZWN0aW9uUXVhbGl0eUluZm8SJwoPcGFydGljaXBhbnRfc2lkGAEgASgJUg5wYXJ0aWNpcGFudFNpZBI0CgdxdWFsaXR5GAIgASgOMhoubGl2ZWtpdC5Db25uZWN0aW9uUXVhbGl0eVIHcXVhbGl0eQ==');
|
||||
@$core.Deprecated('Use connectionQualityUpdateDescriptor instead')
|
||||
const ConnectionQualityUpdate$json = const {
|
||||
'1': 'ConnectionQualityUpdate',
|
||||
'2': const [
|
||||
const {
|
||||
'1': 'updates',
|
||||
'3': 1,
|
||||
'4': 3,
|
||||
'5': 11,
|
||||
'6': '.livekit.ConnectionQualityInfo',
|
||||
'10': 'updates'
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/// Descriptor for `ConnectionQualityUpdate`. Decode as a `google.protobuf.DescriptorProto`.
|
||||
final $typed_data.Uint8List connectionQualityUpdateDescriptor =
|
||||
$convert.base64Decode(
|
||||
'ChdDb25uZWN0aW9uUXVhbGl0eVVwZGF0ZRI4Cgd1cGRhdGVzGAEgAygLMh4ubGl2ZWtpdC5Db25uZWN0aW9uUXVhbGl0eUluZm9SB3VwZGF0ZXM=');
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
// source: livekit_rtc.proto
|
||||
//
|
||||
// @dart = 2.12
|
||||
// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,deprecated_member_use_from_same_package,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_this,unused_import,unused_shown_name
|
||||
// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,deprecated_member_use_from_same_package,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name
|
||||
|
||||
export 'livekit_rtc.pb.dart';
|
||||
|
||||
@@ -174,6 +174,8 @@ class Room extends DisposableChangeNotifier with EventsEmittable<RoomEvent> {
|
||||
(event) => _onEngineActiveSpeakersUpdateEvent(event.speakers))
|
||||
..on<SignalSpeakersChangedEvent>(
|
||||
(event) => _onSignalSpeakersChangedEvent(event.speakers))
|
||||
..on<SignalConnectionQualityUpdateEvent>(
|
||||
(event) => _onSignalConnectionQualityUpdateEvent(event.updates))
|
||||
..on<EngineDataPacketReceivedEvent>(_onDataMessageEvent)
|
||||
..on<EngineRemoteMuteChangedEvent>((event) async {
|
||||
final track = localParticipant.trackPublications[event.sid];
|
||||
@@ -366,6 +368,23 @@ class Room extends DisposableChangeNotifier with EventsEmittable<RoomEvent> {
|
||||
events.emit(ActiveSpeakersChangedEvent(speakers: activeSpeakers));
|
||||
}
|
||||
|
||||
void _onSignalConnectionQualityUpdateEvent(
|
||||
List<lk_rtc.ConnectionQualityInfo> updates) {
|
||||
for (final entry in updates) {
|
||||
Participant? participant;
|
||||
if (entry.participantSid == localParticipant.sid) {
|
||||
participant = localParticipant;
|
||||
} else {
|
||||
participant = _participants[entry.participantSid];
|
||||
}
|
||||
|
||||
if (participant != null) {
|
||||
// update the connection quality if the participant is found
|
||||
participant.updateConnectionQuality(entry.quality.toLKType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _onDataMessageEvent(EngineDataPacketReceivedEvent dataPacketEvent) {
|
||||
// participant may be null if data is sent from Server-API
|
||||
final senderSid = dataPacketEvent.packet.participantSid;
|
||||
|
||||
@@ -550,6 +550,8 @@ class RTCEngine extends Disposable with EventsEmittable<EngineEvent> {
|
||||
..on<SignalParticipantUpdateEvent>((event) => events.emit(event))
|
||||
// relay
|
||||
..on<SignalSpeakersChangedEvent>((event) => events.emit(event))
|
||||
// relay
|
||||
..on<SignalConnectionQualityUpdateEvent>((event) => events.emit(event))
|
||||
..on<SignalLeaveEvent>((event) async {
|
||||
await close();
|
||||
events.emit(const EngineDisconnectedEvent());
|
||||
|
||||
@@ -24,7 +24,7 @@ class SignalClient extends Disposable with EventsEmittable<SignalEvent> {
|
||||
LiveKitWebSocket? _ws;
|
||||
|
||||
SignalClient({
|
||||
this.protocol = ProtocolVersion.protocol4,
|
||||
this.protocol = ProtocolVersion.protocol5,
|
||||
}) {
|
||||
events.listen((event) {
|
||||
logger.fine('[SignalEvent] $event');
|
||||
@@ -247,6 +247,11 @@ class SignalClient extends Disposable with EventsEmittable<SignalEvent> {
|
||||
events.emit(
|
||||
SignalSpeakersChangedEvent(speakers: msg.speakersChanged.speakers));
|
||||
break;
|
||||
case lk_rtc.SignalResponse_Message.connectionQuality:
|
||||
events.emit(SignalConnectionQualityUpdateEvent(
|
||||
updates: msg.connectionQuality.updates,
|
||||
));
|
||||
break;
|
||||
case lk_rtc.SignalResponse_Message.leave:
|
||||
events.emit(SignalLeaveEvent(canReconnect: msg.leave.canReconnect));
|
||||
break;
|
||||
|
||||
@@ -8,6 +8,7 @@ enum ProtocolVersion {
|
||||
protocol2,
|
||||
protocol3,
|
||||
protocol4,
|
||||
protocol5,
|
||||
}
|
||||
|
||||
enum ConnectionState {
|
||||
@@ -16,6 +17,13 @@ enum ConnectionState {
|
||||
reconnecting,
|
||||
}
|
||||
|
||||
enum ConnectionQuality {
|
||||
unknown,
|
||||
poor,
|
||||
good,
|
||||
excellent,
|
||||
}
|
||||
|
||||
enum Reliability {
|
||||
reliable,
|
||||
lossy,
|
||||
|
||||
Reference in New Issue
Block a user