From 439c8ef5e078d4938411ec6583c61f55c6d75641 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Sun, 23 Feb 2025 09:35:40 +0800 Subject: [PATCH] release: 1.5.2. --- CHANGELOG.md | 4 +++ lib/src/rtc_data_channel_impl.dart | 54 ++++++++++++---------------- lib/src/rtc_peerconnection_impl.dart | 20 ++++++++--- lib/src/rtc_rtp_parameters_impl.dart | 11 +++--- lib/src/rtc_rtp_receiver_impl.dart | 22 +++++++++--- lib/src/rtc_rtp_sender_impl.dart | 19 +++++++--- pubspec.yaml | 4 +-- web/main.dart | 22 ++++++++++++ 8 files changed, 106 insertions(+), 50 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 82999b3..caf5c73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ -------------------------------------------- +[1.5.2] - 2025-02-23. + +* fix stats for web. + [1.5.1] - 2025-02-15 * fix E2EE for firefox. diff --git a/lib/src/rtc_data_channel_impl.dart b/lib/src/rtc_data_channel_impl.dart index 71218d1..eb6010b 100644 --- a/lib/src/rtc_data_channel_impl.dart +++ b/lib/src/rtc_data_channel_impl.dart @@ -8,37 +8,29 @@ class RTCDataChannelWeb extends RTCDataChannel { RTCDataChannelWeb(this._jsDc) { stateChangeStream = _stateChangeController.stream; messageStream = _messageController.stream; - _jsDc.addEventListener( - 'close', - (web.Event _) { - _state = RTCDataChannelState.RTCDataChannelClosed; - _stateChangeController.add(_state); - onDataChannelState?.call(_state); - }.toJS, - false.toJS); - _jsDc.addEventListener( - 'open', - (web.Event _) { - _state = RTCDataChannelState.RTCDataChannelOpen; - _stateChangeController.add(_state); - onDataChannelState?.call(_state); - }.toJS, - false.toJS); - _jsDc.addEventListener( - 'message', - (web.MessageEvent event) { - _parse(event.data).then((msg) { - _messageController.add(msg); - onMessage?.call(msg); - }); - }.toJS, - false.toJS); - _jsDc.addEventListener( - 'bufferedamountlow', - (web.Event _) { - onBufferedAmountLow?.call(bufferedAmount ?? 0); - }.toJS, - false.toJS); + + _jsDc.onclose = (web.Event _) { + _state = RTCDataChannelState.RTCDataChannelClosed; + _stateChangeController.add(_state); + onDataChannelState?.call(_state); + }.toJS; + + _jsDc.onopen = (web.Event _) { + _state = RTCDataChannelState.RTCDataChannelOpen; + _stateChangeController.add(_state); + onDataChannelState?.call(_state); + }.toJS; + + _jsDc.onmessage = (web.MessageEvent event) { + _parse(event.data.dartify()).then((msg) { + _messageController.add(msg); + onMessage?.call(msg); + }); + }.toJS; + + _jsDc.onbufferedamountlow = (web.Event _) { + onBufferedAmountLow?.call(bufferedAmount ?? 0); + }.toJS; } final web.RTCDataChannel _jsDc; diff --git a/lib/src/rtc_peerconnection_impl.dart b/lib/src/rtc_peerconnection_impl.dart index 1cc958c..8d171a0 100644 --- a/lib/src/rtc_peerconnection_impl.dart +++ b/lib/src/rtc_peerconnection_impl.dart @@ -1,5 +1,7 @@ import 'dart:async'; +import 'dart:collection'; import 'dart:js_interop'; +import 'dart:js_interop_unsafe'; import 'package:dart_webrtc/dart_webrtc.dart'; import 'package:platform_detect/platform_detect.dart'; @@ -321,10 +323,20 @@ class RTCPeerConnectionWeb extends RTCPeerConnection { } var report = []; - stats.forEach((key, value) { - report.add( - StatsReport(value['id'], value['type'], value['timestamp'], value)); - }); + stats.callMethodVarArgs('forEach'.toJS, [ + (JSObject value, JSAny key) { + var map = value.dartify() as LinkedHashMap; + var stats = {}; + for (var entry in map.entries) { + stats[(entry.key as JSString).toDart] = entry.value; + } + report.add(StatsReport( + value.getProperty('id'.toJS).toDart, + value.getProperty('type'.toJS).toDart, + value.getProperty('timestamp'.toJS).toDartDouble, + stats)); + }.jsify() + ]); return report; } diff --git a/lib/src/rtc_rtp_parameters_impl.dart b/lib/src/rtc_rtp_parameters_impl.dart index b192dd9..54c7881 100644 --- a/lib/src/rtc_rtp_parameters_impl.dart +++ b/lib/src/rtc_rtp_parameters_impl.dart @@ -70,14 +70,17 @@ class RTCHeaderExtensionWeb { class RTCRtpEncodingWeb { static RTCRtpEncoding fromJsObject(web.RTCRtpEncodingParameters object) { return RTCRtpEncoding.fromMap({ - 'rid': object.rid, + 'rid': object.getProperty('rid'.toJS)?.toDart, 'active': object.active, - 'maxBitrate': object.maxBitrate, - 'maxFramerate': object.maxFramerate.toInt(), + 'maxBitrate': object.getProperty('maxBitrate'.toJS)?.toDartInt, + 'maxFramerate': + object.getProperty('maxFramerate'.toJS)?.toDartInt, 'minBitrate': object.getProperty('minBitrate'.toJS)?.toDartInt, 'numTemporalLayers': object.getProperty('numTemporalLayers'.toJS)?.toDartInt, - 'scaleResolutionDownBy': object.scaleResolutionDownBy, + 'scaleResolutionDownBy': object + .getProperty('scaleResolutionDownBy'.toJS) + ?.toDartDouble, 'ssrc': object.getProperty('ssrc'.toJS)?.toDart }); } diff --git a/lib/src/rtc_rtp_receiver_impl.dart b/lib/src/rtc_rtp_receiver_impl.dart index 99db83d..b017b6e 100644 --- a/lib/src/rtc_rtp_receiver_impl.dart +++ b/lib/src/rtc_rtp_receiver_impl.dart @@ -1,4 +1,6 @@ +import 'dart:collection'; import 'dart:js_interop'; +import 'dart:js_interop_unsafe'; import 'package:web/web.dart' as web; import 'package:webrtc_interface/webrtc_interface.dart'; @@ -14,12 +16,22 @@ class RTCRtpReceiverWeb extends RTCRtpReceiver { @override Future> getStats() async { - var stats = (await _jsRtpReceiver.getStats().toDart) as JSObject; + var stats = await _jsRtpReceiver.getStats().toDart; var report = []; - (stats.dartify() as Map).forEach((key, value) { - report.add( - StatsReport(value['id'], value['type'], value['timestamp'], value)); - }); + stats.callMethodVarArgs('forEach'.toJS, [ + (JSObject value, JSAny key) { + var map = value.dartify() as LinkedHashMap; + var stats = {}; + for (var entry in map.entries) { + stats[(entry.key as JSString).toDart] = entry.value; + } + report.add(StatsReport( + value.getProperty('id'.toJS).toDart, + value.getProperty('type'.toJS).toDart, + value.getProperty('timestamp'.toJS).toDartDouble, + stats)); + }.jsify() + ]); return report; } diff --git a/lib/src/rtc_rtp_sender_impl.dart b/lib/src/rtc_rtp_sender_impl.dart index ae20e6c..38b40c2 100644 --- a/lib/src/rtc_rtp_sender_impl.dart +++ b/lib/src/rtc_rtp_sender_impl.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:collection'; import 'dart:js_interop'; import 'dart:js_interop_unsafe'; @@ -85,10 +86,20 @@ class RTCRtpSenderWeb extends RTCRtpSender { Future> getStats() async { var stats = await _jsRtpSender.getStats().toDart; var report = []; - (stats.dartify() as Map).forEach((key, value) { - report.add( - StatsReport(value['id'], value['type'], value['timestamp'], value)); - }); + stats.callMethodVarArgs('forEach'.toJS, [ + (JSObject value, JSAny key) { + var map = value.dartify() as LinkedHashMap; + var stats = {}; + for (var entry in map.entries) { + stats[(entry.key as JSString).toDart] = entry.value; + } + report.add(StatsReport( + value.getProperty('id'.toJS).toDart, + value.getProperty('type'.toJS).toDart, + value.getProperty('timestamp'.toJS).toDartDouble, + stats)); + }.jsify() + ]); return report; } diff --git a/pubspec.yaml b/pubspec.yaml index a39e83a..94364ce 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: dart_webrtc description: Use the dart/js library to re-wrap the webrtc js interface of the browser, to adapted common browsers. -version: 1.5.1 +version: 1.5.2 homepage: https://github.com/flutter-webrtc/dart-webrtc environment: @@ -11,7 +11,7 @@ dependencies: js: ">0.6.0 <0.8.0" logging: ^1.1.0 meta: ^1.8.0 - platform_detect: ^2.1.0 + platform_detect: ^2.1.5 synchronized: ^3.0.0+3 web: ^1.0.0 webrtc_interface: ^1.2.1 diff --git a/web/main.dart b/web/main.dart index 7bcbe7e..cf1cd78 100644 --- a/web/main.dart +++ b/web/main.dart @@ -254,4 +254,26 @@ void loopBackTest() async { key: Uint8List.fromList('testkey2'.codeUnits)); */ + + Timer.periodic(Duration(seconds: 1), (timer) async { + var senders = await pc1.getSenders(); + var receivers = await pc2.getReceivers(); + + print('senders: ${senders.length}'); + print('receivers: ${receivers.length}'); + + senders.forEach((sender) { + sender.getStats().then((stats) { + print( + 'sender stats: ${stats.map((e) => 'id: ${e.id}, type: ${e.type}, timestamp: ${e.timestamp}, values: ${e.values.toString()} ')}'); + }); + }); + + receivers.forEach((receiver) { + receiver.getStats().then((stats) { + print( + 'receiver stats: ${stats.map((e) => 'id: ${e.id}, type: ${e.type}, timestamp: ${e.timestamp}, values: ${e.values.toString()} ')}'); + }); + }); + }); }