From 05800e7599df762a19587a26c3e7f639970fe86b Mon Sep 17 00:00:00 2001 From: CloudWebRTC Date: Fri, 9 Aug 2024 21:37:43 +0800 Subject: [PATCH] fix: Fixed confusing room options causing settings to overwrite. (#570) * fix: Fixed confusing room options causing settings to overwrite. * if publishOptions.videoEncoding is not specified, use the default encoding * fix. * revert changes. * Change VideoParameters.encoding to optional. * update. * Deprecate some APIs in Room. * update. * update. * Update build.yaml * update. * Update build.yaml --- .github/workflows/build.yaml | 4 +- example/lib/pages/prejoin.dart | 48 ++++++++++++++--------- example/pubspec.yaml | 2 +- lib/src/core/engine.dart | 3 +- lib/src/core/room.dart | 6 ++- lib/src/options.dart | 5 +++ lib/src/types/video_parameters.dart | 12 +++--- lib/src/utils.dart | 26 +++++++----- lib/src/widgets/screen_select_dialog.dart | 2 +- test/mock/e2e_container.dart | 1 - 10 files changed, 67 insertions(+), 42 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 73e95ee0..1b94f5f7 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -29,13 +29,15 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-java@v1 with: - java-version: '12.x' + java-version: '17.x' - uses: actions/checkout@v2 - uses: subosito/flutter-action@v2 with: channel: 'stable' - name: Install project dependencies run: flutter pub get + - name: Upgrade to major versions + run: flutter pub upgrade --major-versions - name: Dart Format Check run: dart format lib/ test/ --set-exit-if-changed - name: Import Sorter Check diff --git a/example/lib/pages/prejoin.dart b/example/lib/pages/prejoin.dart index 402d8458..2d957722 100644 --- a/example/lib/pages/prejoin.dart +++ b/example/lib/pages/prejoin.dart @@ -165,10 +165,15 @@ class _PreJoinPageState extends State { try { //create new room - final room = Room(); + var cameraEncoding = VideoEncoding( + maxBitrate: 5 * 1000 * 1000, + maxFramerate: 30, + ); - // Create a Listener before connecting - final listener = room.createListener(); + var screenEncoding = VideoEncoding( + maxBitrate: 3 * 1000 * 1000, + maxFramerate: 15, + ); E2EEOptions? e2eeOptions; if (args.e2ee && args.e2eeKey != null) { @@ -177,36 +182,43 @@ class _PreJoinPageState extends State { await keyProvider.setKey(args.e2eeKey!); } - // Try to connect to the room - // This will throw an Exception if it fails for any reason. - await room.connect( - args.url, - args.token, + final room = Room( roomOptions: RoomOptions( adaptiveStream: args.adaptiveStream, dynacast: args.dynacast, defaultAudioPublishOptions: const AudioPublishOptions( name: 'custom_audio_track_name', ), + defaultCameraCaptureOptions: CameraCaptureOptions( + maxFrameRate: 30, + params: VideoParameters( + dimensions: const VideoDimensions(1280, 720), + )), + defaultScreenShareCaptureOptions: const ScreenShareCaptureOptions( + useiOSBroadcastExtension: true, + params: VideoParameters( + dimensions: VideoDimensionsPresets.h1080_169, + )), defaultVideoPublishOptions: VideoPublishOptions( simulcast: args.simulcast, videoCodec: args.preferredCodec, backupVideoCodec: BackupVideoCodec( enabled: args.enableBackupVideoCodec, ), + videoEncoding: cameraEncoding, + screenShareEncoding: screenEncoding, ), - defaultScreenShareCaptureOptions: const ScreenShareCaptureOptions( - useiOSBroadcastExtension: true, - params: VideoParameters( - dimensions: VideoDimensionsPresets.h1080_169, - encoding: VideoEncoding( - maxBitrate: 3 * 1000 * 1000, - maxFramerate: 15, - ))), - defaultCameraCaptureOptions: CameraCaptureOptions( - maxFrameRate: 30, params: _selectedVideoParameters), e2eeOptions: e2eeOptions, ), + ); + // Create a Listener before connecting + final listener = room.createListener(); + + // Try to connect to the room + // This will throw an Exception if it fails for any reason. + await room.connect( + args.url, + args.token, fastConnectOptions: FastConnectOptions( microphone: TrackOption(track: _audioTrack), camera: TrackOption(track: _videoTrack), diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 307543b9..ddf3cb40 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -29,7 +29,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - flutter_lints: ^3.0.2 + flutter_lints: ^4.0.0 # The following section is specific to Flutter. flutter: diff --git a/lib/src/core/engine.dart b/lib/src/core/engine.dart index e2794b56..925cd9a8 100644 --- a/lib/src/core/engine.dart +++ b/lib/src/core/engine.dart @@ -100,7 +100,7 @@ class Engine extends Disposable with EventsEmittable { String? url; String? token; - ConnectOptions connectOptions; + late ConnectOptions connectOptions; RoomOptions roomOptions; FastConnectOptions? fastConnectOptions; @@ -143,7 +143,6 @@ class Engine extends Disposable with EventsEmittable { } Engine({ - required this.connectOptions, required this.roomOptions, SignalClient? signalClient, PeerConnectionCreate? peerConnectionCreate, diff --git a/lib/src/core/room.dart b/lib/src/core/room.dart index db916d10..5dec460c 100644 --- a/lib/src/core/room.dart +++ b/lib/src/core/room.dart @@ -111,12 +111,12 @@ class Room extends DisposableChangeNotifier with EventsEmittable { late EventsListener _signalListener; Room({ + @Deprecated('deprecated, please use connectOptions in room.connect()') ConnectOptions connectOptions = const ConnectOptions(), RoomOptions roomOptions = const RoomOptions(), Engine? engine, }) : engine = engine ?? Engine( - connectOptions: connectOptions, roomOptions: roomOptions, ) { // @@ -152,10 +152,12 @@ class Room extends DisposableChangeNotifier with EventsEmittable { String url, String token, { ConnectOptions? connectOptions, + @Deprecated('deprecated, please use roomOptions in Room constructor') RoomOptions? roomOptions, FastConnectOptions? fastConnectOptions, }) async { - roomOptions ??= this.roomOptions; + var roomOptions = this.roomOptions; + connectOptions ??= ConnectOptions(); if (roomOptions.e2eeOptions != null) { if (!lkPlatformSupportsE2EE()) { throw LiveKitE2EEException('E2EE is not supported on this platform'); diff --git a/lib/src/options.dart b/lib/src/options.dart index ed80b5da..2394b413 100644 --- a/lib/src/options.dart +++ b/lib/src/options.dart @@ -229,6 +229,8 @@ class VideoPublishOptions extends PublishOptions { /// Defaults to null. final VideoEncoding? videoEncoding; + final VideoEncoding? screenShareEncoding; + /// Whether to enable simulcast or not. /// https://blog.livekit.io/an-introduction-to-webrtc-simulcast-6c5f1f6402eb /// Defaults to true. @@ -249,6 +251,7 @@ class VideoPublishOptions extends PublishOptions { super.stream, this.videoCodec = defaultVideoCodec, this.videoEncoding, + this.screenShareEncoding, this.simulcast = true, this.videoSimulcastLayers = const [], this.screenShareSimulcastLayers = const [], @@ -258,6 +261,7 @@ class VideoPublishOptions extends PublishOptions { VideoPublishOptions copyWith({ VideoEncoding? videoEncoding, + VideoEncoding? screenShareEncoding, bool? simulcast, List? videoSimulcastLayers, List? screenShareSimulcastLayers, @@ -270,6 +274,7 @@ class VideoPublishOptions extends PublishOptions { }) => VideoPublishOptions( videoEncoding: videoEncoding ?? this.videoEncoding, + screenShareEncoding: screenShareEncoding ?? this.screenShareEncoding, simulcast: simulcast ?? this.simulcast, videoSimulcastLayers: videoSimulcastLayers ?? this.videoSimulcastLayers, screenShareSimulcastLayers: diff --git a/lib/src/types/video_parameters.dart b/lib/src/types/video_parameters.dart index a3f27f5e..0ce57f90 100644 --- a/lib/src/types/video_parameters.dart +++ b/lib/src/types/video_parameters.dart @@ -21,12 +21,12 @@ import 'video_encoding.dart'; class VideoParameters implements Comparable { final String? description; final VideoDimensions dimensions; - final VideoEncoding encoding; + final VideoEncoding? encoding; const VideoParameters({ - this.description, required this.dimensions, - required this.encoding, + this.description, + this.encoding, }); // ---------------------------------------------------------------------- @@ -51,8 +51,8 @@ class VideoParameters implements Comparable { // compare by dimension's area final result = dimensions.area().compareTo(other.dimensions.area()); // if dimensions have equal area, compare by encoding - if (result == 0) { - return encoding.compareTo(other.encoding); + if (result == 0 && encoding != null && other.encoding != null) { + return encoding!.compareTo(other.encoding!); } return result; @@ -65,7 +65,7 @@ class VideoParameters implements Comparable { Map toMediaConstraintsMap() => { 'width': dimensions.width, 'height': dimensions.height, - 'frameRate': encoding.maxFramerate, + 'frameRate': encoding?.maxFramerate ?? 30, }; } diff --git a/lib/src/utils.dart b/lib/src/utils.dart index af1613a1..f32f9e6b 100644 --- a/lib/src/utils.dart +++ b/lib/src/utils.dart @@ -240,9 +240,9 @@ class Utils { encoding: VideoEncoding( maxBitrate: math.max( 150 * 1000, - (original.encoding.maxBitrate / + (original.encoding!.maxBitrate / (math.pow(scale, 2) * - (original.encoding.maxFramerate / fps))) + (original.encoding!.maxFramerate / fps))) .floor(), ), maxFramerate: fps, @@ -274,13 +274,13 @@ class Utils { String? codec, }) { assert(presets.isNotEmpty, 'presets should not be empty'); - VideoEncoding result = presets.first.encoding; + VideoEncoding result = presets.first.encoding!; // handle portrait by swapping dimensions final size = dimensions.max(); for (final preset in presets) { - result = preset.encoding; + result = preset.encoding!; if (preset.dimensions.width >= size) break; } @@ -319,11 +319,12 @@ class Utils { } final size = dimensions.min(); final rid = videoRids[i]; - - result.add(e.encoding.toRTCRtpEncoding( - rid: rid, - scaleResolutionDownBy: math.max(1, size / e.dimensions.min()), - )); + if (e.encoding != null) { + result.add(e.encoding!.toRTCRtpEncoding( + rid: rid, + scaleResolutionDownBy: math.max(1, size / e.dimensions.min()), + )); + } }); return result; } @@ -390,6 +391,11 @@ class Utils { options ??= const VideoPublishOptions(); VideoEncoding? videoEncoding = options.videoEncoding; + + if (isScreenShare) { + videoEncoding = options.screenShareEncoding; + } + var scalabilityMode = options.scalabilityMode; if ((videoEncoding == null && @@ -436,7 +442,7 @@ class Utils { encodings.add(rtc.RTCRtpEncoding( rid: videoRids[2 - i], maxBitrate: videoEncoding.maxBitrate ~/ math.pow(3, i), - maxFramerate: original.encoding.maxFramerate, + maxFramerate: original.encoding!.maxFramerate, )); } } else { diff --git a/lib/src/widgets/screen_select_dialog.dart b/lib/src/widgets/screen_select_dialog.dart index 276e9bac..67d68194 100644 --- a/lib/src/widgets/screen_select_dialog.dart +++ b/lib/src/widgets/screen_select_dialog.dart @@ -302,7 +302,7 @@ class ScreenSelectDialog extends Dialog { ), SizedBox( width: double.infinity, - child: ButtonBar( + child: OverflowBar( children: [ MaterialButton( child: const Text( diff --git a/test/mock/e2e_container.dart b/test/mock/e2e_container.dart index 0dcbe131..b33b4598 100644 --- a/test/mock/e2e_container.dart +++ b/test/mock/e2e_container.dart @@ -31,7 +31,6 @@ class E2EContainer { engine = Engine( signalClient: client, peerConnectionCreate: MockPeerConnection.create, - connectOptions: const ConnectOptions(), roomOptions: const RoomOptions(), ); room = Room(engine: engine);