diff --git a/lib/src/publication/remote_track_publication.dart b/lib/src/publication/remote_track_publication.dart index ea1e71b..31cdcb1 100644 --- a/lib/src/publication/remote_track_publication.dart +++ b/lib/src/publication/remote_track_publication.dart @@ -49,6 +49,9 @@ class RemoteTrackPublication /// relevant event. StreamState get streamState => _streamState; + // latest TrackInfo + bool _metadataMuted = false; + @internal Future updateStreamState(StreamState streamState) async { // return if no change @@ -73,6 +76,8 @@ class RemoteTrackPublication required lk_models.TrackInfo info, T? track, }) : super(info: info) { + logger.fine('RemoteTrackPublication.init track: $track, info: $info'); + // register dispose func onDispose(() async { _cancelVisibilityDebounceFunc?.call(); @@ -92,8 +97,11 @@ class RemoteTrackPublication @internal @override void updateFromInfo(lk_models.TrackInfo info) { + logger.fine( + 'RemoteTrackPublication.updateFromInfo sid: ${info.sid} muted: ${info.muted}'); super.updateFromInfo(info); track?.updateMuted(info.muted); + _metadataMuted = info.muted; } // called any time visibility info updates @@ -169,29 +177,35 @@ class RemoteTrackPublication @internal @override Future updateTrack(covariant T? newValue) async { + logger.fine('RemoteTrackPublication.updateTrack track: $newValue'); final didUpdate = await super.updateTrack(newValue); - // Only listen for visibility updates if video optimization is on - // and the attached track is a video track final roomOptions = participant.room.roomOptions ?? const RoomOptions(); - // - if (didUpdate && - newValue != null && - roomOptions.optimizeVideo && - newValue.kind == lk_models.TrackType.VIDEO) { - // - // Attach visibility event listener (if video track) - // - final listener = newValue.createListener(); - listener.on( - _onVideoRendererVisibilityUpdateEvent); - // - newValue.onDispose(() async { - await listener.dispose(); - // consider all views are disposed when track is null - _visibilities.clear(); - if (!isDisposed) _visibilityDidUpdate?.call(null); - }); + + if (didUpdate && newValue != null) { + // if new Track has been set to this RemoteTrackPublication, + // update the Track's muted state from the latest info. + newValue.updateMuted( + _metadataMuted, + shouldNotify: false, // don't emit event since this is initial state + ); + + // Only listen for visibility updates if video optimization is on + // and the attached track is a video track + if (roomOptions.optimizeVideo && + newValue.kind == lk_models.TrackType.VIDEO) { + // Attach visibility event listener + final listener = newValue.createListener(); + listener.on( + _onVideoRendererVisibilityUpdateEvent); + + newValue.onDispose(() async { + await listener.dispose(); + // consider all views are disposed when track is null + _visibilities.clear(); + if (!isDisposed) _visibilityDidUpdate?.call(null); + }); + } } return didUpdate; diff --git a/lib/src/track/track.dart b/lib/src/track/track.dart index 6f1bc4a..76a8672 100644 --- a/lib/src/track/track.dart +++ b/lib/src/track/track.dart @@ -139,14 +139,20 @@ abstract class Track extends DisposableChangeNotifier } @internal - void updateMuted(bool muted, {bool shouldSendSignal = false}) { + void updateMuted( + bool muted, { + bool shouldNotify = true, + bool shouldSendSignal = false, + }) { if (_muted == muted) return; _muted = muted; - events.emit(InternalTrackMuteUpdatedEvent( - track: this, - muted: muted, - shouldSendSignal: shouldSendSignal, - )); + if (shouldNotify) { + events.emit(InternalTrackMuteUpdatedEvent( + track: this, + muted: muted, + shouldSendSignal: shouldSendSignal, + )); + } } @internal