From 79a2d2070260ea5bbe1d127bfd6d9f1899c1e982 Mon Sep 17 00:00:00 2001 From: Hiroshi Horie <548776+hiroshihorie@users.noreply.github.com> Date: Thu, 28 Oct 2021 02:57:15 +0900 Subject: [PATCH] `optimizeVideo` option --- lib/src/options.dart | 9 +++++++++ lib/src/participant/remote_participant.dart | 10 +++++----- lib/src/room.dart | 6 +++--- lib/src/rtc_engine.dart | 14 ++++++++++++-- lib/src/signal_client.dart | 5 +---- lib/src/track/remote_track_publication.dart | 12 ++++++++---- 6 files changed, 38 insertions(+), 18 deletions(-) diff --git a/lib/src/options.dart b/lib/src/options.dart index 154c096..bb2e1d6 100644 --- a/lib/src/options.dart +++ b/lib/src/options.dart @@ -12,10 +12,19 @@ class ConnectOptions { /// Default options used when publishing a audio track final AudioPublishOptions defaultAudioPublishOptions; + /// When this is turned on, the following optimizations will be made: + /// - [RemoteTrackPublication] will be enabled/disabled based on the corresponding + /// [VideoTrackRenderer]'s visibility on screen. + /// - Re-sizing a [VideoTrackRenderer] will signal the server to send down + /// a relavant quality layer (if simulcast is enabled on the publisher) + /// defaults to true. + final bool optimizeVideo; + const ConnectOptions({ this.autoSubscribe = true, this.defaultVideoPublishOptions = const VideoPublishOptions(), this.defaultAudioPublishOptions = const AudioPublishOptions(), + this.optimizeVideo = true, }); } diff --git a/lib/src/participant/remote_participant.dart b/lib/src/participant/remote_participant.dart index 1185607..5c3e047 100644 --- a/lib/src/participant/remote_participant.dart +++ b/lib/src/participant/remote_participant.dart @@ -9,7 +9,7 @@ import '../extensions.dart'; import '../logger.dart'; import '../managers/event.dart'; import '../proto/livekit_models.pb.dart' as lk_models; -import '../signal_client.dart'; +import '../rtc_engine.dart'; import '../track/remote_track_publication.dart'; import '../track/track.dart'; import '../types.dart'; @@ -17,11 +17,11 @@ import 'participant.dart'; /// Represents other participant in the [Room]. class RemoteParticipant extends Participant { - final SignalClient _client; - SignalClient get client => _client; + final RTCEngine _engine; + RTCEngine get engine => _engine; RemoteParticipant( - this._client, + this._engine, String sid, String identity, { required EventsEmitter roomEvents, @@ -32,7 +32,7 @@ class RemoteParticipant extends Participant { ); RemoteParticipant.fromInfo( - this._client, + this._engine, lk_models.ParticipantInfo info, { required EventsEmitter roomEvents, }) : super( diff --git a/lib/src/room.dart b/lib/src/room.dart index 36514b6..7e8905c 100644 --- a/lib/src/room.dart +++ b/lib/src/room.dart @@ -119,7 +119,7 @@ class Room extends DisposableChangeNotifier with EventsEmittable { final joinResponse = await engine.join( url, token, - options: options, + connectOptions: options, ); logger.fine( @@ -227,14 +227,14 @@ class Room extends DisposableChangeNotifier with EventsEmittable { if (info == null) { participant = RemoteParticipant( - engine.signalClient, + engine, sid, '', roomEvents: events, ); } else { participant = RemoteParticipant.fromInfo( - engine.signalClient, + engine, info, roomEvents: events, ); diff --git a/lib/src/rtc_engine.dart b/lib/src/rtc_engine.dart index 55ef632..4a4f9c9 100644 --- a/lib/src/rtc_engine.dart +++ b/lib/src/rtc_engine.dart @@ -30,6 +30,8 @@ class RTCEngine extends Disposable with EventsEmittable { // config for RTCPeerConnection final RTCConfiguration? rtcConfig; + ConnectOptions connectOptions = const ConnectOptions(); + @internal PCTransport? publisher; @@ -91,13 +93,21 @@ class RTCEngine extends Disposable with EventsEmittable { Future join( String url, String token, { - ConnectOptions? options, + ConnectOptions? connectOptions, }) async { this.url = url; this.token = token; + if (connectOptions != null) { + this.connectOptions = connectOptions; + } + // connect to rtc server - await signalClient.connect(url, token, options: options); + await signalClient.connect( + url, + token, + options: this.connectOptions, + ); // wait for join response final event = await _signalListener.waitFor( diff --git a/lib/src/signal_client.dart b/lib/src/signal_client.dart index eef894b..d37a547 100644 --- a/lib/src/signal_client.dart +++ b/lib/src/signal_client.dart @@ -41,11 +41,8 @@ class SignalClient extends Disposable with EventsEmittable { Future connect( String uriString, String token, { - ConnectOptions? options, + required ConnectOptions options, }) async { - // Create default options if null - options ??= const ConnectOptions(); - final rtcUri = Utils.buildUri( uriString, token: token, diff --git a/lib/src/track/remote_track_publication.dart b/lib/src/track/remote_track_publication.dart index e5ba1b1..b09dd4a 100644 --- a/lib/src/track/remote_track_publication.dart +++ b/lib/src/track/remote_track_publication.dart @@ -130,7 +130,7 @@ class RemoteTrackPublication extends TrackPublication { } logger.fine('[Visibility] Sending to server ${settings.toProto3Json()}'); - _participant.client.sendUpdateTrackSettings(settings); + _participant.engine.signalClient.sendUpdateTrackSettings(settings); } @override @@ -141,7 +141,11 @@ class RemoteTrackPublication extends TrackPublication { super.track?.dispose(); super.track = newValue; - if (newValue != null && newValue.kind == lk_models.TrackType.VIDEO) { + // Only listen for visibility updates if video optimization is on + // and the attached track is a video track + if (_participant.engine.connectOptions.optimizeVideo && + newValue != null && + newValue.kind == lk_models.TrackType.VIDEO) { // // Attach visibility event listener (if video track) // @@ -223,7 +227,7 @@ class RemoteTrackPublication extends TrackPublication { trackSids: [sid], subscribe: subscribed, ); - _participant.client.sendUpdateSubscription(subscription); + _participant.engine.signalClient.sendUpdateSubscription(subscription); } void _sendUpdateTrackSettings() { @@ -234,6 +238,6 @@ class RemoteTrackPublication extends TrackPublication { if (kind == lk_models.TrackType.VIDEO) { settings.quality = _videoQuality; } - _participant.client.sendUpdateTrackSettings(settings); + _participant.engine.signalClient.sendUpdateTrackSettings(settings); } }