From 8cd8edb6177ed05a2be690ba5f789de6bacc9ef3 Mon Sep 17 00:00:00 2001 From: Hiroshi Horie <548776+hiroshihorie@users.noreply.github.com> Date: Thu, 21 Oct 2021 06:14:21 +0900 Subject: [PATCH] Fix track subscribe (#20) * fixed * format * set track to null * rearrange --- lib/src/rtc_engine.dart | 18 ++++++++++ lib/src/track/remote_track_publication.dart | 40 ++++++++++++++------- 2 files changed, 45 insertions(+), 13 deletions(-) diff --git a/lib/src/rtc_engine.dart b/lib/src/rtc_engine.dart index d0ef4bc..060e45d 100644 --- a/lib/src/rtc_engine.dart +++ b/lib/src/rtc_engine.dart @@ -337,6 +337,8 @@ class RTCEngine extends Disposable with EventsEmittable { }); subscriber?.pc.onTrack = (rtc.RTCTrackEvent event) { + logger.fine('[WebRTC] pc.onTrack'); + final stream = event.streams.firstOrNull; if (stream == null) { // we need the stream to get the track's id @@ -344,6 +346,16 @@ class RTCEngine extends Disposable with EventsEmittable { return; } + // doesn't get called reliably + event.track.onEnded = () { + logger.fine('[WebRTC] track.onEnded'); + }; + + // doesn't get called reliably + stream.onRemoveTrack = (_) { + logger.fine('[WebRTC] stream.onRemoveTrack'); + }; + events.emit(EngineTrackAddedEvent( track: event.track, stream: stream, @@ -351,6 +363,12 @@ class RTCEngine extends Disposable with EventsEmittable { )); }; + // doesn't get called reliably, doesn't work on mac + subscriber?.pc.onRemoveTrack = + (rtc.MediaStream stream, rtc.MediaStreamTrack track) { + logger.fine('[WebRTC] ${track.id} pc.onRemoveTrack'); + }; + // also handle messages over the pub channel, for backwards compatibility try { final lossyInit = rtc.RTCDataChannelInit() diff --git a/lib/src/track/remote_track_publication.dart b/lib/src/track/remote_track_publication.dart index fef7ba6..38729f7 100644 --- a/lib/src/track/remote_track_publication.dart +++ b/lib/src/track/remote_track_publication.dart @@ -1,3 +1,5 @@ +import 'package:livekit_client/src/logger.dart'; + import '../events.dart'; import '../extensions.dart'; import '../participant/remote_participant.dart'; @@ -10,10 +12,8 @@ import 'track_publication.dart'; /// control if we should subscribe to the track, and its quality (for video). class RemoteTrackPublication extends TrackPublication { final RemoteParticipant _participant; - bool _unsubscribed = false; bool _disabled = false; lk_rtc.VideoQuality _videoQuality = lk_rtc.VideoQuality.HIGH; - lk_rtc.VideoQuality get videoQuality => _videoQuality; set videoQuality(lk_rtc.VideoQuality val) { @@ -29,18 +29,23 @@ class RemoteTrackPublication extends TrackPublication { _sendUpdateTrackSettings(); } - @override - bool get subscribed { - if (_unsubscribed) { - return false; - } - return super.subscribed; - } - set subscribed(bool val) { - if (_unsubscribed == !val) return; - _unsubscribed = !val; - _sendUpdateTrackSettings(); + logger.fine('setting subscribed = ${val}'); + if (val == super.subscribed) return; + _sendUpdateSubscription(subscribed: val); + if (!val && track != null) { + // Ideally, we should wait for WebRTC's onRemoveTrack event + // but it does not work reliably across platforms. + // So for now we will assume remove track succeeded. + [_participant.events, _participant.roomEvents] + .emit(TrackUnsubscribedEvent( + participant: _participant, + track: track!, + publication: this, + )); + // Simply set to null for now + track = null; + } } /// for internal use @@ -77,6 +82,15 @@ class RemoteTrackPublication extends TrackPublication { this.track = track; } + void _sendUpdateSubscription({required bool subscribed}) { + logger.fine('Sending update subscription... ${sid} ${subscribed}'); + final subscription = lk_rtc.UpdateSubscription( + trackSids: [sid], + subscribe: subscribed, + ); + _participant.client.sendUpdateSubscription(subscription); + } + void _sendUpdateTrackSettings() { final settings = lk_rtc.UpdateTrackSettings( trackSids: [sid],