Skip to content

Commit 1953be8

Browse files
committed
fix: Optimize stats display
1 parent c9a0560 commit 1953be8

File tree

3 files changed

+54
-33
lines changed

3 files changed

+54
-33
lines changed

example/lib/widgets/controls.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,7 @@ class _ControlsWidgetState extends State<ControlsWidget> {
312312
else
313313
PopupMenuButton<MediaDevice>(
314314
icon: const Icon(Icons.settings_voice),
315+
offset: Offset(0, -90),
315316
itemBuilder: (BuildContext context) {
316317
return [
317318
PopupMenuItem<MediaDevice>(

example/lib/widgets/participant.dart

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -148,13 +148,6 @@ abstract class _ParticipantWidgetState<T extends ParticipantWidget>
148148
)
149149
: const NoVideoWidget(),
150150
),
151-
if (widget.showStatsLayer)
152-
Positioned(
153-
top: 30,
154-
right: 30,
155-
child: ParticipantStatsWidget(
156-
participant: widget.participant,
157-
)),
158151
// Bottom bar
159152
Align(
160153
alignment: Alignment.bottomCenter,
@@ -176,6 +169,13 @@ abstract class _ParticipantWidgetState<T extends ParticipantWidget>
176169
],
177170
),
178171
),
172+
if (widget.showStatsLayer)
173+
Positioned(
174+
top: 130,
175+
right: 30,
176+
child: ParticipantStatsWidget(
177+
participant: widget.participant,
178+
)),
179179
],
180180
),
181181
);

example/lib/widgets/participant_stats.dart

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,17 @@ class ParticipantStatsWidget extends StatefulWidget {
1919
class _ParticipantStatsWidgetState extends State<ParticipantStatsWidget> {
2020
List<EventsListener<TrackEvent>> listeners = [];
2121
StatsType statsType = StatsType.kUnknown;
22-
Map<String, String> stats = {};
22+
Map<String, Map<String, String>> stats = {'audio': {}, 'video': {}};
2323

2424
void _setUpListener(Track track) {
2525
var listener = track.createListener();
2626
listeners.add(listener);
2727
if (track is LocalVideoTrack) {
2828
statsType = StatsType.kLocalVideoSender;
2929
listener.on<VideoSenderStatsEvent>((event) {
30+
Map<String, String> stats = {};
3031
setState(() {
31-
stats['video tx'] = 'total sent ${event.currentBitrate.toInt()} kpbs';
32+
stats['tx'] = 'total sent ${event.currentBitrate.toInt()} kpbs';
3233
event.stats.forEach((key, value) {
3334
stats['layer-$key'] =
3435
'${value.frameWidth ?? 0}x${value.frameHeight ?? 0} ${value.framesPerSecond?.toDouble() ?? 0} fps, ${event.bitrateForLayers[key] ?? 0} kbps';
@@ -37,52 +38,66 @@ class _ParticipantStatsWidgetState extends State<ParticipantStatsWidget> {
3738
event.stats['f'] ?? event.stats['h'] ?? event.stats['q'];
3839
if (firstStats != null) {
3940
stats['encoder'] = firstStats.encoderImplementation ?? '';
40-
stats['video codec'] =
41-
'${firstStats.mimeType}, ${firstStats.clockRate}hz, pt: ${firstStats.payloadType}';
41+
stats['codec'] =
42+
'${firstStats.mimeType!.split('/')[1]}/${firstStats.clockRate}';
43+
stats['payload'] = '${firstStats.payloadType}';
4244
stats['qualityLimitationReason'] =
4345
firstStats.qualityLimitationReason ?? '';
4446
}
47+
48+
this.stats['video']!.addEntries(stats.entries);
4549
});
4650
});
4751
} else if (track is RemoteVideoTrack) {
4852
statsType = StatsType.kRemoteVideoReceiver;
4953
listener.on<VideoReceiverStatsEvent>((event) {
54+
Map<String, String> stats = {};
5055
setState(() {
51-
stats['video rx'] = '${event.currentBitrate.toInt()} kpbs';
52-
stats['video codec'] =
53-
'${event.stats.mimeType}, ${event.stats.clockRate}hz, pt: ${event.stats.payloadType}';
54-
stats['video size'] =
56+
stats['rx'] = '${event.currentBitrate.toInt()} kpbs';
57+
stats['codec'] =
58+
'${event.stats.mimeType!.split('/')[1]}/${event.stats.clockRate}';
59+
stats['payload'] = '${event.stats.payloadType}';
60+
stats['size/fps'] =
5561
'${event.stats.frameWidth}x${event.stats.frameHeight} ${event.stats.framesPerSecond?.toDouble()}fps';
56-
stats['video jitter'] = '${event.stats.jitter} s';
57-
stats['video decoder'] = '${event.stats.decoderImplementation}';
62+
stats['jitter'] = '${event.stats.jitter} s';
63+
stats['decoder'] = '${event.stats.decoderImplementation}';
5864
//stats['video packets lost'] = '${event.stats.packetsLost}';
5965
//stats['video packets received'] = '${event.stats.packetsReceived}';
60-
stats['video frames received'] = '${event.stats.framesReceived}';
61-
stats['video frames decoded'] = '${event.stats.framesDecoded}';
62-
stats['video frames dropped'] = '${event.stats.framesDropped}';
66+
stats['frames received'] = '${event.stats.framesReceived}';
67+
stats['frames decoded'] = '${event.stats.framesDecoded}';
68+
stats['frames dropped'] = '${event.stats.framesDropped}';
69+
70+
this.stats['video']!.addEntries(stats.entries);
6371
});
6472
});
6573
} else if (track is LocalAudioTrack) {
6674
statsType = StatsType.kLocalAudioSender;
6775
listener.on<AudioSenderStatsEvent>((event) {
76+
Map<String, String> stats = {};
6877
setState(() {
69-
stats['audio tx'] = '${event.currentBitrate.toInt()} kpbs';
70-
stats['audio codec'] =
71-
'${event.stats.mimeType}, ${event.stats.clockRate}hz, ${event.stats.channels}ch, pt: ${event.stats.payloadType}';
78+
stats['tx'] = '${event.currentBitrate.toInt()} kpbs';
79+
stats['codec'] =
80+
'${event.stats.mimeType!.split('/')[1]}/${event.stats.clockRate}/${event.stats.channels}';
81+
stats['payload'] = '${event.stats.payloadType}';
82+
this.stats['audio']!.addEntries(stats.entries);
7283
});
7384
});
7485
} else if (track is RemoteAudioTrack) {
7586
statsType = StatsType.kRemoteAudioReceiver;
7687
listener.on<AudioReceiverStatsEvent>((event) {
88+
Map<String, String> stats = {};
7789
setState(() {
78-
stats['audio rx'] = '${event.currentBitrate.toInt()} kpbs';
79-
stats['audio codec'] =
80-
'${event.stats.mimeType}, ${event.stats.clockRate}hz, ${event.stats.channels}ch, pt: ${event.stats.payloadType}';
81-
stats['audio jitter'] = '${event.stats.jitter} s';
82-
//stats['audio concealed samples'] =
90+
stats['rx'] = '${event.currentBitrate.toInt()} kpbs';
91+
stats['codec'] =
92+
'${event.stats.mimeType!.split('/')[1]}/${event.stats.clockRate}/${event.stats.channels}';
93+
stats['payload'] = '${event.stats.payloadType}';
94+
stats['jitter'] = '${event.stats.jitter} s';
95+
//stats['concealed samples'] =
8396
// '${event.stats.concealedSamples} / ${event.stats.concealmentEvents}';
84-
stats['audio packets lost'] = '${event.stats.packetsLost}';
85-
stats['audio packets received'] = '${event.stats.packetsReceived}';
97+
stats['packets lost'] = '${event.stats.packetsLost}';
98+
stats['packets received'] = '${event.stats.packetsReceived}';
99+
100+
this.stats['audio']!.addEntries(stats.entries);
86101
});
87102
});
88103
}
@@ -130,9 +145,14 @@ class _ParticipantStatsWidgetState extends State<ParticipantStatsWidget> {
130145
vertical: 8,
131146
horizontal: 8,
132147
),
133-
child: Column(
134-
children:
135-
stats.entries.map((e) => Text('${e.key}: ${e.value}')).toList()),
148+
child: Column(children: [
149+
const Text('audio stats',
150+
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16)),
151+
...stats['audio']!.entries.map((e) => Text('${e.key}: ${e.value}')),
152+
const Text('video stats',
153+
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16)),
154+
...stats['video']!.entries.map((e) => Text('${e.key}: ${e.value}')),
155+
]),
136156
);
137157
}
138158
}

0 commit comments

Comments
 (0)