浏览代码

feat(multi-stream-support) Do not assume a single local or remote track/mediaType.

dev1
Jaya Allamsetty 3 年前
父节点
当前提交
310e88224e

+ 6
- 13
JitsiConference.js 查看文件

@@ -2006,11 +2006,9 @@ JitsiConference.prototype.onDisplayNameChanged = function(jid, displayName) {
2006 2006
 };
2007 2007
 
2008 2008
 /**
2009
- * Notifies this JitsiConference that a JitsiRemoteTrack was added into
2010
- * the conference.
2009
+ * Notifies this JitsiConference that a JitsiRemoteTrack was added to the conference.
2011 2010
  *
2012
- * @param {JitsiRemoteTrack} track the JitsiRemoteTrack which was added to this
2013
- * JitsiConference
2011
+ * @param {JitsiRemoteTrack} track the JitsiRemoteTrack which was added to this JitsiConference.
2014 2012
  */
2015 2013
 JitsiConference.prototype.onRemoteTrackAdded = function(track) {
2016 2014
     if (track.isP2P && !this.isP2PActive()) {
@@ -2044,16 +2042,13 @@ JitsiConference.prototype.onRemoteTrackAdded = function(track) {
2044 2042
     track.addEventListener(
2045 2043
         JitsiTrackEvents.TRACK_MUTE_CHANGED,
2046 2044
         () => emitter.emit(JitsiConferenceEvents.TRACK_MUTE_CHANGED, track));
2047
-    track.addEventListener(
2045
+    track.isAudioTrack() && track.addEventListener(
2048 2046
         JitsiTrackEvents.TRACK_AUDIO_LEVEL_CHANGED,
2049 2047
         (audioLevel, tpc) => {
2050 2048
             const activeTPC = this.getActivePeerConnection();
2051 2049
 
2052 2050
             if (activeTPC === tpc) {
2053
-                emitter.emit(
2054
-                    JitsiConferenceEvents.TRACK_AUDIO_LEVEL_CHANGED,
2055
-                    id,
2056
-                    audioLevel);
2051
+                emitter.emit(JitsiConferenceEvents.TRACK_AUDIO_LEVEL_CHANGED, id, audioLevel);
2057 2052
             }
2058 2053
         }
2059 2054
     );
@@ -3016,8 +3011,7 @@ JitsiConference.prototype._acceptP2PIncomingCall = function(jingleSession, jingl
3016 3011
  * @private
3017 3012
  */
3018 3013
 JitsiConference.prototype._addRemoteJVBTracks = function() {
3019
-    this._addRemoteTracks(
3020
-        'JVB', this.jvbJingleSession.peerconnection.getRemoteTracks());
3014
+    this._addRemoteTracks('JVB', this.jvbJingleSession.peerconnection.getRemoteTracks());
3021 3015
 };
3022 3016
 
3023 3017
 /**
@@ -3025,8 +3019,7 @@ JitsiConference.prototype._addRemoteJVBTracks = function() {
3025 3019
  * @private
3026 3020
  */
3027 3021
 JitsiConference.prototype._addRemoteP2PTracks = function() {
3028
-    this._addRemoteTracks(
3029
-        'P2P', this.p2pJingleSession.peerconnection.getRemoteTracks());
3022
+    this._addRemoteTracks('P2P', this.p2pJingleSession.peerconnection.getRemoteTracks());
3030 3023
 };
3031 3024
 
3032 3025
 /**

+ 71
- 145
modules/RTC/TraceablePeerConnection.js 查看文件

@@ -138,12 +138,10 @@ export default function TraceablePeerConnection(
138 138
      */
139 139
     this.isP2P = isP2P;
140 140
 
141
-    // FIXME: We should support multiple streams per jid.
142 141
     /**
143
-     * The map holds remote tracks associated with this peer connection.
144
-     * It maps user's JID to media type and remote track
145
-     * (one track per media type per user's JID).
146
-     * @type {Map<string, Map<MediaType, JitsiRemoteTrack>>}
142
+     * The map holds remote tracks associated with this peer connection. It maps user's JID to media type and a set of
143
+     * remote tracks.
144
+     * @type {Map<string, Map<MediaType, Set<JitsiRemoteTrack>>>}
147 145
      */
148 146
     this.remoteTracks = new Map();
149 147
 
@@ -606,18 +604,19 @@ TraceablePeerConnection.prototype.getLocalTracks = function(mediaType) {
606 604
 };
607 605
 
608 606
 /**
609
- * Retrieves the local video track.
607
+ * Retrieves the local video tracks.
610 608
  *
611
- * @returns {JitsiLocalTrack|undefined} - local video track.
609
+ * @returns {JitsiLocalTrack|undefined} - local video tracks.
612 610
  */
613
-TraceablePeerConnection.prototype.getLocalVideoTrack = function() {
614
-    return this.getLocalTracks(MediaType.VIDEO)[0];
611
+TraceablePeerConnection.prototype.getLocalVideoTracks = function() {
612
+    return this.getLocalTracks(MediaType.VIDEO);
615 613
 };
616 614
 
617 615
 /**
618
- * Checks whether or not this {@link TraceablePeerConnection} instance contains
619
- * any local tracks for given <tt>mediaType</tt>.
620
- * @param {MediaType} mediaType
616
+ * Checks whether or not this {@link TraceablePeerConnection} instance contains any local tracks for given
617
+ * <tt>mediaType</tt>.
618
+ *
619
+ * @param {MediaType} mediaType - The media type.
621 620
  * @return {boolean}
622 621
  */
623 622
 TraceablePeerConnection.prototype.hasAnyTracksOfType = function(mediaType) {
@@ -630,35 +629,24 @@ TraceablePeerConnection.prototype.hasAnyTracksOfType = function(mediaType) {
630 629
 
631 630
 /**
632 631
  * Obtains all remote tracks currently known to this PeerConnection instance.
633
- * @param {string} [endpointId] the track owner's identifier (MUC nickname)
634
- * @param {MediaType} [mediaType] the remote tracks will be filtered
635
- * by their media type if this argument is specified.
632
+ *
633
+ * @param {string} [endpointId] - The track owner's identifier (MUC nickname)
634
+ * @param {MediaType} [mediaType] - The remote tracks will be filtered by their media type if this argument is
635
+ * specified.
636 636
  * @return {Array<JitsiRemoteTrack>}
637 637
  */
638
-TraceablePeerConnection.prototype.getRemoteTracks = function(
639
-        endpointId,
640
-        mediaType) {
641
-    const remoteTracks = [];
642
-    const endpoints
643
-        = endpointId ? [ endpointId ] : this.remoteTracks.keys();
638
+TraceablePeerConnection.prototype.getRemoteTracks = function(endpointId, mediaType) {
639
+    let remoteTracks = [];
640
+    const endpoints = endpointId ? [ endpointId ] : this.remoteTracks.keys();
644 641
 
645 642
     for (const endpoint of endpoints) {
646
-        const endpointTrackMap = this.remoteTracks.get(endpoint);
643
+        const endpointTracksByMediaType = this.remoteTracks.get(endpoint);
647 644
 
648
-        if (!endpointTrackMap) {
649
-
650
-            // Otherwise an empty Map() would have to be allocated above
651
-            // eslint-disable-next-line no-continue
652
-            continue;
653
-        }
654
-
655
-        for (const trackMediaType of endpointTrackMap.keys()) {
656
-            // per media type filtering
657
-            if (!mediaType || mediaType === trackMediaType) {
658
-                const mediaTrack = endpointTrackMap.get(trackMediaType);
659
-
660
-                if (mediaTrack) {
661
-                    remoteTracks.push(mediaTrack);
645
+        if (endpointTracksByMediaType) {
646
+            for (const trackMediaType of endpointTracksByMediaType.keys()) {
647
+                // per media type filtering
648
+                if (!mediaType || mediaType === trackMediaType) {
649
+                    remoteTracks = remoteTracks.concat(Array.from(endpointTracksByMediaType.get(trackMediaType)));
662 650
                 }
663 651
             }
664 652
         }
@@ -969,27 +957,26 @@ TraceablePeerConnection.prototype._createRemoteTrack = function(
969 957
 
970 958
     if (!remoteTracksMap) {
971 959
         remoteTracksMap = new Map();
960
+        remoteTracksMap.set(MediaType.AUDIO, new Set());
961
+        remoteTracksMap.set(MediaType.VIDEO, new Set());
972 962
         this.remoteTracks.set(ownerEndpointId, remoteTracksMap);
973 963
     }
974 964
 
975
-    const existingTrack = remoteTracksMap.get(mediaType);
965
+    const userTracksByMediaType = remoteTracksMap.get(mediaType);
976 966
 
977
-    if (existingTrack && existingTrack.getTrack() === track) {
967
+    if (userTracksByMediaType?.size
968
+        && Array.from(userTracksByMediaType).find(jitsiTrack => jitsiTrack.getTrack() === track)) {
978 969
         // Ignore duplicated event which can originate either from 'onStreamAdded' or 'onTrackAdded'.
979 970
         logger.info(`${this} ignored duplicated track event for track[endpoint=${ownerEndpointId},type=${mediaType}]`);
980 971
 
981 972
         return;
982
-    } else if (existingTrack) {
973
+    } else if (userTracksByMediaType?.size && !FeatureFlags.isSourceNameSignalingEnabled()) {
983 974
         logger.error(`${this} received a second remote track for track[endpoint=${ownerEndpointId},type=${mediaType}]`
984 975
             + 'deleting the existing track');
976
+        const existingTrack = Array.from(userTracksByMediaType)[0];
985 977
 
986
-        // The exisiting track needs to be removed here. We can get here when Jicofo reverses the order of source-add
987
-        // and source-remove messages. Ideally, when a remote endpoint changes source, like switching devices, it sends
988
-        // a source-remove (for old ssrc) followed by a source-add (for new ssrc) and Jicofo then should forward these
989
-        // two messages to all the other endpoints in the conference in the same order. However, sometimes, these
990
-        // messages arrive at the client in the reverse order resulting in two remote tracks (of same media type) being
991
-        // created and in case of video, a black strip (that of the first track which has ended) appears over the live
992
-        // track obscuring it. Removing the existing track when that happens will fix this issue.
978
+        // The exisiting track needs to be removed here. This happens on Safari sometimes when a SSRC is removed from
979
+        // the remote description and the browser doesn't fire a 'removetrack' event on the associated MediaStream.
993 980
         this._remoteTrackRemoved(existingTrack.getOriginalStream(), existingTrack.getTrack());
994 981
     }
995 982
 
@@ -1007,8 +994,7 @@ TraceablePeerConnection.prototype._createRemoteTrack = function(
1007 994
                 this.isP2P,
1008 995
                 sourceName);
1009 996
 
1010
-    remoteTracksMap.set(mediaType, remoteTrack);
1011
-
997
+    userTracksByMediaType.add(remoteTrack);
1012 998
     this.eventEmitter.emit(RTCEvents.REMOTE_TRACK_ADDED, remoteTrack, this);
1013 999
 };
1014 1000
 
@@ -1043,14 +1029,12 @@ TraceablePeerConnection.prototype._remoteStreamRemoved = function(stream) {
1043 1029
 
1044 1030
 /**
1045 1031
  * Handles remote media track removal.
1046
- * @param {MediaStream} stream WebRTC MediaStream instance which is the parent
1047
- * of the track.
1048
- * @param {MediaStreamTrack} track the WebRTC MediaStreamTrack which has been
1049
- * removed from the PeerConnection.
1032
+ *
1033
+ * @param {MediaStream} stream - WebRTC MediaStream instance which is the parent of the track.
1034
+ * @param {MediaStreamTrack} track - WebRTC MediaStreamTrack which has been removed from the PeerConnection.
1035
+ * @returns {void}
1050 1036
  */
1051
-TraceablePeerConnection.prototype._remoteTrackRemoved = function(
1052
-        stream,
1053
-        track) {
1037
+TraceablePeerConnection.prototype._remoteTrackRemoved = function(stream, track) {
1054 1038
     const streamId = RTC.getStreamID(stream);
1055 1039
     const trackId = track && RTC.getTrackID(track);
1056 1040
 
@@ -1059,7 +1043,6 @@ TraceablePeerConnection.prototype._remoteTrackRemoved = function(
1059 1043
 
1060 1044
         return;
1061 1045
     }
1062
-    logger.info(`${this} remote track removed stream[id=${streamId},trackId=${trackId}]`);
1063 1046
 
1064 1047
     if (!streamId) {
1065 1048
         GlobalOnErrorHandler.callErrorHandler(new Error(`${this} remote track removal failed - no stream ID`));
@@ -1073,67 +1056,33 @@ TraceablePeerConnection.prototype._remoteTrackRemoved = function(
1073 1056
         return;
1074 1057
     }
1075 1058
 
1076
-    if (!this._removeRemoteTrackById(streamId, trackId)) {
1077
-        // NOTE this warning is always printed when user leaves the room,
1078
-        // because we remove remote tracks manually on MUC member left event,
1079
-        // before the SSRCs are removed by Jicofo. In most cases it is fine to
1080
-        // ignore this warning, but still it's better to keep it printed for
1081
-        // debugging purposes.
1082
-        //
1083
-        // We could change the behaviour to emit track removed only from here,
1084
-        // but the order of the events will change and consuming apps could
1085
-        // behave unexpectedly (the "user left" event would come before "track
1086
-        // removed" events).
1087
-        logger.warn(`${this} Removed track not found for stream[id=${streamId},trackId=${trackId}]`);
1088
-    }
1089
-};
1059
+    const toBeRemoved = this.getRemoteTracks().find(
1060
+        remoteTrack => remoteTrack.getStreamId() === streamId
1061
+        && remoteTrack.getTrackId() === trackId);
1090 1062
 
1091
-/**
1092
- * Finds remote track by it's stream and track ids.
1093
- * @param {string} streamId the media stream id as defined by the WebRTC
1094
- * @param {string} trackId the media track id as defined by the WebRTC
1095
- * @return {JitsiRemoteTrack|undefined} the track's instance or
1096
- * <tt>undefined</tt> if not found.
1097
- * @private
1098
- */
1099
-TraceablePeerConnection.prototype._getRemoteTrackById = function(
1100
-        streamId,
1101
-        trackId) {
1102
-    // .find will break the loop once the first match is found
1103
-    for (const endpointTrackMap of this.remoteTracks.values()) {
1104
-        for (const mediaTrack of endpointTrackMap.values()) {
1105
-            // FIXME verify and try to use ===
1106
-            /* eslint-disable eqeqeq */
1107
-            if (mediaTrack.getStreamId() == streamId
1108
-                && mediaTrack.getTrackId() == trackId) {
1109
-                return mediaTrack;
1110
-            }
1063
+    if (!toBeRemoved) {
1064
+        GlobalOnErrorHandler.callErrorHandler(new Error(`${this} remote track removal failed - track not found`));
1111 1065
 
1112
-            /* eslint-enable eqeqeq */
1113
-        }
1066
+        return;
1114 1067
     }
1115 1068
 
1116
-    return undefined;
1069
+    logger.info(`${this} remote track removed stream[id=${streamId},trackId=${trackId}]`);
1070
+    this._removeRemoteTrack(toBeRemoved);
1117 1071
 };
1118 1072
 
1119 1073
 /**
1120
- * Removes all JitsiRemoteTracks associated with given MUC nickname
1121
- * (resource part of the JID). Returns array of removed tracks.
1074
+ * Removes all JitsiRemoteTracks associated with given MUC nickname (resource part of the JID).
1122 1075
  *
1123 1076
  * @param {string} owner - The resource part of the MUC JID.
1124
- * @returns {JitsiRemoteTrack[]}
1077
+ * @returns {JitsiRemoteTrack[]} - The array of removed tracks.
1125 1078
  */
1126 1079
 TraceablePeerConnection.prototype.removeRemoteTracks = function(owner) {
1127
-    const removedTracks = [];
1128
-    const remoteTracksMap = this.remoteTracks.get(owner);
1129
-
1130
-    if (remoteTracksMap) {
1131
-        const removedAudioTrack = remoteTracksMap.get(MediaType.AUDIO);
1132
-        const removedVideoTrack = remoteTracksMap.get(MediaType.VIDEO);
1133
-
1134
-        removedAudioTrack && removedTracks.push(removedAudioTrack);
1135
-        removedVideoTrack && removedTracks.push(removedVideoTrack);
1080
+    let removedTracks = [];
1081
+    const remoteTracksByMedia = this.remoteTracks.get(owner);
1136 1082
 
1083
+    if (remoteTracksByMedia) {
1084
+        removedTracks = removedTracks.concat(Array.from(remoteTracksByMedia.get(MediaType.AUDIO)));
1085
+        removedTracks = removedTracks.concat(Array.from(remoteTracksByMedia.get(MediaType.VIDEO)));
1137 1086
         this.remoteTracks.delete(owner);
1138 1087
     }
1139 1088
     logger.debug(`${this} removed remote tracks[endpoint=${owner},count=${removedTracks.length}`);
@@ -1142,45 +1091,24 @@ TraceablePeerConnection.prototype.removeRemoteTracks = function(owner) {
1142 1091
 };
1143 1092
 
1144 1093
 /**
1145
- * Removes and disposes given <tt>JitsiRemoteTrack</tt> instance. Emits
1146
- * {@link RTCEvents.REMOTE_TRACK_REMOVED}.
1147
- * @param {JitsiRemoteTrack} toBeRemoved
1094
+ * Removes and disposes given <tt>JitsiRemoteTrack</tt> instance. Emits {@link RTCEvents.REMOTE_TRACK_REMOVED}.
1095
+ *
1096
+ * @param {JitsiRemoteTrack} toBeRemoved - The remote track to be removed.
1097
+ * @returns {void}
1148 1098
  */
1149 1099
 TraceablePeerConnection.prototype._removeRemoteTrack = function(toBeRemoved) {
1150 1100
     toBeRemoved.dispose();
1151 1101
     const participantId = toBeRemoved.getParticipantId();
1152
-    const remoteTracksMap = this.remoteTracks.get(participantId);
1102
+    const userTracksByMediaType = this.remoteTracks.get(participantId);
1153 1103
 
1154
-    if (!remoteTracksMap) {
1104
+    if (!userTracksByMediaType) {
1155 1105
         logger.error(`${this} removeRemoteTrack: no remote tracks map for endpoint=${participantId}`);
1156
-    } else if (!remoteTracksMap.delete(toBeRemoved.getType())) {
1106
+    } else if (!userTracksByMediaType.get(toBeRemoved.getType())?.delete(toBeRemoved)) {
1157 1107
         logger.error(`${this} Failed to remove ${toBeRemoved} - type mapping messed up ?`);
1158 1108
     }
1159 1109
     this.eventEmitter.emit(RTCEvents.REMOTE_TRACK_REMOVED, toBeRemoved);
1160 1110
 };
1161 1111
 
1162
-/**
1163
- * Removes and disposes <tt>JitsiRemoteTrack</tt> identified by given stream and
1164
- * track ids.
1165
- *
1166
- * @param {string} streamId the media stream id as defined by the WebRTC
1167
- * @param {string} trackId the media track id as defined by the WebRTC
1168
- * @returns {JitsiRemoteTrack|undefined} the track which has been removed or
1169
- * <tt>undefined</tt> if no track matching given stream and track ids was
1170
- * found.
1171
- */
1172
-TraceablePeerConnection.prototype._removeRemoteTrackById = function(
1173
-        streamId,
1174
-        trackId) {
1175
-    const toBeRemoved = this._getRemoteTrackById(streamId, trackId);
1176
-
1177
-    if (toBeRemoved) {
1178
-        this._removeRemoteTrack(toBeRemoved);
1179
-    }
1180
-
1181
-    return toBeRemoved;
1182
-};
1183
-
1184 1112
 /**
1185 1113
  * Returns a map with keys msid/mediaType and <tt>TrackSSRCInfo</tt> values.
1186 1114
  * @param {RTCSessionDescription} desc the local description.
@@ -1614,13 +1542,12 @@ TraceablePeerConnection.prototype.isSharingLowFpsScreen = function() {
1614 1542
 /**
1615 1543
  * Checks if screensharing is in progress.
1616 1544
  *
1617
- * @returns {boolean}  Returns true if a desktop track has been added to the
1618
- * peerconnection, false otherwise.
1545
+ * @returns {boolean}  Returns true if a desktop track has been added to the peerconnection, false otherwise.
1619 1546
  */
1620 1547
 TraceablePeerConnection.prototype._isSharingScreen = function() {
1621
-    const track = this.getLocalVideoTrack();
1548
+    const tracks = this.getLocalVideoTracks();
1622 1549
 
1623
-    return track && track.videoType === VideoType.DESKTOP;
1550
+    return Boolean(tracks.find(track => track.videoType === VideoType.DESKTOP));
1624 1551
 };
1625 1552
 
1626 1553
 /**
@@ -2475,7 +2402,7 @@ TraceablePeerConnection.prototype.setSenderVideoConstraints = function(frameHeig
2475 2402
     }
2476 2403
 
2477 2404
     this._senderVideoMaxHeight = frameHeight;
2478
-    const localVideoTrack = this.getLocalVideoTrack();
2405
+    const localVideoTrack = this.getLocalVideoTracks()[0];
2479 2406
 
2480 2407
     if (!localVideoTrack || localVideoTrack.isMuted()) {
2481 2408
         return Promise.resolve();
@@ -2692,8 +2619,10 @@ TraceablePeerConnection.prototype.close = function() {
2692 2619
     this._usesUnifiedPlan && this.peerconnection.removeEventListener('track', this.onTrack);
2693 2620
 
2694 2621
     for (const peerTracks of this.remoteTracks.values()) {
2695
-        for (const remoteTrack of peerTracks.values()) {
2696
-            this._removeRemoteTrack(remoteTrack);
2622
+        for (const remoteTracks of peerTracks.values()) {
2623
+            for (const remoteTrack of remoteTracks) {
2624
+                this._removeRemoteTrack(remoteTrack);
2625
+            }
2697 2626
         }
2698 2627
     }
2699 2628
     this.remoteTracks.clear();
@@ -2755,7 +2684,7 @@ TraceablePeerConnection.prototype._createOfferOrAnswer = function(
2755 2684
                     dumpSDP(resultSdp));
2756 2685
             }
2757 2686
 
2758
-            const localVideoTrack = this.getLocalVideoTrack();
2687
+            const localVideoTrack = this.getLocalVideoTracks()[0];
2759 2688
 
2760 2689
             // Configure simulcast for camera tracks and for desktop tracks that need simulcast.
2761 2690
             if (this.isSimulcastOn() && browser.usesSdpMungingForSimulcast()
@@ -2764,10 +2693,7 @@ TraceablePeerConnection.prototype._createOfferOrAnswer = function(
2764 2693
                 || !this.isSharingLowFpsScreen())) {
2765 2694
                 // eslint-disable-next-line no-param-reassign
2766 2695
                 resultSdp = this.simulcast.mungeLocalDescription(resultSdp);
2767
-                this.trace(
2768
-                    `create${logName}`
2769
-                        + 'OnSuccess::postTransform (simulcast)',
2770
-                    dumpSDP(resultSdp));
2696
+                this.trace(`create${logName} OnSuccess::postTransform (simulcast)`, dumpSDP(resultSdp));
2771 2697
             }
2772 2698
 
2773 2699
             if (!this.options.disableRtx && browser.usesSdpMungingForSimulcast()) {

+ 2
- 4
types/auto/JitsiConference.d.ts 查看文件

@@ -627,11 +627,9 @@ declare class JitsiConference {
627 627
     onUserRoleChanged(jid: any, role: any): void;
628 628
     onDisplayNameChanged(jid: any, displayName: any): void;
629 629
     /**
630
-     * Notifies this JitsiConference that a JitsiRemoteTrack was added into
631
-     * the conference.
630
+     * Notifies this JitsiConference that a JitsiRemoteTrack was added to the conference.
632 631
      *
633
-     * @param {JitsiRemoteTrack} track the JitsiRemoteTrack which was added to this
634
-     * JitsiConference
632
+     * @param {JitsiRemoteTrack} track the JitsiRemoteTrack which was added to this JitsiConference.
635 633
      */
636 634
     onRemoteTrackAdded(track: any): void;
637 635
     /**

+ 26
- 38
types/auto/modules/RTC/TraceablePeerConnection.d.ts 查看文件

@@ -125,12 +125,11 @@ export default class TraceablePeerConnection {
125 125
      */
126 126
     isP2P: boolean;
127 127
     /**
128
-     * The map holds remote tracks associated with this peer connection.
129
-     * It maps user's JID to media type and remote track
130
-     * (one track per media type per user's JID).
131
-     * @type {Map<string, Map<MediaType, JitsiRemoteTrack>>}
128
+     * The map holds remote tracks associated with this peer connection. It maps user's JID to media type and a set of
129
+     * remote tracks.
130
+     * @type {Map<string, Map<MediaType, Set<JitsiRemoteTrack>>>}
132 131
      */
133
-    remoteTracks: Map<string, Map<typeof MediaType, JitsiRemoteTrack>>;
132
+    remoteTracks: Map<string, Map<typeof MediaType, Set<JitsiRemoteTrack>>>;
134 133
     /**
135 134
      * A map which stores local tracks mapped by {@link JitsiLocalTrack.rtcId}
136 135
      * @type {Map<number, JitsiLocalTrack>}
@@ -303,23 +302,25 @@ export default class TraceablePeerConnection {
303 302
      */
304 303
     getLocalTracks(mediaType?: typeof MediaType): Array<any>;
305 304
     /**
306
-     * Retrieves the local video track.
305
+     * Retrieves the local video tracks.
307 306
      *
308
-     * @returns {JitsiLocalTrack|undefined} - local video track.
307
+     * @returns {JitsiLocalTrack|undefined} - local video tracks.
309 308
      */
310
-    getLocalVideoTrack(): any | undefined;
309
+    getLocalVideoTracks(): any | undefined;
311 310
     /**
312
-     * Checks whether or not this {@link TraceablePeerConnection} instance contains
313
-     * any local tracks for given <tt>mediaType</tt>.
314
-     * @param {MediaType} mediaType
311
+     * Checks whether or not this {@link TraceablePeerConnection} instance contains any local tracks for given
312
+     * <tt>mediaType</tt>.
313
+     *
314
+     * @param {MediaType} mediaType - The media type.
315 315
      * @return {boolean}
316 316
      */
317 317
     hasAnyTracksOfType(mediaType: typeof MediaType): boolean;
318 318
     /**
319 319
      * Obtains all remote tracks currently known to this PeerConnection instance.
320
-     * @param {string} [endpointId] the track owner's identifier (MUC nickname)
321
-     * @param {MediaType} [mediaType] the remote tracks will be filtered
322
-     * by their media type if this argument is specified.
320
+     *
321
+     * @param {string} [endpointId] - The track owner's identifier (MUC nickname)
322
+     * @param {MediaType} [mediaType] - The remote tracks will be filtered by their media type if this argument is
323
+     * specified.
323 324
      * @return {Array<JitsiRemoteTrack>}
324 325
      */
325 326
     getRemoteTracks(endpointId?: string, mediaType?: typeof MediaType): Array<JitsiRemoteTrack>;
@@ -392,38 +393,26 @@ export default class TraceablePeerConnection {
392 393
     _remoteStreamRemoved(stream: any): void;
393 394
     /**
394 395
      * Handles remote media track removal.
395
-     * @param {MediaStream} stream WebRTC MediaStream instance which is the parent
396
-     * of the track.
397
-     * @param {MediaStreamTrack} track the WebRTC MediaStreamTrack which has been
398
-     * removed from the PeerConnection.
396
+     *
397
+     * @param {MediaStream} stream - WebRTC MediaStream instance which is the parent of the track.
398
+     * @param {MediaStreamTrack} track - WebRTC MediaStreamTrack which has been removed from the PeerConnection.
399
+     * @returns {void}
399 400
      */
400 401
     _remoteTrackRemoved(stream: MediaStream, track: MediaStreamTrack): void;
401
-    private _getRemoteTrackById;
402 402
     /**
403
-     * Removes all JitsiRemoteTracks associated with given MUC nickname
404
-     * (resource part of the JID). Returns array of removed tracks.
403
+     * Removes all JitsiRemoteTracks associated with given MUC nickname (resource part of the JID).
405 404
      *
406 405
      * @param {string} owner - The resource part of the MUC JID.
407
-     * @returns {JitsiRemoteTrack[]}
406
+     * @returns {JitsiRemoteTrack[]} - The array of removed tracks.
408 407
      */
409 408
     removeRemoteTracks(owner: string): JitsiRemoteTrack[];
410 409
     /**
411
-     * Removes and disposes given <tt>JitsiRemoteTrack</tt> instance. Emits
412
-     * {@link RTCEvents.REMOTE_TRACK_REMOVED}.
413
-     * @param {JitsiRemoteTrack} toBeRemoved
414
-     */
415
-    _removeRemoteTrack(toBeRemoved: JitsiRemoteTrack): void;
416
-    /**
417
-     * Removes and disposes <tt>JitsiRemoteTrack</tt> identified by given stream and
418
-     * track ids.
410
+     * Removes and disposes given <tt>JitsiRemoteTrack</tt> instance. Emits {@link RTCEvents.REMOTE_TRACK_REMOVED}.
419 411
      *
420
-     * @param {string} streamId the media stream id as defined by the WebRTC
421
-     * @param {string} trackId the media track id as defined by the WebRTC
422
-     * @returns {JitsiRemoteTrack|undefined} the track which has been removed or
423
-     * <tt>undefined</tt> if no track matching given stream and track ids was
424
-     * found.
412
+     * @param {JitsiRemoteTrack} toBeRemoved - The remote track to be removed.
413
+     * @returns {void}
425 414
      */
426
-    _removeRemoteTrackById(streamId: string, trackId: string): JitsiRemoteTrack | undefined;
415
+    _removeRemoteTrack(toBeRemoved: JitsiRemoteTrack): void;
427 416
     /**
428 417
      * Returns a map with keys msid/mediaType and <tt>TrackSSRCInfo</tt> values.
429 418
      * @param {RTCSessionDescription} desc the local description.
@@ -472,8 +461,7 @@ export default class TraceablePeerConnection {
472 461
     /**
473 462
      * Checks if screensharing is in progress.
474 463
      *
475
-     * @returns {boolean}  Returns true if a desktop track has been added to the
476
-     * peerconnection, false otherwise.
464
+     * @returns {boolean}  Returns true if a desktop track has been added to the peerconnection, false otherwise.
477 465
      */
478 466
     _isSharingScreen(): boolean;
479 467
     /**

正在加载...
取消
保存