Ver código fonte

fix(TPC) Allow remote tracks to be created if no presence is found.

Currently, remote tracks are not created if presence for the endpoint is not received before source signaling. With ssrc-rewriting, the source information will be received on the bridge channel and presence on the prosody ws so there are chances that they can be out of sync. We do not want to skip remote track creation when that happens.
dev1
Jaya Allamsetty 2 anos atrás
pai
commit
f8e587f7b9

+ 15
- 10
JitsiConference.js Ver arquivo

@@ -1804,9 +1804,7 @@ JitsiConference.prototype.onMemberJoined = function(
1804 1804
     if (id === 'focus' || this.myUserId() === id) {
1805 1805
         return;
1806 1806
     }
1807
-
1808
-    const participant
1809
-        = new JitsiParticipant(jid, this, nick, isHidden, statsID, status, identity);
1807
+    const participant = new JitsiParticipant(jid, this, nick, isHidden, statsID, status, identity);
1810 1808
 
1811 1809
     participant.setConnectionJid(fullJid);
1812 1810
     participant.setRole(role);
@@ -1814,6 +1812,15 @@ JitsiConference.prototype.onMemberJoined = function(
1814 1812
     participant.setFeatures(features);
1815 1813
     participant.setIsReplacing(isReplaceParticipant);
1816 1814
 
1815
+    // Set remote tracks on the participant if source signaling was received before presence.
1816
+    const remoteTracks = this.isP2PActive()
1817
+        ? this.p2pJingleSession?.peerconnection.getRemoteTracks(id) ?? []
1818
+        : this.jvbJingleSession?.peerconnection.getRemoteTracks(id) ?? [];
1819
+
1820
+    for (const track of remoteTracks) {
1821
+        participant._tracks.push(track);
1822
+    }
1823
+
1817 1824
     this.participants[id] = participant;
1818 1825
     this.eventEmitter.emit(
1819 1826
         JitsiConferenceEvents.USER_JOINED,
@@ -2042,14 +2049,12 @@ JitsiConference.prototype.onRemoteTrackAdded = function(track) {
2042 2049
     const id = track.getParticipantId();
2043 2050
     const participant = this.getParticipantById(id);
2044 2051
 
2045
-    if (!participant) {
2046
-        logger.error(`No participant found for id: ${id}`);
2047
-
2048
-        return;
2049
-    }
2050
-
2051 2052
     // Add track to JitsiParticipant.
2052
-    participant._tracks.push(track);
2053
+    if (participant) {
2054
+        participant._tracks.push(track);
2055
+    } else {
2056
+        logger.info(`Source signaling received before presence for ${id}`);
2057
+    }
2053 2058
 
2054 2059
     if (this.transcriber) {
2055 2060
         this.transcriber.addTrack(track);

+ 1
- 1
modules/RTC/JitsiRemoteTrack.js Ver arquivo

@@ -89,7 +89,7 @@ export default class JitsiRemoteTrack extends JitsiTrack {
89 89
         this.addEventListener = this.on = this._addEventListener.bind(this);
90 90
         this.removeEventListener = this.off = this._removeEventListener.bind(this);
91 91
 
92
-        logger.debug(`New remote track added: ${this}`);
92
+        logger.debug(`New remote track created: ${this}`);
93 93
 
94 94
         // we want to mark whether the track has been ever muted
95 95
         // to detect ttfm events for startmuted conferences, as it can

+ 35
- 58
modules/RTC/TraceablePeerConnection.js Ver arquivo

@@ -7,10 +7,7 @@ import { MediaDirection } from '../../service/RTC/MediaDirection';
7 7
 import { MediaType } from '../../service/RTC/MediaType';
8 8
 import RTCEvents from '../../service/RTC/RTCEvents';
9 9
 import * as SignalingEvents from '../../service/RTC/SignalingEvents';
10
-import {
11
-    getSourceIndexFromSourceName,
12
-    getSourceNameForJitsiTrack
13
-} from '../../service/RTC/SignalingLayer';
10
+import { getSourceIndexFromSourceName } from '../../service/RTC/SignalingLayer';
14 11
 import { VideoType } from '../../service/RTC/VideoType';
15 12
 import { SS_DEFAULT_FRAME_RATE } from '../RTC/ScreenObtainer';
16 13
 import browser from '../browser';
@@ -850,9 +847,8 @@ TraceablePeerConnection.prototype.getSsrcByTrackId = function(id) {
850 847
 TraceablePeerConnection.prototype._remoteStreamAdded = function(stream) {
851 848
     const streamId = stream.id;
852 849
 
850
+    // Do not create remote tracks for 'mixed' JVB SSRCs (used by JVB for RTCP termination).
853 851
     if (!RTC.isUserStreamById(streamId)) {
854
-        logger.info(`${this} ignored remote 'stream added' event for non-user stream[id=${streamId}]`);
855
-
856 852
         return;
857 853
     }
858 854
 
@@ -895,64 +891,58 @@ TraceablePeerConnection.prototype._remoteTrackAdded = function(stream, track, tr
895 891
     const streamId = stream.id;
896 892
     const mediaType = track.kind;
897 893
 
894
+    // Do not create remote tracks for 'mixed' JVB SSRCs (used by JVB for RTCP termination).
898 895
     if (!this.isP2P && !RTC.isUserStreamById(streamId)) {
899
-        logger.info(`${this} ignored remote 'stream added' event for non-user stream[id=${streamId}]`);
900
-
901 896
         return;
902 897
     }
903
-    logger.info(`${this} adding remote track for stream[id=${streamId},type=${mediaType}]`);
898
+    logger.info(`${this} Received track event for remote stream[id=${streamId},type=${mediaType}]`);
904 899
 
905 900
     // look up an associated JID for a stream id
906 901
     if (!mediaType) {
907 902
         GlobalOnErrorHandler.callErrorHandler(
908
-            new Error(
909
-                `MediaType undefined for remote track, stream id: ${streamId}`
910
-            ));
903
+            new Error(`MediaType undefined for remote track, stream id: ${streamId}, track creation failed!`));
911 904
 
912
-        // Abort
913 905
         return;
914 906
     }
915 907
 
916 908
     const remoteSDP = this._usesUnifiedPlan
917 909
         ? new SDP(this.peerconnection.remoteDescription.sdp)
918 910
         : new SDP(this.remoteDescription.sdp);
919
-    let mediaLines;
911
+    let mediaLine;
920 912
 
921
-    // In unified plan mode, find the matching mline using 'mid' if its availble, otherwise use the
922
-    // 'msid' attribute of the stream.
913
+    // In unified plan mode, find the matching mline using 'mid' or the 'msid' attr of the stream.
923 914
     if (this._usesUnifiedPlan) {
924
-        if (transceiver && transceiver.mid) {
915
+        if (transceiver?.mid) {
925 916
             const mid = transceiver.mid;
926 917
 
927
-            mediaLines = remoteSDP.media.filter(mls => SDPUtil.findLine(mls, `a=mid:${mid}`));
918
+            mediaLine = remoteSDP.media.find(mls => SDPUtil.findLine(mls, `a=mid:${mid}`));
928 919
         } else {
929
-            mediaLines = remoteSDP.media.filter(mls => {
920
+            mediaLine = remoteSDP.media.find(mls => {
930 921
                 const msid = SDPUtil.findLine(mls, 'a=msid:');
931 922
 
932 923
                 return typeof msid === 'string' && streamId === msid.substring(7).split(' ')[0];
933 924
             });
934 925
         }
935 926
     } else {
936
-        mediaLines = remoteSDP.media.filter(mls => mls.startsWith(`m=${mediaType}`));
927
+        mediaLine = remoteSDP.media.find(mls => mls.startsWith(`m=${mediaType}`));
937 928
     }
938 929
 
939
-    if (!mediaLines.length) {
930
+    if (!mediaLine) {
940 931
         GlobalOnErrorHandler.callErrorHandler(
941
-            new Error(`No media lines found in remote SDP for remote stream[id=${streamId},type=${mediaType}]`));
932
+            new Error(`Matching media line not found in remote SDP for remote stream[id=${streamId},type=${mediaType}],`
933
+                + 'track creation failed!'));
942 934
 
943
-        // Abort
944 935
         return;
945 936
     }
946 937
 
947
-    let ssrcLines = SDPUtil.findLines(mediaLines[0], 'a=ssrc:');
938
+    let ssrcLines = SDPUtil.findLines(mediaLine, 'a=ssrc:');
948 939
 
949
-    ssrcLines
950
-        = ssrcLines.filter(line => line.indexOf(`msid:${streamId}`) !== -1);
940
+    ssrcLines = ssrcLines.filter(line => line.indexOf(`msid:${streamId}`) !== -1);
951 941
     if (!ssrcLines.length) {
952 942
         GlobalOnErrorHandler.callErrorHandler(
953
-            new Error(`No SSRC lines found in remote SDP for remote stream[msid=${streamId},type=${mediaType}]`));
943
+            new Error(`No SSRC lines found in remote SDP for remote stream[msid=${streamId},type=${mediaType}]`
944
+                + 'track creation failed!'));
954 945
 
955
-        // Abort
956 946
         return;
957 947
     }
958 948
 
@@ -964,47 +954,34 @@ TraceablePeerConnection.prototype._remoteTrackAdded = function(stream, track, tr
964 954
 
965 955
     if (isNaN(trackSsrc) || trackSsrc < 0) {
966 956
         GlobalOnErrorHandler.callErrorHandler(
967
-            new Error(
968
-                `Invalid SSRC for remote stream[ssrc=${trackSsrc},id=${streamId},type=${mediaType}]`));
957
+            new Error(`Invalid SSRC for remote stream[ssrc=${trackSsrc},id=${streamId},type=${mediaType}]`
958
+                + 'track creation failed!'));
969 959
 
970
-        // Abort
971 960
         return;
972 961
     } else if (!ownerEndpointId) {
973 962
         GlobalOnErrorHandler.callErrorHandler(
974
-            new Error(
975
-                `No SSRC owner known for remote stream[ssrc=${trackSsrc},id=${streamId},type=${mediaType}]`));
963
+            new Error(`No SSRC owner known for remote stream[ssrc=${trackSsrc},id=${streamId},type=${mediaType}]`
964
+            + 'track creation failed!'));
976 965
 
977
-        // Abort
978 966
         return;
979 967
     }
980 968
 
981
-    let sourceName = this.signalingLayer.getTrackSourceName(trackSsrc);
982
-
983
-    // If source name was not signaled, we'll generate one which allows testing signaling
984
-    // when mixing legacy(mobile) with new clients.
985
-    if (!sourceName) {
986
-        sourceName = getSourceNameForJitsiTrack(ownerEndpointId, mediaType, 0);
987
-    }
988
-
989
-    // eslint-disable-next-line no-undef
990
-    logger.info(`${this} creating remote track[endpoint=${ownerEndpointId},ssrc=${trackSsrc},`
991
-        + `type=${mediaType},sourceName=${sourceName}]`);
992
-
969
+    const sourceName = this.signalingLayer.getTrackSourceName(trackSsrc);
993 970
     const peerMediaInfo = this.signalingLayer.getPeerMediaInfo(ownerEndpointId, mediaType, sourceName);
994 971
 
995
-    if (!peerMediaInfo) {
996
-        GlobalOnErrorHandler.callErrorHandler(
997
-            new Error(`${this}: no peer media info available for ${ownerEndpointId}`));
972
+    // Assume default presence state for remote source. Presence can be received after source signaling. This shouldn't
973
+    // prevent the endpoint from creating a remote track for the source.
974
+    let muted = true;
975
+    let videoType = VideoType.CAMERA;
998 976
 
999
-        return;
977
+    if (peerMediaInfo) {
978
+        muted = peerMediaInfo.muted;
979
+        videoType = peerMediaInfo.videoType; // can be undefined
980
+    } else {
981
+        logger.info(`${this}: no source-info available for ${ownerEndpointId}:${sourceName}, assuming default state`);
1000 982
     }
1001 983
 
1002
-    const muted = peerMediaInfo.muted;
1003
-    const videoType = peerMediaInfo.videoType; // can be undefined
1004
-
1005
-    // eslint-disable-next-line no-undef
1006
-    this._createRemoteTrack(
1007
-        ownerEndpointId, stream, track, mediaType, videoType, trackSsrc, muted, sourceName);
984
+    this._createRemoteTrack(ownerEndpointId, stream, track, mediaType, videoType, trackSsrc, muted, sourceName);
1008 985
 };
1009 986
 
1010 987
 // FIXME cleanup params
@@ -1032,6 +1009,8 @@ TraceablePeerConnection.prototype._createRemoteTrack = function(
1032 1009
         ssrc,
1033 1010
         muted,
1034 1011
         sourceName) {
1012
+    logger.info(`${this} creating remote track[endpoint=${ownerEndpointId},ssrc=${ssrc},`
1013
+        + `type=${mediaType},sourceName=${sourceName}]`);
1035 1014
     let remoteTracksMap = this.remoteTracks.get(ownerEndpointId);
1036 1015
 
1037 1016
     if (!remoteTracksMap) {
@@ -1069,8 +1048,6 @@ TraceablePeerConnection.prototype._createRemoteTrack = function(
1069 1048
     this.eventEmitter.emit(RTCEvents.REMOTE_TRACK_ADDED, remoteTrack, this);
1070 1049
 };
1071 1050
 
1072
-/* eslint-enable max-params */
1073
-
1074 1051
 /**
1075 1052
  * Handles remote stream removal.
1076 1053
  * @param stream the WebRTC MediaStream object which is being removed from the

Carregando…
Cancelar
Salvar