From e2751619a7bbffa6b40ec82ce2c30aadf8896345 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Mon, 18 Dec 2023 13:32:44 +0800 Subject: [PATCH 1/3] feat: add AudioSourceStats. --- lib/src/events.dart | 2 +- lib/src/stats/audio_source_stats.dart | 51 +++++++++++++++++++++++++++ lib/src/{track => stats}/stats.dart | 18 ++++++---- lib/src/track/local/audio.dart | 7 ++-- lib/src/track/local/video.dart | 2 +- lib/src/track/remote/audio.dart | 7 ++-- lib/src/track/remote/video.dart | 2 +- lib/src/track/track.dart | 2 +- 8 files changed, 76 insertions(+), 15 deletions(-) create mode 100644 lib/src/stats/audio_source_stats.dart rename lib/src/{track => stats}/stats.dart (92%) diff --git a/lib/src/events.dart b/lib/src/events.dart index 963fcadf1..34dae53eb 100644 --- a/lib/src/events.dart +++ b/lib/src/events.dart @@ -21,7 +21,7 @@ import 'participant/remote.dart'; import 'publication/local.dart'; import 'publication/remote.dart'; import 'publication/track_publication.dart'; -import 'track/stats.dart'; +import 'stats/stats.dart'; import 'track/track.dart'; import 'types/other.dart'; import 'types/participant_permissions.dart'; diff --git a/lib/src/stats/audio_source_stats.dart b/lib/src/stats/audio_source_stats.dart new file mode 100644 index 000000000..38876d749 --- /dev/null +++ b/lib/src/stats/audio_source_stats.dart @@ -0,0 +1,51 @@ +// Copyright 2023 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. + +import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc; + +import 'stats.dart'; + +class AudioSourceStats { + final num? audioLevel; + final num? totalAudioEnergy; + final num? totalSamplesDuration; + final num? echoReturnLoss; + final num? echoReturnLossEnhancement; + final String? trackIdentifier; + final bool remoteSource; + + AudioSourceStats({ + required this.echoReturnLossEnhancement, + required this.audioLevel, + required this.totalAudioEnergy, + required this.totalSamplesDuration, + required this.echoReturnLoss, + required this.trackIdentifier, + required this.remoteSource, + }); + + factory AudioSourceStats.fromReport(rtc.StatsReport report) { + return AudioSourceStats( + echoReturnLossEnhancement: + getNumValFromReport(report.values, 'echoReturnLossEnhancement'), + audioLevel: getNumValFromReport(report.values, 'audioLevel'), + totalAudioEnergy: getNumValFromReport(report.values, 'totalAudioEnergy'), + totalSamplesDuration: + getNumValFromReport(report.values, 'totalSamplesDuration'), + echoReturnLoss: getNumValFromReport(report.values, 'echoReturnLoss'), + trackIdentifier: getStringValFromReport(report.values, 'trackIdentifier'), + remoteSource: getBoolValFromReport(report.values, 'remoteSource'), + ); + } +} diff --git a/lib/src/track/stats.dart b/lib/src/stats/stats.dart similarity index 92% rename from lib/src/track/stats.dart rename to lib/src/stats/stats.dart index 8e7a9bcb2..a994d7f2a 100644 --- a/lib/src/track/stats.dart +++ b/lib/src/stats/stats.dart @@ -13,8 +13,7 @@ // limitations under the License. import 'package:flutter/foundation.dart'; - -import '../proto/livekit_models.pb.dart'; +import 'package:livekit_client/src/stats/audio_source_stats.dart'; const monitorFrequency = 2000; @@ -54,12 +53,11 @@ class SenderStats extends CodecStats { class AudioSenderStats extends SenderStats { AudioSenderStats(String streamId, num timestamp) : super(streamId, timestamp); - TrackType type = TrackType.AUDIO; + AudioSourceStats? audioSourceStats; } class VideoSenderStats extends SenderStats { VideoSenderStats(String streamId, num timestamp) : super(streamId, timestamp); - TrackType type = TrackType.VIDEO; num? firCount; @@ -107,7 +105,6 @@ class ReceiverStats extends CodecStats { class AudioReceiverStats extends ReceiverStats { AudioReceiverStats(String streamId, num timestamp) : super(streamId, timestamp); - TrackType type = TrackType.AUDIO; num? concealedSamples; @@ -120,14 +117,14 @@ class AudioReceiverStats extends ReceiverStats { num? totalAudioEnergy; num? totalSamplesDuration; + + AudioSourceStats? audioSourceStats; } class VideoReceiverStats extends ReceiverStats { VideoReceiverStats(String streamId, num timestamp) : super(streamId, timestamp); - TrackType type = TrackType.VIDEO; - num? framesDecoded; num? framesDropped; @@ -212,3 +209,10 @@ String? getStringValFromReport(Map values, String key) { } return null; } + +bool getBoolValFromReport(Map values, String key) { + if (values.containsKey(key) && values[key] is bool) { + return values[key] as bool; + } + return false; +} diff --git a/lib/src/track/local/audio.dart b/lib/src/track/local/audio.dart index a3d4272e1..d8435d0c1 100644 --- a/lib/src/track/local/audio.dart +++ b/lib/src/track/local/audio.dart @@ -16,15 +16,16 @@ import 'dart:async'; import 'package:collection/collection.dart'; import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc; +import 'package:livekit_client/src/stats/audio_source_stats.dart'; import 'package:meta/meta.dart'; import '../../events.dart'; import '../../logger.dart'; import '../../proto/livekit_models.pb.dart' as lk_models; import '../../types/other.dart'; +import '../../stats/stats.dart'; import '../audio_management.dart'; import '../options.dart'; -import '../stats.dart'; import 'local.dart'; class LocalAudioTrack extends LocalTrack @@ -101,7 +102,9 @@ class LocalAudioTrack extends LocalTrack senderStats.channels = getNumValFromReport(c.values, 'channels'); senderStats.clockRate = getNumValFromReport(c.values, 'clockRate'); } - break; + } else if (v.type == 'media-source') { + senderStats ??= AudioSenderStats(v.id, v.timestamp); + senderStats.audioSourceStats = AudioSourceStats.fromReport(v); } } return senderStats; diff --git a/lib/src/track/local/video.dart b/lib/src/track/local/video.dart index 7096021bf..d04606590 100644 --- a/lib/src/track/local/video.dart +++ b/lib/src/track/local/video.dart @@ -23,8 +23,8 @@ import '../../proto/livekit_models.pb.dart' as lk_models; import '../../proto/livekit_rtc.pb.dart' as lk_rtc; import '../../support/platform.dart'; import '../../types/other.dart'; +import '../../stats/stats.dart'; import '../options.dart'; -import '../stats.dart'; import 'audio.dart'; import 'local.dart'; diff --git a/lib/src/track/remote/audio.dart b/lib/src/track/remote/audio.dart index ad11248a7..f8f5ca882 100644 --- a/lib/src/track/remote/audio.dart +++ b/lib/src/track/remote/audio.dart @@ -14,15 +14,16 @@ import 'package:collection/collection.dart'; import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc; +import 'package:livekit_client/src/stats/audio_source_stats.dart'; import '../../events.dart'; import '../../internal/events.dart'; import '../../logger.dart'; import '../../proto/livekit_models.pb.dart' as lk_models; import '../../types/other.dart'; +import '../../stats/stats.dart'; import '../audio_management.dart'; import '../local/local.dart'; -import '../stats.dart'; import 'remote.dart'; import '../web/_audio_api.dart' if (dart.library.html) '../web/_audio_html.dart' @@ -150,7 +151,9 @@ class RemoteAudioTrack extends RemoteTrack receiverStats.channels = getNumValFromReport(c.values, 'channels'); receiverStats.clockRate = getNumValFromReport(c.values, 'clockRate'); } - break; + } else if (v.type == 'track') { + receiverStats ??= AudioReceiverStats(v.id, v.timestamp); + receiverStats.audioSourceStats = AudioSourceStats.fromReport(v); } } return receiverStats; diff --git a/lib/src/track/remote/video.dart b/lib/src/track/remote/video.dart index 49b79f41c..6acfb0780 100644 --- a/lib/src/track/remote/video.dart +++ b/lib/src/track/remote/video.dart @@ -20,8 +20,8 @@ import '../../events.dart'; import '../../logger.dart'; import '../../proto/livekit_models.pb.dart' as lk_models; import '../../types/other.dart'; +import '../../stats/stats.dart'; import '../local/local.dart'; -import '../stats.dart'; import 'remote.dart'; class RemoteVideoTrack extends RemoteTrack with VideoTrack { diff --git a/lib/src/track/track.dart b/lib/src/track/track.dart index b1ad1d8d3..0b7dc5e1a 100644 --- a/lib/src/track/track.dart +++ b/lib/src/track/track.dart @@ -26,7 +26,7 @@ import '../managers/event.dart'; import '../proto/livekit_models.pb.dart' as lk_models; import '../support/disposable.dart'; import '../types/other.dart'; -import 'stats.dart'; +import '../stats/stats.dart'; /// Wrapper around a MediaStreamTrack with additional metadata. /// Base for [AudioTrack] and [VideoTrack], From 896f988fc3d5c402233bdfe2536cc9e82e632346 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Mon, 18 Dec 2023 13:37:08 +0800 Subject: [PATCH 2/3] import sorter. --- lib/src/stats/stats.dart | 1 + lib/src/track/local/audio.dart | 4 ++-- lib/src/track/local/video.dart | 2 +- lib/src/track/remote/audio.dart | 4 ++-- lib/src/track/remote/video.dart | 2 +- lib/src/track/track.dart | 2 +- 6 files changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/src/stats/stats.dart b/lib/src/stats/stats.dart index a994d7f2a..ff0ecc62e 100644 --- a/lib/src/stats/stats.dart +++ b/lib/src/stats/stats.dart @@ -13,6 +13,7 @@ // limitations under the License. import 'package:flutter/foundation.dart'; + import 'package:livekit_client/src/stats/audio_source_stats.dart'; const monitorFrequency = 2000; diff --git a/lib/src/track/local/audio.dart b/lib/src/track/local/audio.dart index d8435d0c1..09be97505 100644 --- a/lib/src/track/local/audio.dart +++ b/lib/src/track/local/audio.dart @@ -16,14 +16,14 @@ import 'dart:async'; import 'package:collection/collection.dart'; import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc; -import 'package:livekit_client/src/stats/audio_source_stats.dart'; import 'package:meta/meta.dart'; +import 'package:livekit_client/src/stats/audio_source_stats.dart'; import '../../events.dart'; import '../../logger.dart'; import '../../proto/livekit_models.pb.dart' as lk_models; -import '../../types/other.dart'; import '../../stats/stats.dart'; +import '../../types/other.dart'; import '../audio_management.dart'; import '../options.dart'; import 'local.dart'; diff --git a/lib/src/track/local/video.dart b/lib/src/track/local/video.dart index d04606590..2bcb8d350 100644 --- a/lib/src/track/local/video.dart +++ b/lib/src/track/local/video.dart @@ -21,9 +21,9 @@ import '../../events.dart'; import '../../logger.dart'; import '../../proto/livekit_models.pb.dart' as lk_models; import '../../proto/livekit_rtc.pb.dart' as lk_rtc; +import '../../stats/stats.dart'; import '../../support/platform.dart'; import '../../types/other.dart'; -import '../../stats/stats.dart'; import '../options.dart'; import 'audio.dart'; import 'local.dart'; diff --git a/lib/src/track/remote/audio.dart b/lib/src/track/remote/audio.dart index f8f5ca882..057e3ee29 100644 --- a/lib/src/track/remote/audio.dart +++ b/lib/src/track/remote/audio.dart @@ -14,14 +14,14 @@ import 'package:collection/collection.dart'; import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc; -import 'package:livekit_client/src/stats/audio_source_stats.dart'; +import 'package:livekit_client/src/stats/audio_source_stats.dart'; import '../../events.dart'; import '../../internal/events.dart'; import '../../logger.dart'; import '../../proto/livekit_models.pb.dart' as lk_models; -import '../../types/other.dart'; import '../../stats/stats.dart'; +import '../../types/other.dart'; import '../audio_management.dart'; import '../local/local.dart'; import 'remote.dart'; diff --git a/lib/src/track/remote/video.dart b/lib/src/track/remote/video.dart index 6acfb0780..6d726820b 100644 --- a/lib/src/track/remote/video.dart +++ b/lib/src/track/remote/video.dart @@ -19,8 +19,8 @@ import 'package:meta/meta.dart'; import '../../events.dart'; import '../../logger.dart'; import '../../proto/livekit_models.pb.dart' as lk_models; -import '../../types/other.dart'; import '../../stats/stats.dart'; +import '../../types/other.dart'; import '../local/local.dart'; import 'remote.dart'; diff --git a/lib/src/track/track.dart b/lib/src/track/track.dart index 0b7dc5e1a..b02c5a192 100644 --- a/lib/src/track/track.dart +++ b/lib/src/track/track.dart @@ -24,9 +24,9 @@ import '../internal/events.dart'; import '../logger.dart'; import '../managers/event.dart'; import '../proto/livekit_models.pb.dart' as lk_models; +import '../stats/stats.dart'; import '../support/disposable.dart'; import '../types/other.dart'; -import '../stats/stats.dart'; /// Wrapper around a MediaStreamTrack with additional metadata. /// Base for [AudioTrack] and [VideoTrack], From fed7e154abc003adf93a8c003220907168918ef0 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Mon, 18 Dec 2023 21:42:19 +0800 Subject: [PATCH 3/3] update. --- lib/src/stats/stats.dart | 2 +- lib/src/track/local/audio.dart | 2 +- lib/src/track/remote/audio.dart | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/src/stats/stats.dart b/lib/src/stats/stats.dart index ff0ecc62e..e95d0caf2 100644 --- a/lib/src/stats/stats.dart +++ b/lib/src/stats/stats.dart @@ -14,7 +14,7 @@ import 'package:flutter/foundation.dart'; -import 'package:livekit_client/src/stats/audio_source_stats.dart'; +import 'audio_source_stats.dart'; const monitorFrequency = 2000; diff --git a/lib/src/track/local/audio.dart b/lib/src/track/local/audio.dart index 09be97505..482e64e05 100644 --- a/lib/src/track/local/audio.dart +++ b/lib/src/track/local/audio.dart @@ -18,10 +18,10 @@ import 'package:collection/collection.dart'; import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc; import 'package:meta/meta.dart'; -import 'package:livekit_client/src/stats/audio_source_stats.dart'; import '../../events.dart'; import '../../logger.dart'; import '../../proto/livekit_models.pb.dart' as lk_models; +import '../../stats/audio_source_stats.dart'; import '../../stats/stats.dart'; import '../../types/other.dart'; import '../audio_management.dart'; diff --git a/lib/src/track/remote/audio.dart b/lib/src/track/remote/audio.dart index 057e3ee29..0e2555e4b 100644 --- a/lib/src/track/remote/audio.dart +++ b/lib/src/track/remote/audio.dart @@ -15,11 +15,11 @@ import 'package:collection/collection.dart'; import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc; -import 'package:livekit_client/src/stats/audio_source_stats.dart'; import '../../events.dart'; import '../../internal/events.dart'; import '../../logger.dart'; import '../../proto/livekit_models.pb.dart' as lk_models; +import '../../stats/audio_source_stats.dart'; import '../../stats/stats.dart'; import '../../types/other.dart'; import '../audio_management.dart';