From 211bfe9cdaf596c258dcf7ce873966045e69de44 Mon Sep 17 00:00:00 2001 From: Tobias Ollmann Date: Wed, 22 Jan 2025 12:12:17 +0100 Subject: [PATCH 01/11] fix: tighten VideoTrackRenderer Widget This allows external users to e.g. apply rounded edges. Without this patch, VideoTrackRenderer will expand to its available space with no way for parent widgets to know how large the video actually is --- lib/src/widgets/video_track_renderer.dart | 62 ++++++++++++++++++++++- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/lib/src/widgets/video_track_renderer.dart b/lib/src/widgets/video_track_renderer.dart index 61e353603..eb7ccc277 100644 --- a/lib/src/widgets/video_track_renderer.dart +++ b/lib/src/widgets/video_track_renderer.dart @@ -65,6 +65,9 @@ class VideoTrackRenderer extends StatefulWidget { final rtc.RTCVideoRenderer? cachedRenderer; final bool autoDisposeRenderer; + /// wrap the video view in a Center widget (if [fit] is [VideoViewFit.contain]) + final bool autoCenter; + const VideoTrackRenderer( this.track, { this.fit = VideoViewFit.contain, @@ -72,6 +75,7 @@ class VideoTrackRenderer extends StatefulWidget { this.renderMode = VideoRenderMode.texture, this.autoDisposeRenderer = true, this.cachedRenderer, + this.autoCenter = true, Key? key, }) : super(key: key); @@ -83,6 +87,7 @@ class _VideoTrackRendererState extends State { rtc.VideoRenderer? _renderer; // for flutter web only. bool _rendererReadyForWeb = false; + double? _aspectRatio; EventsListener? _listener; // Used to compute visibility information late GlobalKey _internalKey; @@ -121,6 +126,7 @@ class _VideoTrackRendererState extends State { void disposeRenderer() { try { + _renderer?.onResize = null; _renderer?.srcObject = null; _renderer?.dispose(); _renderer = null; @@ -167,6 +173,14 @@ class _VideoTrackRendererState extends State { // force recompute of mirror mode setState(() {}); }); + _renderer?.onResize = () { + if (mounted) { + setState(() { + _aspectRatio = + (_renderer as rtc.RTCVideoRenderer?)?.videoValue.aspectRatio; + }); + } + }; } @override @@ -268,8 +282,52 @@ class _VideoTrackRendererState extends State { // FutureBuilder will cause flickering for flutter web. so using // different rendering methods for web and native. @override - Widget build(BuildContext context) => - kIsWeb ? _videoViewForWeb() : _videoViewForNative(); + Widget build(BuildContext context) { + final child = kIsWeb ? _videoViewForWeb() : _videoViewForNative(); + + if (widget.fit == VideoViewFit.cover) { + return child; + } + + final videoView = LayoutBuilder( + builder: (BuildContext context, BoxConstraints constraints) { + if (!constraints.hasBoundedWidth && !constraints.hasBoundedHeight) { + return child; + } + if (_aspectRatio == null) { + return child; + } + + bool fixHeight; + if (!constraints.hasBoundedWidth) { + fixHeight = true; + } else if (!constraints.hasBoundedHeight) { + fixHeight = false; + } else { + // both width and height are bound, figure out which to fix based on aspect ratios + final constraintsAspectRatio = + constraints.maxWidth / constraints.maxHeight; + fixHeight = constraintsAspectRatio > _aspectRatio!; + } + final double width; + final double height; + if (fixHeight) { + height = constraints.maxHeight; + width = height * _aspectRatio!; + } else { + width = constraints.maxWidth; + height = width / _aspectRatio!; + } + return SizedBox(width: width, height: height, child: child); + }, + ); + + if (widget.autoCenter) { + return Center(child: videoView); + } else { + return videoView; + } + } bool _shouldMirror() { // off for screen share From ff23d72eb43b024a8b5691f4454d9bc53525bab7 Mon Sep 17 00:00:00 2001 From: Tobias Ollmann Date: Tue, 8 Jul 2025 11:43:21 +0200 Subject: [PATCH 02/11] fix(web, firefox): backup old values before overwriting them --- lib/src/track/local/video.dart | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/src/track/local/video.dart b/lib/src/track/local/video.dart index 44d3afc94..09f30260d 100644 --- a/lib/src/track/local/video.dart +++ b/lib/src/track/local/video.dart @@ -62,6 +62,7 @@ class LocalVideoTrack extends LocalTrack with VideoTrack { final Map _bitrateFoLayers = {}; Map simulcastCodecs = {}; + Map<(String, int), rtc.RTCRtpEncoding> encodingBackups = {}; List subscribedCodecs = []; @@ -452,11 +453,16 @@ extension LocalVideoTrackExt on LocalVideoTrack { // have a workaround of lowering its bitrate and resolution to the min. if (kIsWeb && lkBrowser() == BrowserType.firefox) { if (subscribedQuality.enabled) { + final encodingBackup = encodingBackups[(sender.senderId, idx)]!; encoding.scaleResolutionDownBy = - encodings[idx].scaleResolutionDownBy; - encoding.maxBitrate = encodings[idx].maxBitrate; - encoding.maxFramerate = encodings[idx].maxBitrate; + encodingBackup.scaleResolutionDownBy; + encoding.maxBitrate = encodingBackup.maxBitrate; + encoding.maxFramerate = encodingBackup.maxFramerate; } else { + encodingBackups[(sender.senderId, idx)] = rtc.RTCRtpEncoding( + scaleResolutionDownBy: encoding.scaleResolutionDownBy, + maxBitrate: encoding.maxBitrate, + maxFramerate: encoding.maxFramerate); encoding.scaleResolutionDownBy = 4; encoding.maxBitrate = 10; encoding.maxFramerate = 2; From 591eaba968d28da37dc4f1dc0bef9a3129347a6b Mon Sep 17 00:00:00 2001 From: Tobias Ollmann Date: Wed, 2 Apr 2025 15:52:15 +0200 Subject: [PATCH 03/11] fix: copy processor --- lib/src/track/options.dart | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/src/track/options.dart b/lib/src/track/options.dart index b7e63ff0e..f3bb5ed3d 100644 --- a/lib/src/track/options.dart +++ b/lib/src/track/options.dart @@ -81,6 +81,7 @@ class CameraCaptureOptions extends VideoCaptureOptions { params: captureOptions.params, deviceId: captureOptions.deviceId, maxFrameRate: captureOptions.maxFrameRate, + processor: captureOptions.processor, ); @override @@ -112,19 +113,25 @@ class CameraCaptureOptions extends VideoCaptureOptions { // Returns new options with updated properties CameraCaptureOptions copyWith({ - VideoParameters? params, CameraPosition? cameraPosition, + CameraFocusMode? focusMode, + CameraExposureMode? exposureMode, String? deviceId, double? maxFrameRate, + VideoParameters? params, bool? stopCameraCaptureOnMute, + TrackProcessor? processor, }) => CameraCaptureOptions( - params: params ?? this.params, cameraPosition: cameraPosition ?? this.cameraPosition, + focusMode: focusMode ?? this.focusMode, + exposureMode: exposureMode ?? this.exposureMode, deviceId: deviceId ?? this.deviceId, maxFrameRate: maxFrameRate ?? this.maxFrameRate, + params: params ?? this.params, stopCameraCaptureOnMute: stopCameraCaptureOnMute ?? this.stopCameraCaptureOnMute, + processor: processor ?? this.processor, ); } From 64aba20fb7b5ecca5593a9cf4a4f3b73601bfc5c Mon Sep 17 00:00:00 2001 From: Tobias Ollmann Date: Thu, 3 Jul 2025 19:35:59 +0200 Subject: [PATCH 04/11] fix: properly handle processor updates --- lib/src/track/local/local.dart | 15 ++++++++++----- lib/src/track/track.dart | 10 +++++++++- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/lib/src/track/local/local.dart b/lib/src/track/local/local.dart index d96a05fa0..22b5477ac 100644 --- a/lib/src/track/local/local.dart +++ b/lib/src/track/local/local.dart @@ -36,9 +36,6 @@ import '../track.dart'; import 'audio.dart'; import 'video.dart'; -import '../processor_native.dart' - if (dart.library.js_interop) '../processor_web.dart'; - /// Used to group [LocalVideoTrack] and [RemoteVideoTrack]. mixin VideoTrack on Track { @internal @@ -133,6 +130,13 @@ abstract class LocalTrack extends Track { @override Future stop() async { + try { + if (_processor != null) { + await stopProcessor(); + } + } catch (error) { + logger.severe('LocalTrack.stopProcessor did throw: $error'); + } final didStop = await super.stop() || !_stopped; if (didStop) { logger.fine('Stopping mediaStreamTrack...'); @@ -261,14 +265,15 @@ abstract class LocalTrack extends Track { _processor = processor; - var processorOptions = AudioProcessorOptions( + var processorOptions = ProcessorOptions( + kind: kind, track: mediaStreamTrack, ); await _processor!.init(processorOptions); if (_processor?.processedTrack != null) { - setProcessedTrack(processor.processedTrack!); + await setProcessedTrack(processor.processedTrack!); } logger.fine('processor initialized'); diff --git a/lib/src/track/track.dart b/lib/src/track/track.dart index c72f4dcc0..43d06c12a 100644 --- a/lib/src/track/track.dart +++ b/lib/src/track/track.dart @@ -229,8 +229,16 @@ abstract class Track extends DisposableChangeNotifier } @internal - void setProcessedTrack(rtc.MediaStreamTrack track) { + Future setProcessedTrack(rtc.MediaStreamTrack track) async { _originalTrack = _mediaStreamTrack; _mediaStreamTrack = track; + if (_originalTrack != null) { + await _mediaStream.removeTrack(_originalTrack!); + } + await _mediaStream.addTrack(track); + events.emit(TrackStreamUpdatedEvent( + track: this, + stream: _mediaStream, + )); } } From 7b7c583adc9d867fdc9b952498994878e9a12cff Mon Sep 17 00:00:00 2001 From: Tobias Ollmann Date: Wed, 16 Jul 2025 08:15:07 +0200 Subject: [PATCH 05/11] fix: properly update processed streams --- lib/src/track/local/local.dart | 2 ++ lib/src/track/track.dart | 21 +++++++++++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/lib/src/track/local/local.dart b/lib/src/track/local/local.dart index 22b5477ac..ca9406fd6 100644 --- a/lib/src/track/local/local.dart +++ b/lib/src/track/local/local.dart @@ -299,6 +299,8 @@ abstract class LocalTrack extends Track { // force re-setting of the mediaStreamTrack on the sender //await this.setMediaStreamTrack(this._mediaStreamTrack, true); + await setProcessedTrack(null); + events.emit(TrackProcessorUpdateEvent(track: this)); } diff --git a/lib/src/track/track.dart b/lib/src/track/track.dart index 43d06c12a..f15015900 100644 --- a/lib/src/track/track.dart +++ b/lib/src/track/track.dart @@ -229,13 +229,22 @@ abstract class Track extends DisposableChangeNotifier } @internal - Future setProcessedTrack(rtc.MediaStreamTrack track) async { - _originalTrack = _mediaStreamTrack; - _mediaStreamTrack = track; - if (_originalTrack != null) { - await _mediaStream.removeTrack(_originalTrack!); + Future setProcessedTrack(rtc.MediaStreamTrack? track) async { + if (track != null) { + // set processed track + _originalTrack = _mediaStreamTrack; + _mediaStreamTrack = track; + if (_originalTrack != null) { + await _mediaStream.removeTrack(_originalTrack!); + } + await _mediaStream.addTrack(track); + } else if (_originalTrack != null) { + // reset processed track + await _mediaStream.removeTrack(_mediaStreamTrack); + await _mediaStream.addTrack(_originalTrack!); + _mediaStreamTrack = _originalTrack!; + _originalTrack = null; } - await _mediaStream.addTrack(track); events.emit(TrackStreamUpdatedEvent( track: this, stream: _mediaStream, From 19f3d0580d6e30e54e4ded3002422a9ae130329e Mon Sep 17 00:00:00 2001 From: Tobias Ollmann Date: Thu, 21 Aug 2025 16:21:45 +0200 Subject: [PATCH 06/11] fix: stop stream first, processor second otherwise unblurred video is visible for a few frames --- lib/src/track/local/local.dart | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/src/track/local/local.dart b/lib/src/track/local/local.dart index ca9406fd6..7e0321774 100644 --- a/lib/src/track/local/local.dart +++ b/lib/src/track/local/local.dart @@ -130,13 +130,6 @@ abstract class LocalTrack extends Track { @override Future stop() async { - try { - if (_processor != null) { - await stopProcessor(); - } - } catch (error) { - logger.severe('LocalTrack.stopProcessor did throw: $error'); - } final didStop = await super.stop() || !_stopped; if (didStop) { logger.fine('Stopping mediaStreamTrack...'); @@ -151,6 +144,13 @@ abstract class LocalTrack extends Track { logger.severe('MediaStreamTrack.dispose() did throw $error'); } _stopped = true; + try { + if (_processor != null) { + await stopProcessor(); + } + } catch (error) { + logger.severe('LocalTrack.stopProcessor did throw: $error'); + } } return didStop; } From e92daaa53c20e85491f4508e6acc469197e770f0 Mon Sep 17 00:00:00 2001 From: Tobias Ollmann Date: Tue, 26 Aug 2025 08:48:26 +0200 Subject: [PATCH 07/11] chore: format files --- lib/src/core/engine.dart | 3 +- lib/src/events.dart | 3 +- lib/src/participant/participant.dart | 48 ++++++++++++++++++---------- lib/src/types/participant_state.dart | 3 +- 4 files changed, 38 insertions(+), 19 deletions(-) diff --git a/lib/src/core/engine.dart b/lib/src/core/engine.dart index 25b371af8..28f075816 100644 --- a/lib/src/core/engine.dart +++ b/lib/src/core/engine.dart @@ -34,7 +34,8 @@ import '../proto/livekit_models.pb.dart' as lk_models; import '../proto/livekit_rtc.pb.dart' as lk_rtc; import '../publication/local.dart'; import '../support/disposable.dart'; -import '../support/platform.dart' show lkPlatformIsTest, lkPlatformIs, PlatformType; +import '../support/platform.dart' + show lkPlatformIsTest, lkPlatformIs, PlatformType; import '../support/region_url_provider.dart'; import '../support/websocket.dart'; import '../track/local/local.dart'; diff --git a/lib/src/events.dart b/lib/src/events.dart index 31cbbaf09..a8e1b47bc 100644 --- a/lib/src/events.dart +++ b/lib/src/events.dart @@ -387,7 +387,8 @@ class ParticipantStateUpdatedEvent with RoomEvent, ParticipantEvent { /// [Pariticpant]'s [ConnectionQuality] has updated. /// Emitted by [Room] and [Participant]. -class ParticipantConnectionQualityUpdatedEvent with RoomEvent, ParticipantEvent { +class ParticipantConnectionQualityUpdatedEvent + with RoomEvent, ParticipantEvent { final Participant participant; final ConnectionQuality connectionQuality; const ParticipantConnectionQualityUpdatedEvent({ diff --git a/lib/src/participant/participant.dart b/lib/src/participant/participant.dart index 1d83ea3d4..d36d84aec 100644 --- a/lib/src/participant/participant.dart +++ b/lib/src/participant/participant.dart @@ -39,8 +39,8 @@ import '../utils.dart'; /// Base for [RemoteParticipant] and [LocalParticipant], /// can not be instantiated directly. -abstract class Participant extends DisposableChangeNotifier - with EventsEmittable { +abstract class Participant + extends DisposableChangeNotifier with EventsEmittable { /// Reference to [Room] @internal final Room room; @@ -81,7 +81,8 @@ abstract class Participant extends DisposableChangeN ParticipantPermissions get permissions => _permissions; /// Attributes associated with the participant - UnmodifiableMapView get attributes => UnmodifiableMapView(_attributes); + UnmodifiableMapView get attributes => + UnmodifiableMapView(_attributes); Map _attributes = {}; // Participant state @@ -92,7 +93,8 @@ abstract class Participant extends DisposableChangeN DateTime get joinedAt { final pi = _participantInfo; if (pi != null) { - return DateTime.fromMillisecondsSinceEpoch(pi.joinedAt.toInt() * 1000, isUtc: true); + return DateTime.fromMillisecondsSinceEpoch(pi.joinedAt.toInt() * 1000, + isUtc: true); } return DateTime.now(); } @@ -191,10 +193,14 @@ abstract class Participant extends DisposableChangeN } void _setAttributes(Map attrs) { - final diff = mapDiff(_attributes, attrs).map((k, v) => MapEntry(k as String, v as String)); + final diff = mapDiff(_attributes, attrs) + .map((k, v) => MapEntry(k as String, v as String)); _attributes = attrs; if (diff.isNotEmpty) { - [events, room.events].emit(ParticipantAttributesChanged(participant: this, attributes: diff)); + [ + events, + room.events + ].emit(ParticipantAttributesChanged(participant: this, attributes: diff)); } } @@ -211,7 +217,9 @@ abstract class Participant extends DisposableChangeN @internal Future updateFromInfo(lk_models.ParticipantInfo info) async { logger.fine('LocalParticipant.updateFromInfo(info: $info)'); - if (_participantInfo != null && _participantInfo!.sid == info.sid && _participantInfo!.version > info.version) { + if (_participantInfo != null && + _participantInfo!.sid == info.sid && + _participantInfo!.version > info.version) { return false; } @@ -287,14 +295,19 @@ abstract class Participant extends DisposableChangeN T? getTrackPublicationBySource(TrackSource source) { if (source == TrackSource.unknown) return null; // try to find by source - final result = trackPublications.values.firstWhereOrNull((e) => e.source == source); + final result = + trackPublications.values.firstWhereOrNull((e) => e.source == source); if (result != null) return result; // try to find by compatibility - return trackPublications.values.where((e) => e.source == TrackSource.unknown).firstWhereOrNull((e) => - (source == TrackSource.microphone && e.kind == TrackType.AUDIO) || - (source == TrackSource.camera && e.kind == TrackType.VIDEO) || - (source == TrackSource.screenShareVideo && e.kind == TrackType.VIDEO) || - (source == TrackSource.screenShareAudio && e.kind == TrackType.AUDIO)); + return trackPublications.values + .where((e) => e.source == TrackSource.unknown) + .firstWhereOrNull((e) => + (source == TrackSource.microphone && e.kind == TrackType.AUDIO) || + (source == TrackSource.camera && e.kind == TrackType.VIDEO) || + (source == TrackSource.screenShareVideo && + e.kind == TrackType.VIDEO) || + (source == TrackSource.screenShareAudio && + e.kind == TrackType.AUDIO)); } /// Convenience property to check whether [TrackSource.camera] is published or not. @@ -304,17 +317,20 @@ abstract class Participant extends DisposableChangeN /// Convenience property to check whether [TrackSource.microphone] is published or not. bool isMicrophoneEnabled() { - return !(getTrackPublicationBySource(TrackSource.microphone)?.muted ?? true); + return !(getTrackPublicationBySource(TrackSource.microphone)?.muted ?? + true); } /// Convenience property to check whether [TrackSource.screenShareVideo] is published or not. bool isScreenShareEnabled() { - return !(getTrackPublicationBySource(TrackSource.screenShareVideo)?.muted ?? true); + return !(getTrackPublicationBySource(TrackSource.screenShareVideo)?.muted ?? + true); } /// Convenience property to check whether [TrackSource.screenShareAudio] is published or not. bool isScreenShareAudioEnabled() { - return !(getTrackPublicationBySource(TrackSource.screenShareAudio)?.muted ?? true); + return !(getTrackPublicationBySource(TrackSource.screenShareAudio)?.muted ?? + true); } /// (Equality operator) [Participant.hashCode] is same as [sid.hashCode]. diff --git a/lib/src/types/participant_state.dart b/lib/src/types/participant_state.dart index 6691b5e5c..8f278686e 100644 --- a/lib/src/types/participant_state.dart +++ b/lib/src/types/participant_state.dart @@ -37,7 +37,8 @@ extension ParticipantStateExt on lk_models.ParticipantInfo_State { lk_models.ParticipantInfo_State.JOINING => ParticipantState.joining, lk_models.ParticipantInfo_State.JOINED => ParticipantState.joined, lk_models.ParticipantInfo_State.ACTIVE => ParticipantState.active, - lk_models.ParticipantInfo_State.DISCONNECTED => ParticipantState.disconnected, + lk_models.ParticipantInfo_State.DISCONNECTED => + ParticipantState.disconnected, _ => ParticipantState.unknown, }; } From 1cd7c2a50bd27b5819f1a8704c1e533ecfbe2164 Mon Sep 17 00:00:00 2001 From: Tobias Ollmann Date: Tue, 26 Aug 2025 08:49:29 +0200 Subject: [PATCH 08/11] chore: update webrtc sdk to same version as flutter-webrtc --- ios/livekit_client.podspec | 2 +- macos/livekit_client.podspec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ios/livekit_client.podspec b/ios/livekit_client.podspec index dde89354e..bae4ad60a 100644 --- a/ios/livekit_client.podspec +++ b/ios/livekit_client.podspec @@ -16,6 +16,6 @@ Pod::Spec.new do |s| s.static_framework = true s.dependency 'Flutter' - s.dependency 'WebRTC-SDK', '137.7151.02' + s.dependency 'WebRTC-SDK', '137.7151.03' s.dependency 'flutter_webrtc' end diff --git a/macos/livekit_client.podspec b/macos/livekit_client.podspec index 285fa6420..5000c68cc 100644 --- a/macos/livekit_client.podspec +++ b/macos/livekit_client.podspec @@ -16,6 +16,6 @@ Pod::Spec.new do |s| s.static_framework = true s.dependency 'FlutterMacOS' - s.dependency 'WebRTC-SDK', '137.7151.02' + s.dependency 'WebRTC-SDK', '137.7151.03' s.dependency 'flutter_webrtc' end From 1b0a28684499d56db85c9c15d8411d29b097f8be Mon Sep 17 00:00:00 2001 From: Tobias Ollmann Date: Tue, 26 Aug 2025 08:51:46 +0200 Subject: [PATCH 09/11] chore: run import sorter --- lib/src/core/engine.dart | 8 +++++--- lib/src/track/audio_visualizer.dart | 2 +- lib/src/track/local/video.dart | 3 ++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/src/core/engine.dart b/lib/src/core/engine.dart index 28f075816..353be0eea 100644 --- a/lib/src/core/engine.dart +++ b/lib/src/core/engine.dart @@ -16,9 +16,10 @@ import 'dart:async'; +import 'package:flutter/foundation.dart'; + import 'package:collection/collection.dart'; import 'package:connectivity_plus/connectivity_plus.dart'; -import 'package:flutter/foundation.dart'; import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc; import 'package:meta/meta.dart'; @@ -34,8 +35,6 @@ import '../proto/livekit_models.pb.dart' as lk_models; import '../proto/livekit_rtc.pb.dart' as lk_rtc; import '../publication/local.dart'; import '../support/disposable.dart'; -import '../support/platform.dart' - show lkPlatformIsTest, lkPlatformIs, PlatformType; import '../support/region_url_provider.dart'; import '../support/websocket.dart'; import '../track/local/local.dart'; @@ -45,6 +44,9 @@ import '../types/other.dart'; import 'signal_client.dart'; import 'transport.dart'; +import '../support/platform.dart' + show lkPlatformIsTest, lkPlatformIs, PlatformType; + const maxRetryDelay = 7000; const defaultRetryDelaysInMs = [ diff --git a/lib/src/track/audio_visualizer.dart b/lib/src/track/audio_visualizer.dart index 9f4982ae0..0db094462 100644 --- a/lib/src/track/audio_visualizer.dart +++ b/lib/src/track/audio_visualizer.dart @@ -1,8 +1,8 @@ import 'package:uuid/uuid.dart' as uuid; -import '../support/disposable.dart'; import '../events.dart' show AudioVisualizerEvent; import '../managers/event.dart' show EventsEmittable; +import '../support/disposable.dart'; import 'local/local.dart' show AudioTrack; import 'audio_visualizer_native.dart' diff --git a/lib/src/track/local/video.dart b/lib/src/track/local/video.dart index ee06df1c3..63d566db5 100644 --- a/lib/src/track/local/video.dart +++ b/lib/src/track/local/video.dart @@ -12,8 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -import 'package:collection/collection.dart'; import 'package:flutter/foundation.dart'; + +import 'package:collection/collection.dart'; import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc; import '../../events.dart'; From 8d8609531fbca20072fad7509c18cff30ff75803 Mon Sep 17 00:00:00 2001 From: Tobias Ollmann Date: Tue, 26 Aug 2025 09:11:05 +0200 Subject: [PATCH 10/11] chore: fix analyzer issues --- lib/src/core/engine.dart | 1 - lib/src/core/room.dart | 1 - lib/src/core/signal_client.dart | 1 - lib/src/data_stream/stream_reader.dart | 4 ++-- lib/src/data_stream/stream_writer.dart | 2 +- lib/src/managers/broadcast_manager.dart | 2 -- lib/src/participant/local.dart | 1 - lib/src/track/local/local.dart | 1 - lib/src/track/track.dart | 1 - lib/src/utils.dart | 1 - 10 files changed, 3 insertions(+), 12 deletions(-) diff --git a/lib/src/core/engine.dart b/lib/src/core/engine.dart index 353be0eea..2fd725758 100644 --- a/lib/src/core/engine.dart +++ b/lib/src/core/engine.dart @@ -21,7 +21,6 @@ import 'package:flutter/foundation.dart'; import 'package:collection/collection.dart'; import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc; -import 'package:meta/meta.dart'; import '../events.dart'; import '../exceptions.dart'; diff --git a/lib/src/core/room.dart b/lib/src/core/room.dart index c6d5bc4f1..04c577eee 100644 --- a/lib/src/core/room.dart +++ b/lib/src/core/room.dart @@ -18,7 +18,6 @@ import 'package:flutter/foundation.dart'; import 'package:collection/collection.dart'; import 'package:http/http.dart' as http; -import 'package:meta/meta.dart'; import '../core/signal_client.dart'; import '../data_stream/stream_reader.dart'; diff --git a/lib/src/core/signal_client.dart b/lib/src/core/signal_client.dart index 21be53781..bb3a706fc 100644 --- a/lib/src/core/signal_client.dart +++ b/lib/src/core/signal_client.dart @@ -21,7 +21,6 @@ import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:fixnum/fixnum.dart'; import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc; import 'package:http/http.dart' as http; -import 'package:meta/meta.dart'; import '../events.dart'; import '../exceptions.dart'; diff --git a/lib/src/data_stream/stream_reader.dart b/lib/src/data_stream/stream_reader.dart index ba458b705..44dd300fc 100644 --- a/lib/src/data_stream/stream_reader.dart +++ b/lib/src/data_stream/stream_reader.dart @@ -18,8 +18,8 @@ abstract class BaseStreamReader { BaseStreamReader(T info, DataStreamController stream, this._totalByteSize) { - this.reader = stream; - this._info = info; + reader = stream; + _info = info; } void handleChunkReceived(DataStream_Chunk chunk); diff --git a/lib/src/data_stream/stream_writer.dart b/lib/src/data_stream/stream_writer.dart index 1d2832a80..bfb702cb4 100644 --- a/lib/src/data_stream/stream_writer.dart +++ b/lib/src/data_stream/stream_writer.dart @@ -24,7 +24,7 @@ class BaseStreamWriter { Future close() async { await writableStream.close(); - this.onClose?.call(); + onClose?.call(); } } diff --git a/lib/src/managers/broadcast_manager.dart b/lib/src/managers/broadcast_manager.dart index 913d7a7b2..84f97b03e 100644 --- a/lib/src/managers/broadcast_manager.dart +++ b/lib/src/managers/broadcast_manager.dart @@ -14,8 +14,6 @@ import 'package:flutter/foundation.dart'; -import 'package:meta/meta.dart'; - import '../support/native.dart'; /// Manages broadcast state and track publication for screen sharing on iOS. diff --git a/lib/src/participant/local.dart b/lib/src/participant/local.dart index 823513819..3dc0f298b 100644 --- a/lib/src/participant/local.dart +++ b/lib/src/participant/local.dart @@ -23,7 +23,6 @@ import 'package:flutter/foundation.dart'; import 'package:async/async.dart'; import 'package:fixnum/fixnum.dart'; import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc; -import 'package:meta/meta.dart'; import 'package:mime_type/mime_type.dart'; import 'package:path/path.dart'; import 'package:uuid/uuid.dart'; diff --git a/lib/src/track/local/local.dart b/lib/src/track/local/local.dart index 7e0321774..20373dab1 100644 --- a/lib/src/track/local/local.dart +++ b/lib/src/track/local/local.dart @@ -18,7 +18,6 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc; -import 'package:meta/meta.dart'; import '../../events.dart'; import '../../exceptions.dart'; diff --git a/lib/src/track/track.dart b/lib/src/track/track.dart index f15015900..999ca4a22 100644 --- a/lib/src/track/track.dart +++ b/lib/src/track/track.dart @@ -17,7 +17,6 @@ import 'dart:async'; import 'package:flutter/foundation.dart'; import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc; -import 'package:meta/meta.dart'; import 'package:uuid/uuid.dart'; import '../events.dart'; diff --git a/lib/src/utils.dart b/lib/src/utils.dart index 3a45de6a1..eaa21b5a5 100644 --- a/lib/src/utils.dart +++ b/lib/src/utils.dart @@ -22,7 +22,6 @@ import 'package:collection/collection.dart'; import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:device_info_plus/device_info_plus.dart'; import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc; -import 'package:meta/meta.dart'; import './proto/livekit_models.pb.dart' as lk_models; import './support/native.dart'; From 5d24c85fb88c04c094eeda529bfdb596780e0711 Mon Sep 17 00:00:00 2001 From: Tobias Ollmann Date: Mon, 1 Sep 2025 08:17:27 +0200 Subject: [PATCH 11/11] chore: fix imports after merge from main --- lib/src/core/engine.dart | 2 ++ lib/src/core/room.dart | 1 + lib/src/core/signal_client.dart | 1 + lib/src/managers/broadcast_manager.dart | 2 ++ lib/src/participant/local.dart | 1 + lib/src/track/local/local.dart | 1 + lib/src/track/track.dart | 1 + lib/src/utils.dart | 1 + 8 files changed, 10 insertions(+) diff --git a/lib/src/core/engine.dart b/lib/src/core/engine.dart index f05881bc1..d22e80904 100644 --- a/lib/src/core/engine.dart +++ b/lib/src/core/engine.dart @@ -21,6 +21,7 @@ import 'package:flutter/foundation.dart' hide internal; import 'package:collection/collection.dart'; import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc; +import 'package:meta/meta.dart'; import '../events.dart'; import '../exceptions.dart'; @@ -312,6 +313,7 @@ class Engine extends Disposable with EventsEmittable { completer.completeError('Engine disconnected'); } } + events.once((e) => onClosing()); while (!_dcBufferStatus[kind]!) { diff --git a/lib/src/core/room.dart b/lib/src/core/room.dart index 7ed32ae38..7a019d86d 100644 --- a/lib/src/core/room.dart +++ b/lib/src/core/room.dart @@ -18,6 +18,7 @@ import 'package:flutter/foundation.dart' hide internal; import 'package:collection/collection.dart'; import 'package:http/http.dart' as http; +import 'package:meta/meta.dart'; import '../core/signal_client.dart'; import '../data_stream/stream_reader.dart'; diff --git a/lib/src/core/signal_client.dart b/lib/src/core/signal_client.dart index 4a6d6f0ac..a25ed8f27 100644 --- a/lib/src/core/signal_client.dart +++ b/lib/src/core/signal_client.dart @@ -21,6 +21,7 @@ import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:fixnum/fixnum.dart'; import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc; import 'package:http/http.dart' as http; +import 'package:meta/meta.dart'; import '../events.dart'; import '../exceptions.dart'; diff --git a/lib/src/managers/broadcast_manager.dart b/lib/src/managers/broadcast_manager.dart index d0fd6a55b..590bddb8b 100644 --- a/lib/src/managers/broadcast_manager.dart +++ b/lib/src/managers/broadcast_manager.dart @@ -14,6 +14,8 @@ import 'package:flutter/foundation.dart' hide internal; +import 'package:meta/meta.dart'; + import '../support/native.dart'; /// Manages broadcast state and track publication for screen sharing on iOS. diff --git a/lib/src/participant/local.dart b/lib/src/participant/local.dart index be5db2f2e..679e37fa9 100644 --- a/lib/src/participant/local.dart +++ b/lib/src/participant/local.dart @@ -23,6 +23,7 @@ import 'package:flutter/foundation.dart' hide internal; import 'package:async/async.dart'; import 'package:fixnum/fixnum.dart'; import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc; +import 'package:meta/meta.dart'; import 'package:mime_type/mime_type.dart'; import 'package:path/path.dart'; import 'package:uuid/uuid.dart'; diff --git a/lib/src/track/local/local.dart b/lib/src/track/local/local.dart index ccc2fdb14..64f046685 100644 --- a/lib/src/track/local/local.dart +++ b/lib/src/track/local/local.dart @@ -18,6 +18,7 @@ import 'package:flutter/foundation.dart' hide internal; import 'package:flutter/material.dart'; import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc; +import 'package:meta/meta.dart'; import '../../events.dart'; import '../../exceptions.dart'; diff --git a/lib/src/track/track.dart b/lib/src/track/track.dart index 84e36f969..62792e960 100644 --- a/lib/src/track/track.dart +++ b/lib/src/track/track.dart @@ -17,6 +17,7 @@ import 'dart:async'; import 'package:flutter/foundation.dart' hide internal; import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc; +import 'package:meta/meta.dart'; import 'package:uuid/uuid.dart'; import '../events.dart'; diff --git a/lib/src/utils.dart b/lib/src/utils.dart index 7d912fb73..8a786a5d4 100644 --- a/lib/src/utils.dart +++ b/lib/src/utils.dart @@ -22,6 +22,7 @@ import 'package:collection/collection.dart'; import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:device_info_plus/device_info_plus.dart'; import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc; +import 'package:meta/meta.dart'; import './proto/livekit_models.pb.dart' as lk_models; import './support/native.dart';