From bdc1555ba76d18dc9b6eec2d0c793ec2e690a0e7 Mon Sep 17 00:00:00 2001 From: CloudWebRTC Date: Mon, 8 Apr 2024 18:49:14 +0800 Subject: [PATCH 01/36] Update publish.yaml --- .github/workflows/publish.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index 4ae46b2..78a6d59 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -13,9 +13,9 @@ jobs: - name: Checkout uses: actions/checkout@v1 - name: Publish - uses: sakebook/actions-flutter-pub-publisher@v1.3.1 + uses: k-paxian/dart-package-publisher@v1.5.1 with: - credential: ${{ secrets.CREDENTIAL_JSON }} - flutter_package: true - skip_test: true - dry_run: false + credentialJson: ${{ secrets.CREDENTIAL_JSON }} + flutter: true + skipTests: true + force: true From e15d496f29f4f207ca4b8ba420420b580fbda586 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Mon, 8 Apr 2024 18:52:53 +0800 Subject: [PATCH 02/36] update CHANGELOG.md. --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index adceea3..ae49d78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog -------------------------------------------- +[1.3.0] - 2024-04-08 + +* update to package:web by @jezell in #29. + [1.2.1] - 2024-02-05 * Downgrade some dependencies make more compatible. From a11a6ded3b39f95dfff2cc5f9600f87cd0417068 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Mon, 8 Apr 2024 21:44:30 +0800 Subject: [PATCH 03/36] feat: add keyRingSize/discardFrameWhenCryptorNotReady to KeyProviderOptions. --- lib/src/e2ee.worker/e2ee.cryptor.dart | 6 ++++++ lib/src/e2ee.worker/e2ee.keyhandler.dart | 17 +++++++++++++---- lib/src/e2ee.worker/e2ee.worker.dart | 5 ++++- lib/src/frame_cryptor_impl.dart | 3 +++ pubspec.yaml | 2 +- web/main.dart | 13 +++++++++++-- 6 files changed, 38 insertions(+), 8 deletions(-) diff --git a/lib/src/e2ee.worker/e2ee.cryptor.dart b/lib/src/e2ee.worker/e2ee.cryptor.dart index e731f2f..e871317 100644 --- a/lib/src/e2ee.worker/e2ee.cryptor.dart +++ b/lib/src/e2ee.worker/e2ee.cryptor.dart @@ -301,6 +301,9 @@ class FrameCryptor { if (!enabled || // skip for encryption for empty dtx frames buffer.isEmpty) { + if (keyOptions.discardFrameWhenCryptorNotReady) { + return; + } controller.enqueue(frame); return; } @@ -405,6 +408,9 @@ class FrameCryptor { // skip for encryption for empty dtx frames buffer.isEmpty) { sifGuard.recordUserFrame(); + if (keyOptions.discardFrameWhenCryptorNotReady) { + return; + } controller.enqueue(frame); return; } diff --git a/lib/src/e2ee.worker/e2ee.keyhandler.dart b/lib/src/e2ee.worker/e2ee.keyhandler.dart index 84f9c2a..e7feae6 100644 --- a/lib/src/e2ee.worker/e2ee.keyhandler.dart +++ b/lib/src/e2ee.worker/e2ee.keyhandler.dart @@ -8,6 +8,8 @@ import 'crypto.dart' as crypto; import 'e2ee.logger.dart'; import 'e2ee.utils.dart'; +const KEYRING_SIZE = 16; + class KeyOptions { KeyOptions({ required this.sharedKey, @@ -15,12 +17,16 @@ class KeyOptions { required this.ratchetWindowSize, this.uncryptedMagicBytes, this.failureTolerance = -1, + this.keyRingSze = KEYRING_SIZE, + this.discardFrameWhenCryptorNotReady = false, }); bool sharedKey; Uint8List ratchetSalt; int ratchetWindowSize = 0; int failureTolerance; Uint8List? uncryptedMagicBytes; + int keyRingSze; + bool discardFrameWhenCryptorNotReady; @override String toString() { @@ -77,8 +83,6 @@ class KeyProvider { } } -const KEYRING_SIZE = 16; - class KeySet { KeySet(this.material, this.encryptionKey); web.CryptoKey material; @@ -90,10 +94,15 @@ class ParticipantKeyHandler { required this.worker, required this.keyOptions, required this.participantIdentity, - }); + }) { + if (keyOptions.keyRingSze <= 0 || keyOptions.keyRingSze > 255) { + throw Exception('Invalid key ring size'); + } + cryptoKeyRing = List.filled(keyOptions.keyRingSze, null); + } int currentKeyIndex = 0; - List cryptoKeyRing = List.filled(KEYRING_SIZE, null); + late List cryptoKeyRing; bool _hasValidKey = false; diff --git a/lib/src/e2ee.worker/e2ee.worker.dart b/lib/src/e2ee.worker/e2ee.worker.dart index 17d555a..fac64b0 100644 --- a/lib/src/e2ee.worker/e2ee.worker.dart +++ b/lib/src/e2ee.worker/e2ee.worker.dart @@ -118,7 +118,10 @@ void main() async { uncryptedMagicBytes: options['uncryptedMagicBytes'] != null ? Uint8List.fromList( base64Decode(options['uncryptedMagicBytes'] as String)) - : null); + : null, + keyRingSze: options['keyRingSize'] ?? KEYRING_SIZE, + discardFrameWhenCryptorNotReady: + options['discardFrameWhenCryptorNotReady'] ?? false); logger.config( 'Init with keyProviderOptions:\n ${keyProviderOptions.toString()}'); diff --git a/lib/src/frame_cryptor_impl.dart b/lib/src/frame_cryptor_impl.dart index 9e16bf4..db66d52 100644 --- a/lib/src/frame_cryptor_impl.dart +++ b/lib/src/frame_cryptor_impl.dart @@ -193,6 +193,9 @@ class KeyProviderImpl implements KeyProvider { 'ratchetWindowSize': options.ratchetWindowSize, if (options.uncryptedMagicBytes != null) 'uncryptedMagicBytes': base64Encode(options.uncryptedMagicBytes!), + 'keyRingSize': options.keyRingSize, + 'discardFrameWhenCryptorNotReady': + options.discardFrameWhenCryptorNotReady, }, }) ]); diff --git a/pubspec.yaml b/pubspec.yaml index 5682271..925629e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -14,7 +14,7 @@ dependencies: platform_detect: ^2.0.7 synchronized: ^3.0.0+3 web: ^0.5.1 - webrtc_interface: ^1.1.2 + webrtc_interface: ^1.2.0 dev_dependencies: build_runner: ^2.3.3 diff --git a/web/main.dart b/web/main.dart index 8dd8300..4bbed71 100644 --- a/web/main.dart +++ b/web/main.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'dart:typed_data'; import 'package:dart_webrtc/dart_webrtc.dart'; @@ -49,7 +50,8 @@ void loopBackTest() async { sharedKey: false, ratchetWindowSize: 16, failureTolerance: -1, - ratchetSalt: Uint8List.fromList('testSalt'.codeUnits)); + ratchetSalt: Uint8List.fromList('testSalt'.codeUnits), + discardFrameWhenCryptorNotReady: true); var keyProvider = await frameCryptorFactory.createDefaultKeyProvider(keyProviderOptions); @@ -73,7 +75,14 @@ void loopBackTest() async { receiver: event.receiver!, algorithm: Algorithm.kAesGcm, keyProvider: keyProvider); - await fc.setEnabled(true); + if (keyProviderOptions.discardFrameWhenCryptorNotReady) { + Timer(Duration(seconds: 2), () { + fc.setEnabled(true); + }); + } else { + await fc.setEnabled(true); + } + await fc.setKeyIndex(0); await fc.updateCodec('vp8'); pc2FrameCryptors.add(fc); From 8aa3647e5cd849a0a22ea06ecfc4b40750385ade Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Mon, 8 Apr 2024 22:34:04 +0800 Subject: [PATCH 04/36] update. --- CHANGELOG.md | 4 ++++ pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae49d78..525d560 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog -------------------------------------------- +[1.3.1] - 2024-04-08 + +* Add keyRingSize/discardFrameWhenCryptorNotReady to KeyProviderOptions. + [1.3.0] - 2024-04-08 * update to package:web by @jezell in #29. diff --git a/pubspec.yaml b/pubspec.yaml index 925629e..1f37dd0 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.3.0 +version: 1.3.1 homepage: https://github.com/flutter-webrtc/dart-webrtc environment: From 6e196692bc2e40d878a522df7c8df5a0ae05f768 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Tue, 9 Apr 2024 08:17:08 +0800 Subject: [PATCH 05/36] fix data channel init error. --- lib/src/rtc_peerconnection_impl.dart | 36 ++++++++++++++++++---------- web/main.dart | 12 +++++++--- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/lib/src/rtc_peerconnection_impl.dart b/lib/src/rtc_peerconnection_impl.dart index 17e6f04..d57a661 100644 --- a/lib/src/rtc_peerconnection_impl.dart +++ b/lib/src/rtc_peerconnection_impl.dart @@ -8,9 +8,7 @@ import 'package:dart_webrtc/dart_webrtc.dart'; import 'package:js/js_util.dart'; import 'package:platform_detect/platform_detect.dart'; import 'package:web/web.dart' as web; -import 'package:webrtc_interface/webrtc_interface.dart'; -import 'media_stream_impl.dart'; import 'media_stream_track_impl.dart'; import 'rtc_data_channel_impl.dart'; import 'rtc_dtmf_sender_impl.dart'; @@ -18,6 +16,10 @@ import 'rtc_rtp_receiver_impl.dart'; import 'rtc_rtp_sender_impl.dart'; import 'rtc_rtp_transceiver_impl.dart'; +extension on web.RTCDataChannelInit { + external set binaryType(String value); +} + /* * PeerConnection */ @@ -395,21 +397,29 @@ class RTCPeerConnectionWeb extends RTCPeerConnection { @override Future createDataChannel( String label, RTCDataChannelInit dataChannelDict) { - final map = dataChannelDict.toMap(); + var dcInit = web.RTCDataChannelInit( + id: dataChannelDict.id, + ordered: dataChannelDict.ordered, + protocol: dataChannelDict.protocol, + negotiated: dataChannelDict.negotiated, + ); + if (dataChannelDict.binaryType == 'binary') { - map['binaryType'] = 'arraybuffer'; // Avoid Blob in data channel + dcInit.binaryType = 'arraybuffer'; // Avoid Blob in data channel + } + + if (dataChannelDict.maxRetransmits > 0) { + dcInit.maxRetransmits = dataChannelDict.maxRetransmits; + } + + if (dataChannelDict.maxRetransmitTime > 0) { + dcInit.maxPacketLifeTime = dataChannelDict.maxRetransmitTime; } final jsDc = _jsPc.createDataChannel( - label, - web.RTCDataChannelInit( - id: map['id'], - ordered: map['ordered'], - maxPacketLifeTime: map['maxPacketLifeTime'], - maxRetransmits: map['maxRetransmits'], - protocol: map['protocol'], - negotiated: map['negotiated'], - )); + label, + dcInit, + ); return Future.value(RTCDataChannelWeb(jsDc)); } diff --git a/web/main.dart b/web/main.dart index 4bbed71..dd071fb 100644 --- a/web/main.dart +++ b/web/main.dart @@ -76,7 +76,7 @@ void loopBackTest() async { algorithm: Algorithm.kAesGcm, keyProvider: keyProvider); if (keyProviderOptions.discardFrameWhenCryptorNotReady) { - Timer(Duration(seconds: 2), () { + Timer(Duration(seconds: 1), () { fc.setEnabled(true); }); } else { @@ -84,7 +84,9 @@ void loopBackTest() async { } await fc.setKeyIndex(0); - await fc.updateCodec('vp8'); + if (event.track.kind == 'video') { + await fc.updateCodec('vp8'); + } pc2FrameCryptors.add(fc); }; pc2.onConnectionState = (state) { @@ -138,7 +140,9 @@ void loopBackTest() async { keyProvider: keyProvider); await fc.setEnabled(true); await fc.setKeyIndex(0); - await fc.updateCodec('vp8'); + if (track.kind == 'video') { + await fc.updateCodec('vp8'); + } pc1FrameCryptors.add(fc); }); /* @@ -163,6 +167,8 @@ void loopBackTest() async { } }); */ + var dc = await pc1.createDataChannel( + 'label', RTCDataChannelInit()..binaryType = 'binary'); var offer = await pc1.createOffer(); await pc2.addTransceiver( From dd7c8ba491f1351c44a5d39820b2a19004215719 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Tue, 9 Apr 2024 08:18:26 +0800 Subject: [PATCH 06/36] bump version. --- CHANGELOG.md | 4 ++++ pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 525d560..3d517ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog -------------------------------------------- +[1.3.2] - 2024-04-09 + +* Fix error when constructing RTCDataChannelInit. + [1.3.1] - 2024-04-08 * Add keyRingSize/discardFrameWhenCryptorNotReady to KeyProviderOptions. diff --git a/pubspec.yaml b/pubspec.yaml index 1f37dd0..aa8a061 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.3.1 +version: 1.3.2 homepage: https://github.com/flutter-webrtc/dart-webrtc environment: From ce00dde5a9458e3c601f65370afd522fe8a71bf3 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Tue, 9 Apr 2024 08:59:54 +0800 Subject: [PATCH 07/36] * Fix DC data parse. --- CHANGELOG.md | 4 ++++ lib/src/rtc_data_channel_impl.dart | 8 +++----- pubspec.yaml | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d517ef..2939b7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog -------------------------------------------- +[1.3.3] - 2024-04-09 + +* Fix DC data parse. + [1.3.2] - 2024-04-09 * Fix error when constructing RTCDataChannelInit. diff --git a/lib/src/rtc_data_channel_impl.dart b/lib/src/rtc_data_channel_impl.dart index 230e13d..41fb773 100644 --- a/lib/src/rtc_data_channel_impl.dart +++ b/lib/src/rtc_data_channel_impl.dart @@ -70,12 +70,10 @@ class RTCDataChannelWeb extends RTCDataChannel { return RTCDataChannelMessage(data); } dynamic arrayBuffer; - if (data is web.Blob) { - // This should never happen actually - arrayBuffer = await jsutil - .promiseToFuture(jsutil.callMethod(data, 'arrayBuffer', [])); + if (data is JSArrayBuffer) { + arrayBuffer = data.toDart; } else { - arrayBuffer = data; + arrayBuffer = data.toString(); } return RTCDataChannelMessage.fromBinary(arrayBuffer.asUint8List()); } diff --git a/pubspec.yaml b/pubspec.yaml index aa8a061..61da252 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.3.2 +version: 1.3.3 homepage: https://github.com/flutter-webrtc/dart-webrtc environment: From 6ac191bfde877d26d6119a3d96011e3fd920dd64 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Tue, 9 Apr 2024 09:03:35 +0800 Subject: [PATCH 08/36] remove Unused import. --- lib/src/rtc_data_channel_impl.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/src/rtc_data_channel_impl.dart b/lib/src/rtc_data_channel_impl.dart index 41fb773..a9ab3f7 100644 --- a/lib/src/rtc_data_channel_impl.dart +++ b/lib/src/rtc_data_channel_impl.dart @@ -1,6 +1,5 @@ import 'dart:async'; import 'dart:js_interop'; -import 'dart:js_util' as jsutil; import 'package:web/web.dart' as web; import 'package:webrtc_interface/webrtc_interface.dart'; From b78d7c724067d80ae74351e876e1101b52cfc9d9 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Tue, 9 Apr 2024 10:13:43 +0800 Subject: [PATCH 09/36] release: 1.4.0. --- CHANGELOG.md | 4 ++++ lib/src/factory_impl.dart | 3 ++- lib/src/rtc_peerconnection_impl.dart | 9 ++------- lib/src/utils.dart | 27 +++++++++++++++++++++++++++ pubspec.yaml | 2 +- 5 files changed, 36 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2939b7a..2909fe1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog -------------------------------------------- +[1.4.0] - 2024-04-09 + +* Fixed bug for RTCConfiguration convert. + [1.3.3] - 2024-04-09 * Fix DC data parse. diff --git a/lib/src/factory_impl.dart b/lib/src/factory_impl.dart index 9b99e79..ee428b4 100644 --- a/lib/src/factory_impl.dart +++ b/lib/src/factory_impl.dart @@ -11,6 +11,7 @@ import 'media_stream_impl.dart'; import 'navigator_impl.dart'; import 'rtc_peerconnection_impl.dart'; import 'rtc_rtp_capailities_imp.dart'; +import 'utils.dart'; @JS('RTCRtpSender') @anonymous @@ -41,7 +42,7 @@ class RTCFactoryWeb extends RTCFactory { ], }; final jsRtcPc = web.RTCPeerConnection( - jsify({...constr, ...configuration}) as web.RTCConfiguration); + convertRTCConfiguration({...constr, ...configuration})); final _peerConnectionId = base64Encode(jsRtcPc.toString().codeUnits); return RTCPeerConnectionWeb(_peerConnectionId, jsRtcPc); } diff --git a/lib/src/rtc_peerconnection_impl.dart b/lib/src/rtc_peerconnection_impl.dart index d57a661..416fa43 100644 --- a/lib/src/rtc_peerconnection_impl.dart +++ b/lib/src/rtc_peerconnection_impl.dart @@ -15,6 +15,7 @@ import 'rtc_dtmf_sender_impl.dart'; import 'rtc_rtp_receiver_impl.dart'; import 'rtc_rtp_sender_impl.dart'; import 'rtc_rtp_transceiver_impl.dart'; +import 'utils.dart'; extension on web.RTCDataChannelInit { external set binaryType(String value); @@ -263,13 +264,7 @@ class RTCPeerConnectionWeb extends RTCPeerConnection { @override Future setConfiguration(Map configuration) { _configuration.addAll(configuration); - - final object = jsutil.newObject(); - for (var key in configuration.keys) { - jsutil.setProperty(object, key, configuration[key]); - } - - _jsPc.setConfiguration(object as web.RTCConfiguration); + _jsPc.setConfiguration(convertRTCConfiguration(configuration)); return Future.value(); } diff --git a/lib/src/utils.dart b/lib/src/utils.dart index 7bd218e..3f34feb 100644 --- a/lib/src/utils.dart +++ b/lib/src/utils.dart @@ -1,4 +1,6 @@ +import 'dart:js_util' as jsutil; import 'dart:math'; + import 'package:web/web.dart' as web; bool get isMobile { @@ -25,3 +27,28 @@ String randomString(int length) { } return buf.toString(); } + +web.RTCConfiguration convertRTCConfiguration( + Map configuration) { + final object = jsutil.newObject(); + for (var key in configuration.keys) { + if (key == 'iceServers') { + final servers = configuration[key] as List; + final jsServers = []; + for (var server in servers) { + var iceServer = web.RTCIceServer(urls: server['urls']); + if (server['username'] != null) { + iceServer.username = server['username']; + } + if (server['credential'] != null) { + iceServer.credential = server['credential']; + } + jsServers.add(iceServer); + } + jsutil.setProperty(object, key, jsServers); + } else { + jsutil.setProperty(object, key, configuration[key]); + } + } + return object as web.RTCConfiguration; +} diff --git a/pubspec.yaml b/pubspec.yaml index 61da252..ad8d2e4 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.3.3 +version: 1.4.0 homepage: https://github.com/flutter-webrtc/dart-webrtc environment: From 46428da752158eda9600d74d72c87c5ca9383c6c Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Fri, 12 Apr 2024 19:19:52 +0800 Subject: [PATCH 10/36] remove RTCConfiguration convert. --- CHANGELOG.md | 4 ++++ lib/src/factory_impl.dart | 2 +- lib/src/rtc_peerconnection_impl.dart | 3 +-- lib/src/utils.dart | 25 ------------------------- pubspec.yaml | 2 +- 5 files changed, 7 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2909fe1..031c90b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog -------------------------------------------- +[1.4.1] - 2024-04-12 + +* remove RTCConfiguration convert. + [1.4.0] - 2024-04-09 * Fixed bug for RTCConfiguration convert. diff --git a/lib/src/factory_impl.dart b/lib/src/factory_impl.dart index ee428b4..20c1062 100644 --- a/lib/src/factory_impl.dart +++ b/lib/src/factory_impl.dart @@ -42,7 +42,7 @@ class RTCFactoryWeb extends RTCFactory { ], }; final jsRtcPc = web.RTCPeerConnection( - convertRTCConfiguration({...constr, ...configuration})); + {...constr, ...configuration} as web.RTCConfiguration); final _peerConnectionId = base64Encode(jsRtcPc.toString().codeUnits); return RTCPeerConnectionWeb(_peerConnectionId, jsRtcPc); } diff --git a/lib/src/rtc_peerconnection_impl.dart b/lib/src/rtc_peerconnection_impl.dart index 416fa43..a75c10b 100644 --- a/lib/src/rtc_peerconnection_impl.dart +++ b/lib/src/rtc_peerconnection_impl.dart @@ -15,7 +15,6 @@ import 'rtc_dtmf_sender_impl.dart'; import 'rtc_rtp_receiver_impl.dart'; import 'rtc_rtp_sender_impl.dart'; import 'rtc_rtp_transceiver_impl.dart'; -import 'utils.dart'; extension on web.RTCDataChannelInit { external set binaryType(String value); @@ -264,7 +263,7 @@ class RTCPeerConnectionWeb extends RTCPeerConnection { @override Future setConfiguration(Map configuration) { _configuration.addAll(configuration); - _jsPc.setConfiguration(convertRTCConfiguration(configuration)); + _jsPc.setConfiguration(configuration as web.RTCConfiguration); return Future.value(); } diff --git a/lib/src/utils.dart b/lib/src/utils.dart index 3f34feb..30bd835 100644 --- a/lib/src/utils.dart +++ b/lib/src/utils.dart @@ -27,28 +27,3 @@ String randomString(int length) { } return buf.toString(); } - -web.RTCConfiguration convertRTCConfiguration( - Map configuration) { - final object = jsutil.newObject(); - for (var key in configuration.keys) { - if (key == 'iceServers') { - final servers = configuration[key] as List; - final jsServers = []; - for (var server in servers) { - var iceServer = web.RTCIceServer(urls: server['urls']); - if (server['username'] != null) { - iceServer.username = server['username']; - } - if (server['credential'] != null) { - iceServer.credential = server['credential']; - } - jsServers.add(iceServer); - } - jsutil.setProperty(object, key, jsServers); - } else { - jsutil.setProperty(object, key, configuration[key]); - } - } - return object as web.RTCConfiguration; -} diff --git a/pubspec.yaml b/pubspec.yaml index ad8d2e4..9b00861 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.4.0 +version: 1.4.1 homepage: https://github.com/flutter-webrtc/dart-webrtc environment: From f39b9417013f87f6989779748f7d2c6cbe2242c1 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Mon, 15 Apr 2024 10:33:13 +0800 Subject: [PATCH 11/36] fix. --- CHANGELOG.md | 4 ++++ lib/src/factory_impl.dart | 2 +- lib/src/rtc_peerconnection_impl.dart | 2 +- pubspec.yaml | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 031c90b..4f78d95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog -------------------------------------------- +[1.4.2] - 2024-04-15 + +* fix. + [1.4.1] - 2024-04-12 * remove RTCConfiguration convert. diff --git a/lib/src/factory_impl.dart b/lib/src/factory_impl.dart index 20c1062..833f7a5 100644 --- a/lib/src/factory_impl.dart +++ b/lib/src/factory_impl.dart @@ -42,7 +42,7 @@ class RTCFactoryWeb extends RTCFactory { ], }; final jsRtcPc = web.RTCPeerConnection( - {...constr, ...configuration} as web.RTCConfiguration); + jsify({...constr, ...configuration}) as web.RTCConfiguration); final _peerConnectionId = base64Encode(jsRtcPc.toString().codeUnits); return RTCPeerConnectionWeb(_peerConnectionId, jsRtcPc); } diff --git a/lib/src/rtc_peerconnection_impl.dart b/lib/src/rtc_peerconnection_impl.dart index a75c10b..9f85d37 100644 --- a/lib/src/rtc_peerconnection_impl.dart +++ b/lib/src/rtc_peerconnection_impl.dart @@ -263,7 +263,7 @@ class RTCPeerConnectionWeb extends RTCPeerConnection { @override Future setConfiguration(Map configuration) { _configuration.addAll(configuration); - _jsPc.setConfiguration(configuration as web.RTCConfiguration); + _jsPc.setConfiguration(jsify(configuration) as web.RTCConfiguration); return Future.value(); } diff --git a/pubspec.yaml b/pubspec.yaml index 9b00861..923f1c1 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.4.1 +version: 1.4.2 homepage: https://github.com/flutter-webrtc/dart-webrtc environment: From 0025e43ea9acd61f24cd56a05b93f3faa58c8ed9 Mon Sep 17 00:00:00 2001 From: td Date: Thu, 18 Apr 2024 06:58:06 +0530 Subject: [PATCH 12/36] fix: do not fail if removing constraint fails --- lib/src/mediadevices_impl.dart | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/lib/src/mediadevices_impl.dart b/lib/src/mediadevices_impl.dart index 763e8f2..014d559 100644 --- a/lib/src/mediadevices_impl.dart +++ b/lib/src/mediadevices_impl.dart @@ -12,16 +12,20 @@ class MediaDevicesWeb extends MediaDevices { Future getUserMedia( Map mediaConstraints) async { try { - if (!isMobile) { - if (mediaConstraints['video'] is Map && - mediaConstraints['video']['facingMode'] != null) { - mediaConstraints['video'].remove('facingMode'); + try { + if (!isMobile) { + if (mediaConstraints['video'] is Map && + mediaConstraints['video']['facingMode'] != null) { + mediaConstraints['video'].remove('facingMode'); + } } + mediaConstraints.putIfAbsent('video', () => false); + mediaConstraints.putIfAbsent('audio', () => false); + } catch (e) { + print( + '[getUserMedia] failed to remove facingMode from mediaConstraints'); } - mediaConstraints.putIfAbsent('video', () => false); - mediaConstraints.putIfAbsent('audio', () => false); - final mediaDevices = html.window.navigator.mediaDevices; if (mediaDevices == null) throw Exception('MediaDevices is null'); From 327413b8247b60412c7b87090cd840a7856ab364 Mon Sep 17 00:00:00 2001 From: CloudWebRTC Date: Thu, 18 Apr 2024 19:55:57 +0800 Subject: [PATCH 13/36] Update mediadevices_impl.dart --- lib/src/mediadevices_impl.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/src/mediadevices_impl.dart b/lib/src/mediadevices_impl.dart index c315000..e04a600 100644 --- a/lib/src/mediadevices_impl.dart +++ b/lib/src/mediadevices_impl.dart @@ -20,8 +20,6 @@ class MediaDevicesWeb extends MediaDevices { mediaConstraints['video'].remove('facingMode'); } } - mediaConstraints.putIfAbsent('video', () => false); - mediaConstraints.putIfAbsent('audio', () => false); } catch (e) { print( '[getUserMedia] failed to remove facingMode from mediaConstraints'); From 0d38f4ffaf38ad93294f91a371c32671e7309b9b Mon Sep 17 00:00:00 2001 From: CloudWebRTC Date: Thu, 18 Apr 2024 22:21:17 +0800 Subject: [PATCH 14/36] Update pubspec.yaml --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 923f1c1..572cc3f 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.4.2 +version: 1.4.3 homepage: https://github.com/flutter-webrtc/dart-webrtc environment: From 571298fa680f764ed7aa0404c0feefc59c22acc4 Mon Sep 17 00:00:00 2001 From: CloudWebRTC Date: Thu, 18 Apr 2024 22:21:51 +0800 Subject: [PATCH 15/36] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f78d95..2a5d7e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog -------------------------------------------- +[1.4.3] - 2024-04-18 + +* fix: do not fail if removing constraint fails + [1.4.2] - 2024-04-15 * fix. From c0a3820d3b5342938685ca0d98379dd927b42c05 Mon Sep 17 00:00:00 2001 From: td Date: Mon, 22 Apr 2024 18:03:39 +0530 Subject: [PATCH 16/36] fix: tryCatch editing mediaConstraints --- lib/src/mediadevices_impl.dart | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/src/mediadevices_impl.dart b/lib/src/mediadevices_impl.dart index e04a600..a7d9192 100644 --- a/lib/src/mediadevices_impl.dart +++ b/lib/src/mediadevices_impl.dart @@ -20,14 +20,13 @@ class MediaDevicesWeb extends MediaDevices { mediaConstraints['video'].remove('facingMode'); } } + mediaConstraints.putIfAbsent('video', () => false); + mediaConstraints.putIfAbsent('audio', () => false); } catch (e) { print( '[getUserMedia] failed to remove facingMode from mediaConstraints'); } - mediaConstraints.putIfAbsent('video', () => false); - mediaConstraints.putIfAbsent('audio', () => false); - final mediaDevices = web.window.navigator.mediaDevices; if (jsutil.hasProperty(mediaDevices, 'getUserMedia')) { From bb6416bf0032d5c4bb2e6818b7a354b541abeead Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Wed, 24 Apr 2024 06:51:59 +0800 Subject: [PATCH 17/36] fix dc parse. --- lib/src/rtc_data_channel_impl.dart | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/src/rtc_data_channel_impl.dart b/lib/src/rtc_data_channel_impl.dart index a9ab3f7..08855f7 100644 --- a/lib/src/rtc_data_channel_impl.dart +++ b/lib/src/rtc_data_channel_impl.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'dart:js_interop'; +import 'package:js/js_util.dart' as jsutil; import 'package:web/web.dart' as web; import 'package:webrtc_interface/webrtc_interface.dart'; @@ -71,8 +72,11 @@ class RTCDataChannelWeb extends RTCDataChannel { dynamic arrayBuffer; if (data is JSArrayBuffer) { arrayBuffer = data.toDart; + } else if (data is web.Blob) { + arrayBuffer = await jsutil + .promiseToFuture(jsutil.callMethod(data, 'arrayBuffer', [])); } else { - arrayBuffer = data.toString(); + arrayBuffer = data.toDart; } return RTCDataChannelMessage.fromBinary(arrayBuffer.asUint8List()); } From 4e87ddcd22e76c7f095a9b24978aa09b1ac455d7 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Wed, 24 Apr 2024 06:54:30 +0800 Subject: [PATCH 18/36] release: 1.4.4. --- CHANGELOG.md | 5 +++++ pubspec.yaml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a5d7e4..61b2da8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ # Changelog -------------------------------------------- +[1.4.4] - 2024-04-24 + +* fix: datachannel message parse for Firefox. +* fix: tryCatch editing mediaConstraints #34 + [1.4.3] - 2024-04-18 * fix: do not fail if removing constraint fails diff --git a/pubspec.yaml b/pubspec.yaml index 572cc3f..b9c6a92 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.4.3 +version: 1.4.4 homepage: https://github.com/flutter-webrtc/dart-webrtc environment: From 84a0172f0cf586d122e1876dd9c9c624ac92000c Mon Sep 17 00:00:00 2001 From: Christopher Hull Date: Tue, 30 Apr 2024 09:54:23 -0600 Subject: [PATCH 19/36] fix type cast exception in getConstraints() --- lib/src/media_stream_track_impl.dart | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/src/media_stream_track_impl.dart b/lib/src/media_stream_track_impl.dart index 39f6b70..1c4b8d9 100644 --- a/lib/src/media_stream_track_impl.dart +++ b/lib/src/media_stream_track_impl.dart @@ -37,7 +37,9 @@ class MediaStreamTrackWeb extends MediaStreamTrack { @override Map getConstraints() { - return jsTrack.getConstraints() as Map; + final c = jsTrack.getConstraints(); + final jso = (c as JSObject).dartify(); + return (jso as Map).cast(); } @override @@ -47,7 +49,8 @@ class MediaStreamTrackWeb extends MediaStreamTrack { final arg = js.jsify(constraints ?? {}); final _val = await js.promiseToFuture( - js.callMethod(jsTrack, 'applyConstraints', [arg])); + js.callMethod(jsTrack, 'applyConstraints', [arg]), + ); return _val; } From 807413613a714c9de400d62b4d974fa799755f60 Mon Sep 17 00:00:00 2001 From: td Date: Mon, 13 May 2024 17:37:38 +0530 Subject: [PATCH 20/36] fix: negotiationNeeded listener --- lib/src/rtc_peerconnection_impl.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/rtc_peerconnection_impl.dart b/lib/src/rtc_peerconnection_impl.dart index 9f85d37..3ce9245 100644 --- a/lib/src/rtc_peerconnection_impl.dart +++ b/lib/src/rtc_peerconnection_impl.dart @@ -149,7 +149,7 @@ class RTCPeerConnectionWeb extends RTCPeerConnection { } _jsPc.addEventListener( - 'onnegotiationneeded', + 'negotiationneeded', (_) { onRenegotiationNeeded?.call(); }.toJS); From e16c87bd38f175faf8d83b1d0a961b4850d3cf77 Mon Sep 17 00:00:00 2001 From: td Date: Mon, 13 May 2024 17:44:24 +0530 Subject: [PATCH 21/36] chore: remove addstream and removestream events --- lib/src/rtc_peerconnection_impl.dart | 45 ---------------------------- 1 file changed, 45 deletions(-) diff --git a/lib/src/rtc_peerconnection_impl.dart b/lib/src/rtc_peerconnection_impl.dart index 3ce9245..e4da6cf 100644 --- a/lib/src/rtc_peerconnection_impl.dart +++ b/lib/src/rtc_peerconnection_impl.dart @@ -25,41 +25,6 @@ extension on web.RTCDataChannelInit { */ class RTCPeerConnectionWeb extends RTCPeerConnection { RTCPeerConnectionWeb(this._peerConnectionId, this._jsPc) { - _jsPc.addEventListener( - 'addstream', - (_RTCMediaStreamEvent mediaStreamEvent) { - final jsStream = mediaStreamEvent.stream; - - final _remoteStream = _remoteStreams.putIfAbsent( - jsStream.id, () => MediaStreamWeb(jsStream, _peerConnectionId)); - - onAddStream?.call(_remoteStream); - - jsStream.addEventListener( - 'addtrack', - (web.RTCTrackEvent mediaStreamTrackEvent) { - final jsTrack = - (mediaStreamTrackEvent as web.MediaStreamTrackEvent).track; - final track = MediaStreamTrackWeb(jsTrack); - _remoteStream.addTrack(track, addToNative: false).then((_) { - onAddTrack?.call(_remoteStream, track); - }); - }.toJS); - - jsStream.addEventListener( - 'removetrack', - (web.RTCTrackEvent mediaStreamTrackEvent) { - final jsTrack = - (mediaStreamTrackEvent as web.MediaStreamTrackEvent).track; - final track = MediaStreamTrackWeb(jsTrack); - _remoteStream - .removeTrack(track, removeFromNative: false) - .then((_) { - onRemoveTrack?.call(_remoteStream, track); - }); - }.toJS); - }.toJS); - _jsPc.addEventListener( 'datachannel', (dataChannelEvent) { @@ -121,16 +86,6 @@ class RTCPeerConnectionWeb extends RTCPeerConnection { onIceGatheringState?.call(_iceGatheringState!); })); - _jsPc.addEventListener( - 'removestream', - (_RTCMediaStreamEvent mediaStreamEvent) { - final _remoteStream = - _remoteStreams.remove(mediaStreamEvent.stream.id); - if (_remoteStream != null) { - onRemoveStream?.call(_remoteStream); - } - }.toJS); - _jsPc.addEventListener( 'signalingstatechange', (_) { From fe84e042915d6f6c1bd5340ed9b2c283838f318b Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Mon, 13 May 2024 21:16:51 +0800 Subject: [PATCH 22/36] release: 1.4.5. --- CHANGELOG.md | 4 ++++ pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 61b2da8..81c83fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog -------------------------------------------- +[1.4.5] - 2024-05-13 + +* fix: negotiationNeeded listener. + [1.4.4] - 2024-04-24 * fix: datachannel message parse for Firefox. diff --git a/pubspec.yaml b/pubspec.yaml index b9c6a92..ccf6f39 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.4.4 +version: 1.4.5 homepage: https://github.com/flutter-webrtc/dart-webrtc environment: From ab0438db5c41ff17e2fd45ea094ac2229b8ecb69 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Mon, 13 May 2024 21:20:00 +0800 Subject: [PATCH 23/36] update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81c83fa..f679361 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ [1.4.5] - 2024-05-13 * fix: negotiationNeeded listener. +* fix: fix type cast exception in getConstraints(). [1.4.4] - 2024-04-24 From 1009132a6a179db2a907a1c2ef083708fb2f07eb Mon Sep 17 00:00:00 2001 From: td Date: Tue, 28 May 2024 03:00:05 +0530 Subject: [PATCH 24/36] chore: add logs and increase worker msg timeout --- lib/src/frame_cryptor_impl.dart | 65 ++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 18 deletions(-) diff --git a/lib/src/frame_cryptor_impl.dart b/lib/src/frame_cryptor_impl.dart index db66d52..a598f1a 100644 --- a/lib/src/frame_cryptor_impl.dart +++ b/lib/src/frame_cryptor_impl.dart @@ -6,6 +6,7 @@ import 'dart:js_util' as jsutil; import 'dart:typed_data'; import 'package:collection/collection.dart'; +import 'package:dart_webrtc/src/e2ee.worker/e2ee.logger.dart'; import 'package:dart_webrtc/src/event.dart'; import 'package:js/js_util.dart'; import 'package:web/web.dart' as web; @@ -201,8 +202,11 @@ class KeyProviderImpl implements KeyProvider { ]); await events.waitFor( - filter: (event) => event.msgId == msgId, - duration: Duration(seconds: 5)); + filter: (event) { + logger.fine('waiting for init on msg: $msgId'); + return event.msgId == msgId; + }, + duration: Duration(seconds: 15)); } @override @@ -217,8 +221,11 @@ class KeyProviderImpl implements KeyProvider { ]); await events.waitFor( - filter: (event) => event.msgId == msgId, - duration: Duration(seconds: 5)); + filter: (event) { + logger.fine('waiting for dispose on msg: $msgId'); + return event.msgId == msgId; + }, + duration: Duration(seconds: 15)); _keys.clear(); } @@ -241,8 +248,12 @@ class KeyProviderImpl implements KeyProvider { ]); await events.waitFor( - filter: (event) => event.msgId == msgId, - duration: Duration(seconds: 5)); + filter: (event) { + logger.fine('waiting for setKey on msg: $msgId'); + return event.msgId == msgId; + }, + duration: Duration(minutes: 15), + ); _keys[participantId] ??= []; if (_keys[participantId]!.length <= index) { @@ -268,8 +279,11 @@ class KeyProviderImpl implements KeyProvider { ]); var res = await events.waitFor( - filter: (event) => event.msgId == msgId, - duration: Duration(seconds: 5)); + filter: (event) { + logger.fine('waiting for ratchetKey on msg: $msgId'); + return event.msgId == msgId; + }, + duration: Duration(seconds: 15)); return base64Decode(res.data['newKey']); } @@ -289,8 +303,11 @@ class KeyProviderImpl implements KeyProvider { ]); var res = await events.waitFor( - filter: (event) => event.msgId == msgId, - duration: Duration(seconds: 5)); + filter: (event) { + logger.fine('waiting for exportKey on msg: $msgId'); + return event.msgId == msgId; + }, + duration: Duration(seconds: 15)); return base64Decode(res.data['exportedKey']); } @@ -308,8 +325,11 @@ class KeyProviderImpl implements KeyProvider { ]); var res = await events.waitFor( - filter: (event) => event.msgId == msgId, - duration: Duration(seconds: 5)); + filter: (event) { + logger.fine('waiting for exportSharedKey on msg: $msgId'); + return event.msgId == msgId; + }, + duration: Duration(seconds: 15)); return base64Decode(res.data['exportedKey']); } @@ -326,8 +346,11 @@ class KeyProviderImpl implements KeyProvider { }) ]); var res = await events.waitFor( - filter: (event) => event.msgId == msgId, - duration: Duration(seconds: 5)); + filter: (event) { + logger.fine('waiting for ratchetSharedKey on msg: $msgId'); + return event.msgId == msgId; + }, + duration: Duration(seconds: 15)); return base64Decode(res.data['newKey']); } @@ -346,8 +369,11 @@ class KeyProviderImpl implements KeyProvider { ]); await events.waitFor( - filter: (event) => event.msgId == msgId, - duration: Duration(seconds: 5)); + filter: (event) { + logger.fine('waiting for setSharedKey on msg: $msgId'); + return event.msgId == msgId; + }, + duration: Duration(seconds: 15)); } @override @@ -363,8 +389,11 @@ class KeyProviderImpl implements KeyProvider { ]); await events.waitFor( - filter: (event) => event.msgId == msgId, - duration: Duration(seconds: 5)); + filter: (event) { + logger.fine('waiting for setSifTrailer on msg: $msgId'); + return event.msgId == msgId; + }, + duration: Duration(seconds: 15)); } } From c3c8c836c87858c095d853d75a89ef5f365d22b7 Mon Sep 17 00:00:00 2001 From: td Date: Tue, 28 May 2024 03:00:14 +0530 Subject: [PATCH 25/36] chore: formatting --- lib/src/e2ee.worker/e2ee.cryptor.dart | 2 +- lib/src/e2ee.worker/e2ee.worker.dart | 2 +- lib/src/factory_impl.dart | 1 + lib/src/frame_cryptor_impl.dart | 4 ++-- lib/src/media_recorder_impl.dart | 1 + lib/src/media_stream_impl.dart | 1 + lib/src/mediadevices_impl.dart | 1 + lib/src/rtc_data_channel_impl.dart | 1 + lib/src/rtc_peerconnection_impl.dart | 2 +- lib/src/rtc_rtp_capailities_imp.dart | 1 + lib/src/rtc_rtp_parameters_impl.dart | 1 + lib/src/rtc_rtp_receiver_impl.dart | 1 + lib/src/rtc_rtp_sender_impl.dart | 2 +- lib/src/rtc_transform_stream.dart | 1 + lib/src/rtc_video_element.dart | 2 ++ 15 files changed, 17 insertions(+), 6 deletions(-) diff --git a/lib/src/e2ee.worker/e2ee.cryptor.dart b/lib/src/e2ee.worker/e2ee.cryptor.dart index e871317..576389b 100644 --- a/lib/src/e2ee.worker/e2ee.cryptor.dart +++ b/lib/src/e2ee.worker/e2ee.cryptor.dart @@ -5,9 +5,9 @@ import 'dart:js_util' as jsutil; import 'dart:math'; import 'dart:typed_data'; -import 'package:dart_webrtc/src/rtc_transform_stream.dart'; import 'package:web/web.dart' as web; +import 'package:dart_webrtc/src/rtc_transform_stream.dart'; import 'crypto.dart' as crypto; import 'e2ee.keyhandler.dart'; import 'e2ee.logger.dart'; diff --git a/lib/src/e2ee.worker/e2ee.worker.dart b/lib/src/e2ee.worker/e2ee.worker.dart index fac64b0..fce7f33 100644 --- a/lib/src/e2ee.worker/e2ee.worker.dart +++ b/lib/src/e2ee.worker/e2ee.worker.dart @@ -4,10 +4,10 @@ import 'dart:js_util' as js_util; import 'dart:typed_data'; import 'package:collection/collection.dart'; -import 'package:dart_webrtc/src/rtc_transform_stream.dart'; import 'package:logging/logging.dart'; import 'package:web/web.dart' as web; +import 'package:dart_webrtc/src/rtc_transform_stream.dart'; import 'e2ee.cryptor.dart'; import 'e2ee.keyhandler.dart'; import 'e2ee.logger.dart'; diff --git a/lib/src/factory_impl.dart b/lib/src/factory_impl.dart index 833f7a5..20bd9c2 100644 --- a/lib/src/factory_impl.dart +++ b/lib/src/factory_impl.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'dart:convert'; + import 'package:js/js.dart'; import 'package:js/js_util.dart'; import 'package:web/web.dart' as web; diff --git a/lib/src/frame_cryptor_impl.dart b/lib/src/frame_cryptor_impl.dart index a598f1a..ec5cd54 100644 --- a/lib/src/frame_cryptor_impl.dart +++ b/lib/src/frame_cryptor_impl.dart @@ -6,12 +6,12 @@ import 'dart:js_util' as jsutil; import 'dart:typed_data'; import 'package:collection/collection.dart'; -import 'package:dart_webrtc/src/e2ee.worker/e2ee.logger.dart'; -import 'package:dart_webrtc/src/event.dart'; import 'package:js/js_util.dart'; import 'package:web/web.dart' as web; import 'package:webrtc_interface/webrtc_interface.dart'; +import 'package:dart_webrtc/src/e2ee.worker/e2ee.logger.dart'; +import 'package:dart_webrtc/src/event.dart'; import 'rtc_rtp_receiver_impl.dart'; import 'rtc_rtp_sender_impl.dart'; import 'rtc_transform_stream.dart'; diff --git a/lib/src/media_recorder_impl.dart b/lib/src/media_recorder_impl.dart index 3a3c206..12decec 100644 --- a/lib/src/media_recorder_impl.dart +++ b/lib/src/media_recorder_impl.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'dart:js' as js; import 'dart:js_interop'; + import 'package:web/web.dart' as web; import 'package:webrtc_interface/webrtc_interface.dart'; diff --git a/lib/src/media_stream_impl.dart b/lib/src/media_stream_impl.dart index 55b15af..4f312d2 100644 --- a/lib/src/media_stream_impl.dart +++ b/lib/src/media_stream_impl.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'dart:js_interop'; + import 'package:web/web.dart' as web; import 'package:webrtc_interface/webrtc_interface.dart'; diff --git a/lib/src/mediadevices_impl.dart b/lib/src/mediadevices_impl.dart index a7d9192..f8511d2 100644 --- a/lib/src/mediadevices_impl.dart +++ b/lib/src/mediadevices_impl.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:js' as js; import 'dart:js_interop'; import 'dart:js_util' as jsutil; + import 'package:web/web.dart' as web; import 'package:webrtc_interface/webrtc_interface.dart'; diff --git a/lib/src/rtc_data_channel_impl.dart b/lib/src/rtc_data_channel_impl.dart index 08855f7..697d75c 100644 --- a/lib/src/rtc_data_channel_impl.dart +++ b/lib/src/rtc_data_channel_impl.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'dart:js_interop'; + import 'package:js/js_util.dart' as jsutil; import 'package:web/web.dart' as web; import 'package:webrtc_interface/webrtc_interface.dart'; diff --git a/lib/src/rtc_peerconnection_impl.dart b/lib/src/rtc_peerconnection_impl.dart index e4da6cf..6e41dbb 100644 --- a/lib/src/rtc_peerconnection_impl.dart +++ b/lib/src/rtc_peerconnection_impl.dart @@ -4,11 +4,11 @@ import 'dart:js_interop'; import 'dart:js_interop_unsafe'; import 'dart:js_util' as jsutil; -import 'package:dart_webrtc/dart_webrtc.dart'; import 'package:js/js_util.dart'; import 'package:platform_detect/platform_detect.dart'; import 'package:web/web.dart' as web; +import 'package:dart_webrtc/dart_webrtc.dart'; import 'media_stream_track_impl.dart'; import 'rtc_data_channel_impl.dart'; import 'rtc_dtmf_sender_impl.dart'; diff --git a/lib/src/rtc_rtp_capailities_imp.dart b/lib/src/rtc_rtp_capailities_imp.dart index 4174d70..9a21314 100644 --- a/lib/src/rtc_rtp_capailities_imp.dart +++ b/lib/src/rtc_rtp_capailities_imp.dart @@ -1,4 +1,5 @@ import 'dart:js_util' as jsutil; + import 'package:webrtc_interface/webrtc_interface.dart'; class RTCRtpCapabilitiesWeb { diff --git a/lib/src/rtc_rtp_parameters_impl.dart b/lib/src/rtc_rtp_parameters_impl.dart index 94405b5..e9ed0c2 100644 --- a/lib/src/rtc_rtp_parameters_impl.dart +++ b/lib/src/rtc_rtp_parameters_impl.dart @@ -1,4 +1,5 @@ import 'dart:js_util' as jsutil; + import 'package:webrtc_interface/webrtc_interface.dart'; class RTCRtpParametersWeb { diff --git a/lib/src/rtc_rtp_receiver_impl.dart b/lib/src/rtc_rtp_receiver_impl.dart index e3cc1a8..d2c8c64 100644 --- a/lib/src/rtc_rtp_receiver_impl.dart +++ b/lib/src/rtc_rtp_receiver_impl.dart @@ -1,4 +1,5 @@ import 'dart:js_util' as jsutil; + import 'package:web/web.dart' as web; import 'package:webrtc_interface/webrtc_interface.dart'; diff --git a/lib/src/rtc_rtp_sender_impl.dart b/lib/src/rtc_rtp_sender_impl.dart index b7d3b9c..643020e 100644 --- a/lib/src/rtc_rtp_sender_impl.dart +++ b/lib/src/rtc_rtp_sender_impl.dart @@ -1,10 +1,10 @@ import 'dart:async'; import 'dart:js_util' as jsutil; -import 'package:dart_webrtc/src/media_stream_impl.dart'; import 'package:web/web.dart' as web; import 'package:webrtc_interface/webrtc_interface.dart'; +import 'package:dart_webrtc/src/media_stream_impl.dart'; import 'media_stream_track_impl.dart'; import 'rtc_dtmf_sender_impl.dart'; import 'rtc_rtp_parameters_impl.dart'; diff --git a/lib/src/rtc_transform_stream.dart b/lib/src/rtc_transform_stream.dart index d2b1952..f185a4f 100644 --- a/lib/src/rtc_transform_stream.dart +++ b/lib/src/rtc_transform_stream.dart @@ -1,5 +1,6 @@ import 'dart:js_util' as js_util; import 'dart:typed_data'; + import 'package:js/js.dart'; import 'package:web/web.dart'; diff --git a/lib/src/rtc_video_element.dart b/lib/src/rtc_video_element.dart index 6901a97..04d7416 100644 --- a/lib/src/rtc_video_element.dart +++ b/lib/src/rtc_video_element.dart @@ -1,5 +1,7 @@ import 'dart:js_interop'; + import 'package:web/web.dart' as web; + import '../dart_webrtc.dart'; class RTCVideoElement { From 6571ab3347b7179a4a51cfeafa8f921b02bd5509 Mon Sep 17 00:00:00 2001 From: td Date: Mon, 3 Jun 2024 17:16:15 +0530 Subject: [PATCH 26/36] fix: missing fault tolerance value --- lib/src/frame_cryptor_impl.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/src/frame_cryptor_impl.dart b/lib/src/frame_cryptor_impl.dart index ec5cd54..30b0e4c 100644 --- a/lib/src/frame_cryptor_impl.dart +++ b/lib/src/frame_cryptor_impl.dart @@ -192,6 +192,7 @@ class KeyProviderImpl implements KeyProvider { 'sharedKey': options.sharedKey, 'ratchetSalt': base64Encode(options.ratchetSalt), 'ratchetWindowSize': options.ratchetWindowSize, + 'failureTolerance': options.failureTolerance, if (options.uncryptedMagicBytes != null) 'uncryptedMagicBytes': base64Encode(options.uncryptedMagicBytes!), 'keyRingSize': options.keyRingSize, From dc362d57964519efe11a3f27e920d76461ceb819 Mon Sep 17 00:00:00 2001 From: td Date: Wed, 5 Jun 2024 16:00:35 +0530 Subject: [PATCH 27/36] fix: translate audio constraints for web --- lib/src/mediadevices_impl.dart | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/lib/src/mediadevices_impl.dart b/lib/src/mediadevices_impl.dart index f8511d2..5051c96 100644 --- a/lib/src/mediadevices_impl.dart +++ b/lib/src/mediadevices_impl.dart @@ -27,6 +27,28 @@ class MediaDevicesWeb extends MediaDevices { print( '[getUserMedia] failed to remove facingMode from mediaConstraints'); } + try { + if (mediaConstraints['audio'] is Map && + Map.from(mediaConstraints['audio']).containsKey('optional') && + mediaConstraints['audio']['optional'] + is List>) { + List> optionalValues = + mediaConstraints['audio']['optional']; + final audioMap = {}; + + optionalValues.forEach((option) { + option.forEach((key, value) { + audioMap[key] = value; + }); + }); + + mediaConstraints['audio'].remove('optional'); + mediaConstraints['audio'].addAll(audioMap); + } + } catch (e, s) { + print( + '[getUserMedia] failed to translate optional audio constraints, $e, $s'); + } final mediaDevices = web.window.navigator.mediaDevices; From 18e868d13966d7f2508c07a631a05b6bd582e5d1 Mon Sep 17 00:00:00 2001 From: td Date: Wed, 5 Jun 2024 16:37:58 +0530 Subject: [PATCH 28/36] fix: decrypting audio when e2ee --- lib/src/e2ee.worker/e2ee.cryptor.dart | 145 +++++++++++++++----------- 1 file changed, 82 insertions(+), 63 deletions(-) diff --git a/lib/src/e2ee.worker/e2ee.cryptor.dart b/lib/src/e2ee.worker/e2ee.cryptor.dart index 576389b..670dda8 100644 --- a/lib/src/e2ee.worker/e2ee.cryptor.dart +++ b/lib/src/e2ee.worker/e2ee.cryptor.dart @@ -5,9 +5,9 @@ import 'dart:js_util' as jsutil; import 'dart:math'; import 'dart:typed_data'; +import 'package:dart_webrtc/src/rtc_transform_stream.dart'; import 'package:web/web.dart' as web; -import 'package:dart_webrtc/src/rtc_transform_stream.dart'; import 'crypto.dart' as crypto; import 'e2ee.keyhandler.dart'; import 'e2ee.logger.dart'; @@ -408,9 +408,8 @@ class FrameCryptor { // skip for encryption for empty dtx frames buffer.isEmpty) { sifGuard.recordUserFrame(); - if (keyOptions.discardFrameWhenCryptorNotReady) { - return; - } + if (keyOptions.discardFrameWhenCryptorNotReady) return; + logger.fine('enqueing empty frame'); controller.enqueue(frame); return; } @@ -421,7 +420,7 @@ class FrameCryptor { var magicBytesBuffer = buffer.sublist( buffer.length - magicBytes.length - 1, buffer.length - 1); logger.finer( - 'magicBytesBuffer $magicBytesBuffer, magicBytes $magicBytes, '); + 'magicBytesBuffer $magicBytesBuffer, magicBytes $magicBytes'); if (magicBytesBuffer.toString() == magicBytes.toString()) { sifGuard.recordSif(); if (sifGuard.isSifAllowed()) { @@ -431,6 +430,7 @@ class FrameCryptor { finalBuffer.add(Uint8List.fromList( buffer.sublist(0, buffer.length - (magicBytes.length + 1)))); frame.data = crypto.jsArrayBufferFrom(finalBuffer.toBytes()); + logger.fine('enqueing silent frame'); controller.enqueue(frame); } else { logger.finer('SIF limit reached, dropping frame'); @@ -455,6 +455,12 @@ class FrameCryptor { initialKeySet = keyHandler.getKeySet(keyIndex); initialKeyIndex = keyIndex; + /// missingKey flow: + /// tries to decrypt once, fails, tries to ratchet once and decrypt again, + /// fails (does not save ratcheted key), bumps _decryptionFailureCount, + /// if higher than failuretolerance hasValidKey is set to false, on next + /// frame it fires a missingkey + /// to throw missingkeys faster lower your failureTolerance if (initialKeySet == null || !keyHandler.hasValidKey) { if (lastError != CryptorError.kMissingKey) { lastError = CryptorError.kMissingKey; @@ -468,14 +474,14 @@ class FrameCryptor { 'error': 'Missing key for track $trackId' }); } - controller.enqueue(frame); + // controller.enqueue(frame); return; } - var endDecLoop = false; var currentkeySet = initialKeySet; - while (!endDecLoop) { - try { - decrypted = await jsutil.promiseToFuture(crypto.decrypt( + + Future decryptFrameInternal() async { + decrypted = await jsutil.promiseToFuture( + crypto.decrypt( crypto.AesGcmParams( name: 'AES-GCM', iv: crypto.jsArrayBufferFrom(iv), @@ -484,56 +490,78 @@ class FrameCryptor { ), currentkeySet.encryptionKey, crypto.jsArrayBufferFrom( - buffer.sublist(headerLength, buffer.length - ivLength - 2)), - )); - - if (currentkeySet != initialKeySet) { - logger.fine( - 'ratchetKey: decryption ok, reset state to kKeyRatcheted'); - await keyHandler.setKeySetFromMaterial( - currentkeySet, initialKeyIndex); - } + buffer.sublist(headerLength, buffer.length - ivLength - 2), + ), + ), + ); + if (decrypted == null) { + throw Exception('[decryptFrameInternal] could not decrypt'); + } - endDecLoop = true; + if (currentkeySet != initialKeySet) { + logger.fine('ratchetKey: decryption ok, newState: kKeyRatcheted'); + await keyHandler.setKeySetFromMaterial( + currentkeySet, initialKeyIndex); + } - if (lastError != CryptorError.kOk && - lastError != CryptorError.kKeyRatcheted && - ratchetCount > 0) { - logger.finer( - 'KeyRatcheted: ssrc ${metaData.synchronizationSource} timestamp ${frame.timestamp} ratchetCount $ratchetCount participantId: $participantIdentity'); - logger.finer( - 'ratchetKey: lastError != CryptorError.kKeyRatcheted, reset state to kKeyRatcheted'); - - lastError = CryptorError.kKeyRatcheted; - postMessage({ - 'type': 'cryptorState', - 'msgType': 'event', - 'participantId': participantIdentity, - 'trackId': trackId, - 'kind': kind, - 'state': 'keyRatcheted', - 'error': 'Key ratcheted ok' - }); - } - } catch (e) { - lastError = CryptorError.kInternalError; - endDecLoop = ratchetCount >= keyOptions.ratchetWindowSize || - keyOptions.ratchetWindowSize <= 0; - if (endDecLoop) { - rethrow; - } - var newKeyBuffer = crypto.jsArrayBufferFrom(await keyHandler.ratchet( - currentkeySet.material, keyOptions.ratchetSalt)); - var newMaterial = await keyHandler.ratchetMaterial( - currentkeySet.material, newKeyBuffer); - currentkeySet = - await keyHandler.deriveKeys(newMaterial, keyOptions.ratchetSalt); - ratchetCount++; + if (lastError != CryptorError.kOk && + lastError != CryptorError.kKeyRatcheted && + ratchetCount > 0) { + logger.finer( + 'KeyRatcheted: ssrc ${metaData.synchronizationSource} timestamp ${frame.timestamp} ratchetCount $ratchetCount participantId: $participantIdentity'); + logger.finer( + 'ratchetKey: lastError != CryptorError.kKeyRatcheted, reset state to kKeyRatcheted'); + + lastError = CryptorError.kKeyRatcheted; + postMessage({ + 'type': 'cryptorState', + 'msgType': 'event', + 'participantId': participantIdentity, + 'trackId': trackId, + 'kind': kind, + 'state': 'keyRatcheted', + 'error': 'Key ratcheted ok' + }); } } + Future ratchedKeyInternal() async { + if (ratchetCount >= keyOptions.ratchetWindowSize || + keyOptions.ratchetWindowSize <= 0) { + throw Exception('[ratchedKeyInternal] cannot ratchet anymore'); + } + + var newKeyBuffer = crypto.jsArrayBufferFrom(await keyHandler.ratchet( + currentkeySet.material, keyOptions.ratchetSalt)); + var newMaterial = await keyHandler.ratchetMaterial( + currentkeySet.material, newKeyBuffer); + currentkeySet = + await keyHandler.deriveKeys(newMaterial, keyOptions.ratchetSalt); + ratchetCount++; + await decryptFrameInternal(); + } + + try { + /// gets frame -> tries to decrypt -> tries to ratchet (does this failureTolerance + /// times, then says missing key) + /// we only save the new key after ratcheting if we were able to decrypt something + await decryptFrameInternal(); + } catch (e) { + lastError = CryptorError.kInternalError; + await ratchedKeyInternal(); + } + + if (decrypted == null) { + throw Exception( + '[decodeFunction] decryption failed even after ratchting'); + } + + // we can now be sure that decryption was a success + keyHandler.decryptionSuccess(); + logger.finer( - 'buffer: ${buffer.length}, decrypted: ${decrypted?.asUint8List().length ?? 0}'); + 'buffer: ${buffer.length}, decrypted: ${decrypted!.asUint8List().length}'); + var finalBuffer = BytesBuilder(); finalBuffer.add(Uint8List.fromList(buffer.sublist(0, headerLength))); @@ -570,15 +598,6 @@ class FrameCryptor { }); } - /// Since the key it is first send and only afterwards actually used for encrypting, there were - /// situations when the decrypting failed due to the fact that the received frame was not encrypted - /// yet and ratcheting, of course, did not solve the problem. So if we fail RATCHET_WINDOW_SIZE times, - /// we come back to the initial key. - if (initialKeySet != null) { - logger.warning( - 'decryption failed, ratcheting back to initial key, keyIndex: $initialKeyIndex'); - await keyHandler.setKeySetFromMaterial(initialKeySet, initialKeyIndex); - } keyHandler.decryptionFailure(); } } From 99a87e358e3456c9e8ab44c556ae944ab6c49997 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Wed, 5 Jun 2024 20:58:17 +0800 Subject: [PATCH 29/36] release: 1.4.6. --- CHANGELOG.md | 8 ++++++++ README.md | 4 ++-- pubspec.yaml | 6 +++--- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f679361..9612304 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,14 @@ # Changelog -------------------------------------------- +[1.4.6] - 2024-06-05 + +* chore: bump version for js and http. +* fix: decrypting audio when e2ee. +* fix: translate audio constraints for web. +* fix: missing fault tolerance, better worker reports and a increased timeout for worker tasks. +* fix type cast exception in getConstraints() + [1.4.5] - 2024-05-13 * fix: negotiationNeeded listener. diff --git a/README.md b/README.md index c4cf777..54dc83d 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,6 @@ dart compile js ./lib/src/e2ee.worker/e2ee.worker.dart -o web/e2ee.worker.dart.j ## How to develop * `git clone https://github.com/flutter-webrtc/dart-webrtc && cd dart-webrtc` -* `pub get` -* `pub global activate webdev` +* `dart pub get` +* `dart pub global activate webdev` * `webdev serve --auto=refresh` diff --git a/pubspec.yaml b/pubspec.yaml index ccf6f39..94063ff 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.4.5 +version: 1.4.6 homepage: https://github.com/flutter-webrtc/dart-webrtc environment: @@ -8,7 +8,7 @@ environment: dependencies: collection: ^1.17.1 - js: ^0.6.4 + js: ^0.7.1 logging: ^1.1.0 meta: ^1.8.0 platform_detect: ^2.0.7 @@ -19,7 +19,7 @@ dependencies: dev_dependencies: build_runner: ^2.3.3 build_web_compilers: - http: ^0.13.3 + http: ^1.2.1 import_sorter: ^4.6.0 pedantic: ^1.9.0 protoo_client: ^0.3.0 From 060eee16adec86780f70184adabbc5fbd3784d6b Mon Sep 17 00:00:00 2001 From: td Date: Fri, 7 Jun 2024 03:27:50 +0530 Subject: [PATCH 30/36] chore: manage pubspec js and http versions to avoid conflicts --- lib/src/e2ee.worker/e2ee.cryptor.dart | 2 +- pubspec.yaml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/src/e2ee.worker/e2ee.cryptor.dart b/lib/src/e2ee.worker/e2ee.cryptor.dart index 670dda8..1aed4c1 100644 --- a/lib/src/e2ee.worker/e2ee.cryptor.dart +++ b/lib/src/e2ee.worker/e2ee.cryptor.dart @@ -5,9 +5,9 @@ import 'dart:js_util' as jsutil; import 'dart:math'; import 'dart:typed_data'; -import 'package:dart_webrtc/src/rtc_transform_stream.dart'; import 'package:web/web.dart' as web; +import 'package:dart_webrtc/src/rtc_transform_stream.dart'; import 'crypto.dart' as crypto; import 'e2ee.keyhandler.dart'; import 'e2ee.logger.dart'; diff --git a/pubspec.yaml b/pubspec.yaml index 94063ff..2ac2ebc 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -8,7 +8,7 @@ environment: dependencies: collection: ^1.17.1 - js: ^0.7.1 + js: ">0.6.0 <0.8.0" logging: ^1.1.0 meta: ^1.8.0 platform_detect: ^2.0.7 @@ -19,7 +19,7 @@ dependencies: dev_dependencies: build_runner: ^2.3.3 build_web_compilers: - http: ^1.2.1 + http: ">0.13.0 <1.3.0" import_sorter: ^4.6.0 pedantic: ^1.9.0 protoo_client: ^0.3.0 From 937f43c10a8ae2f01d10f9884f8fcf55df771ee4 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Fri, 7 Jun 2024 09:21:12 +0800 Subject: [PATCH 31/36] release: 1.4.6+hotfix.1. --- CHANGELOG.md | 4 ++++ pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9612304..369c91d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog -------------------------------------------- +[1.4.6+hotfix.1] - 2024-06-07 + +* Wider version dependencies for js/http. + [1.4.6] - 2024-06-05 * chore: bump version for js and http. diff --git a/pubspec.yaml b/pubspec.yaml index 2ac2ebc..7326e30 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.4.6 +version: 1.4.6+hotfix.1 homepage: https://github.com/flutter-webrtc/dart-webrtc environment: From 1047d10aecfd84a7a30f24e2d4ad8a9ffafbf335 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Fri, 12 Jul 2024 09:41:09 +0800 Subject: [PATCH 32/36] fix: MediaStreamTrack.getSettings. --- CHANGELOG.md | 6 ++++++ lib/src/media_stream_track_impl.dart | 26 +++++++++++++++++++++++++- pubspec.yaml | 2 +- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 369c91d..da7975b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ # Changelog -------------------------------------------- +[1.4.7] - 2024-07-12 + +* fix: MediaStreamTrack.getSettings. + +[1.4.6+hotfix.2] - 2024-06-07 + [1.4.6+hotfix.1] - 2024-06-07 * Wider version dependencies for js/http. diff --git a/lib/src/media_stream_track_impl.dart b/lib/src/media_stream_track_impl.dart index 1c4b8d9..abdf807 100644 --- a/lib/src/media_stream_track_impl.dart +++ b/lib/src/media_stream_track_impl.dart @@ -6,6 +6,8 @@ import 'dart:typed_data'; import 'package:web/web.dart' as web; import 'package:webrtc_interface/webrtc_interface.dart'; +import 'utils.dart'; + class MediaStreamTrackWeb extends MediaStreamTrack { MediaStreamTrackWeb(this.jsTrack) { jsTrack.addEventListener('ended', ((event) => onEnded?.call()).toJS); @@ -64,7 +66,29 @@ class MediaStreamTrackWeb extends MediaStreamTrack { @override Map getSettings() { - return jsTrack.getSettings() as Map; + var settings = jsTrack.getSettings(); + var _converted = {}; + if (kind == 'audio') { + _converted['sampleRate'] = settings.sampleRate; + _converted['sampleSize'] = settings.sampleSize; + _converted['echoCancellation'] = settings.echoCancellation; + _converted['autoGainControl'] = settings.autoGainControl; + _converted['noiseSuppression'] = settings.noiseSuppression; + _converted['latency'] = settings.latency; + _converted['channelCount'] = settings.channelCount; + } else { + _converted['width'] = settings.width; + _converted['height'] = settings.height; + _converted['aspectRatio'] = settings.aspectRatio; + _converted['frameRate'] = settings.frameRate; + if (isMobile) { + _converted['facingMode'] = settings.facingMode; + } + _converted['resizeMode'] = settings.resizeMode; + } + _converted['deviceId'] = settings.deviceId; + _converted['groupId'] = settings.groupId; + return _converted; } @override diff --git a/pubspec.yaml b/pubspec.yaml index 7326e30..b8e9bbe 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.4.6+hotfix.1 +version: 1.4.7 homepage: https://github.com/flutter-webrtc/dart-webrtc environment: From a40a1fc7b9f9d76d2006bfe038ad0bbfe9c57e5a Mon Sep 17 00:00:00 2001 From: James Pellow Date: Sun, 14 Jul 2024 15:03:41 -0700 Subject: [PATCH 33/36] fix: RTCPeerConnectionWeb.getRemoteStreams --- lib/src/rtc_peerconnection_impl.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/src/rtc_peerconnection_impl.dart b/lib/src/rtc_peerconnection_impl.dart index 6e41dbb..9b81367 100644 --- a/lib/src/rtc_peerconnection_impl.dart +++ b/lib/src/rtc_peerconnection_impl.dart @@ -129,7 +129,6 @@ class RTCPeerConnectionWeb extends RTCPeerConnection { final String _peerConnectionId; late final web.RTCPeerConnection _jsPc; final _localStreams = {}; - final _remoteStreams = {}; final _configuration = {}; RTCSignalingState? _signalingState; @@ -340,7 +339,7 @@ class RTCPeerConnectionWeb extends RTCPeerConnection { List getRemoteStreams() => _jsPc .getRemoteStreams() .toDart - .map((jsStream) => _remoteStreams[jsStream.id]!) + .map((e) => MediaStreamWeb(e, _peerConnectionId)) .toList(); @override From f4a56c437a432a0af3a4852442477ac96eb5dc8c Mon Sep 17 00:00:00 2001 From: kNoAPP Date: Thu, 18 Jul 2024 12:00:30 -0700 Subject: [PATCH 34/36] fix: missing streamCompleter complete for getUserMedia --- lib/src/mediadevices_impl.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/src/mediadevices_impl.dart b/lib/src/mediadevices_impl.dart index 5051c96..52a1c03 100644 --- a/lib/src/mediadevices_impl.dart +++ b/lib/src/mediadevices_impl.dart @@ -66,7 +66,9 @@ class MediaDevicesWeb extends MediaDevices { audio: mediaConstraints['audio'], video: mediaConstraints['video'], ), - (web.MediaStream stream) {}.toJS, + (web.MediaStream stream) { + streamCompleter.complete(stream); + }.toJS, (JSAny err) { streamCompleter.completeError(err); }.toJS); From 15a94afd170639139758505564585364d6fce9fd Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Fri, 19 Jul 2024 14:09:43 +0800 Subject: [PATCH 35/36] release: 1.4.8. --- CHANGELOG.md | 5 +++++ pubspec.yaml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index da7975b..63b67ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ # Changelog -------------------------------------------- +[1.4.8] - 2024-07-12 + +* fix: missing streamCompleter complete for getUserMedia. +* fix: RTCPeerConnectionWeb.getRemoteStreams. + [1.4.7] - 2024-07-12 * fix: MediaStreamTrack.getSettings. diff --git a/pubspec.yaml b/pubspec.yaml index b8e9bbe..2264bde 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.4.7 +version: 1.4.8 homepage: https://github.com/flutter-webrtc/dart-webrtc environment: From 38badf0f78052ec54ae7331db816ebe92ff0392b Mon Sep 17 00:00:00 2001 From: Jesse Ezell Date: Thu, 8 Aug 2024 00:29:31 -0700 Subject: [PATCH 36/36] update to web 1.0 --- lib/src/frame_cryptor_impl.dart | 2 +- lib/src/mediadevices_impl.dart | 33 ++++++++------------------------- pubspec.yaml | 2 +- 3 files changed, 10 insertions(+), 27 deletions(-) diff --git a/lib/src/frame_cryptor_impl.dart b/lib/src/frame_cryptor_impl.dart index 30b0e4c..4666c41 100644 --- a/lib/src/frame_cryptor_impl.dart +++ b/lib/src/frame_cryptor_impl.dart @@ -400,7 +400,7 @@ class KeyProviderImpl implements KeyProvider { class FrameCryptorFactoryImpl implements FrameCryptorFactory { FrameCryptorFactoryImpl._internal() { - worker = web.Worker('e2ee.worker.dart.js'); + worker = web.Worker('e2ee.worker.dart.js'.toJS); worker.addEventListener( 'message', (web.MessageEvent msg) { diff --git a/lib/src/mediadevices_impl.dart b/lib/src/mediadevices_impl.dart index 52a1c03..1f3b5cb 100644 --- a/lib/src/mediadevices_impl.dart +++ b/lib/src/mediadevices_impl.dart @@ -59,21 +59,12 @@ class MediaDevicesWeb extends MediaDevices { return MediaStreamWeb(jsStream, 'local'); } else { - final streamCompleter = Completer(); - - web.window.navigator.getUserMedia( - web.MediaStreamConstraints( + final jsStream = await web.window.navigator.mediaDevices + .getUserMedia(web.MediaStreamConstraints( audio: mediaConstraints['audio'], video: mediaConstraints['video'], - ), - (web.MediaStream stream) { - streamCompleter.complete(stream); - }.toJS, - (JSAny err) { - streamCompleter.completeError(err); - }.toJS); - - final jsStream = await streamCompleter.future; + )) + .toDart; return MediaStreamWeb(jsStream, 'local'); } } catch (e) { @@ -93,19 +84,11 @@ class MediaDevicesWeb extends MediaDevices { jsutil.callMethod(mediaDevices, 'getDisplayMedia', [arg])); return MediaStreamWeb(jsStream, 'local'); } else { - final streamCompleter = Completer(); - - web.window.navigator.getUserMedia( - web.MediaStreamConstraints( + final jsStream = await web.window.navigator.mediaDevices + .getUserMedia(web.MediaStreamConstraints( video: jsutil.jsify({'mediaSource': 'screen'}), - audio: mediaConstraints['audio'] ?? false), - (web.MediaStream stream) { - streamCompleter.complete(stream); - }.toJS, - (JSAny err) { - streamCompleter.completeError(err); - }.toJS); - final jsStream = await streamCompleter.future; + audio: mediaConstraints['audio'] ?? false)) + .toDart; return MediaStreamWeb(jsStream, 'local'); } } catch (e) { diff --git a/pubspec.yaml b/pubspec.yaml index 2264bde..ebcf797 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -13,7 +13,7 @@ dependencies: meta: ^1.8.0 platform_detect: ^2.0.7 synchronized: ^3.0.0+3 - web: ^0.5.1 + web: ^1.0.0 webrtc_interface: ^1.2.0 dev_dependencies: