@flashphoner/sfusdk-examples 2.0.324 → 2.0.330

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flashphoner/sfusdk-examples",
3
- "version": "2.0.324",
3
+ "version": "2.0.330",
4
4
  "description": "Official Flashphoner WebCallServer SFU SDK usage examples",
5
5
  "main": "dist/sfu.js",
6
6
  "types": "src/sfu.ts",
@@ -10,7 +10,8 @@ const createControls = function (config) {
10
10
  roomPin: document.getElementById("roomPin"),
11
11
  nickName: document.getElementById("nickName"),
12
12
  enter: document.getElementById("startButton"),
13
- transport: document.getElementById("transport")
13
+ transport: document.getElementById("transport"),
14
+ participantViewType: document.getElementById("participantViewType"),
14
15
  },
15
16
  addVideoTrack: {
16
17
  source: document.getElementById("addVideoTrackSource"),
@@ -173,7 +174,8 @@ const createControls = function (config) {
173
174
  roomName: controls.entrance.roomName.value,
174
175
  pin: controls.entrance.roomPin.value,
175
176
  nickname: controls.entrance.nickName.value,
176
- transport: controls.entrance.transport.value
177
+ transport: controls.entrance.transport.value,
178
+ participantViewType: controls.entrance.participantViewType.value,
177
179
  };
178
180
  if (config.room.failedProbesThreshold !== undefined) {
179
181
  roomConfig.failedProbesThreshold = config.room.failedProbesThreshold;
@@ -30,51 +30,56 @@
30
30
  <!-- Tracks console -->
31
31
  <ul class="nav nav-tabs" id="tracksTablist" role="tablist">
32
32
  <li class="nav-item" role="presentation">
33
- <button class="nav-link active" id="videoTracksTab" data-bs-toggle="tab" data-bs-target="#videoTracks" type="button" role="tab" aria-controls="videoTracks" aria-selected="true">VideoTracks</button>
33
+ <button class="nav-link active" id="videoTracksTab" data-bs-toggle="tab"
34
+ data-bs-target="#videoTracks" type="button" role="tab" aria-controls="videoTracks"
35
+ aria-selected="true">VideoTracks
36
+ </button>
34
37
  </li>
35
38
  <li class="nav-item" role="presentation">
36
- <button class="nav-link" id="audioTracksTab" data-bs-toggle="tab" data-bs-target="#audioTracks" type="button" role="tab" aria-controls="audioTracks" aria-selected="false">AudioTracks</button>
39
+ <button class="nav-link" id="audioTracksTab" data-bs-toggle="tab" data-bs-target="#audioTracks"
40
+ type="button" role="tab" aria-controls="audioTracks" aria-selected="false">AudioTracks
41
+ </button>
37
42
  </li>
38
43
  </ul>
39
44
  <div class="tab-content" id="tracksTabContent">
40
45
  <div class="tab-pane fade show active mt-2" id="videoTracks" role="tabpanel" aria-labelledby="raw-tab">
41
46
  <table class="table" id="videoTracksTable">
42
47
  <thead>
43
- <tr>
44
- <th></th>
45
- <th>Source</th>
46
- <th>Width</th>
47
- <th>Height</th>
48
- <th>Codec</th>
49
- <th>Action</th>
50
- </tr>
48
+ <tr>
49
+ <th></th>
50
+ <th>Source</th>
51
+ <th>Width</th>
52
+ <th>Height</th>
53
+ <th>Codec</th>
54
+ <th>Action</th>
55
+ </tr>
51
56
  </thead>
52
57
  <tfoot>
53
- <tr>
54
- <th></th>
55
- <th>
56
- <select class="form-select-sm" id="addVideoTrackSource">
57
- <option value="camera" selected>camera</option>
58
- <option value="screen">screen</option>
59
- </select>
60
- </th>
61
- <th>
62
- <input class="form-control-sm" id="addVideoTrackWidth" type="number" value="1280">
63
- </th>
64
- <th>
65
- <input class="form-control-sm" id="addVideoTrackHeight" type="number" value="720">
66
- </th>
67
- <th>
68
- <select class="form-select-sm" id="addVideoTrackCodec">
69
- <option value="H264" selected>H264</option>
70
- <option value="VP8">VP8</option>
71
- <option value="VP9">VP9</option>
72
- </select>
73
- </th>
74
- <th>
75
- <button class="btn btn-primary" id="addVideoTrack">Add</button>
76
- </th>
77
- </tr>
58
+ <tr>
59
+ <th></th>
60
+ <th>
61
+ <select class="form-select-sm" id="addVideoTrackSource">
62
+ <option value="camera" selected>camera</option>
63
+ <option value="screen">screen</option>
64
+ </select>
65
+ </th>
66
+ <th>
67
+ <input class="form-control-sm" id="addVideoTrackWidth" type="number" value="1280">
68
+ </th>
69
+ <th>
70
+ <input class="form-control-sm" id="addVideoTrackHeight" type="number" value="720">
71
+ </th>
72
+ <th>
73
+ <select class="form-select-sm" id="addVideoTrackCodec">
74
+ <option value="H264" selected>H264</option>
75
+ <option value="VP8">VP8</option>
76
+ <option value="VP9">VP9</option>
77
+ </select>
78
+ </th>
79
+ <th>
80
+ <button class="btn btn-primary" id="addVideoTrack">Add</button>
81
+ </th>
82
+ </tr>
78
83
  </tfoot>
79
84
  <tbody id="videoTracksTableBody"></tbody>
80
85
  </table>
@@ -83,50 +88,51 @@
83
88
  <div class="col">
84
89
  <table class="table" id="videoTrackEncodingsTable">
85
90
  <thead>
86
- <tr>
87
- <th>RID</th>
88
- <th>Active</th>
89
- <th>MaxBitrate</th>
90
- <th>ResolutionScale</th>
91
- <th>Scalability Mode</th>
92
- <th>Action</th>
93
- </tr>
91
+ <tr>
92
+ <th>RID</th>
93
+ <th>Active</th>
94
+ <th>MaxBitrate</th>
95
+ <th>ResolutionScale</th>
96
+ <th>Scalability Mode</th>
97
+ <th>Action</th>
98
+ </tr>
94
99
  </thead>
95
100
  <tfoot>
96
- <tr>
97
- <th>
98
- <select class="form-select-sm" id="addVideoTrackEncodingRid">
99
- <option value="h" selected>h</option>
100
- <option value="m">m</option>
101
- <option value="l">l</option>
102
- </select>
103
- </th>
104
- <th>
105
- <select class="form-select-sm" id="addVideoTrackEncodingActive">
106
- <option value="true" selected>true</option>
107
- <option value="false">false</option>
108
- </select>
109
- </th>
110
- <th>
111
- <input class="form-control-sm" id="addVideoTrackEncodingMaxBitrate" type="number" value="900000">
112
- </th>
113
- <th>
114
- <select class="form-select-sm" id="addVideoTrackEncodingResolutionScale">
115
- <option value="1" selected>1</option>
116
- <option value="2">2</option>
117
- <option value="4">4</option>
118
- <option value="6">6</option>
119
- </select>
120
- </th>
121
- <th>
122
- <select class="form-select-sm" id="addVideoTrackScalabilityMode">
123
- <option selected value="">NONE</option>
124
- </select>
125
- </th>
126
- <th>
127
- <button class="btn btn-primary" id="addVideoTrackEncoding">Add</button>
128
- </th>
129
- </tr>
101
+ <tr>
102
+ <th>
103
+ <select class="form-select-sm" id="addVideoTrackEncodingRid">
104
+ <option value="h" selected>h</option>
105
+ <option value="m">m</option>
106
+ <option value="l">l</option>
107
+ </select>
108
+ </th>
109
+ <th>
110
+ <select class="form-select-sm" id="addVideoTrackEncodingActive">
111
+ <option value="true" selected>true</option>
112
+ <option value="false">false</option>
113
+ </select>
114
+ </th>
115
+ <th>
116
+ <input class="form-control-sm" id="addVideoTrackEncodingMaxBitrate"
117
+ type="number" value="900000">
118
+ </th>
119
+ <th>
120
+ <select class="form-select-sm" id="addVideoTrackEncodingResolutionScale">
121
+ <option value="1" selected>1</option>
122
+ <option value="2">2</option>
123
+ <option value="4">4</option>
124
+ <option value="6">6</option>
125
+ </select>
126
+ </th>
127
+ <th>
128
+ <select class="form-select-sm" id="addVideoTrackScalabilityMode">
129
+ <option selected value="">NONE</option>
130
+ </select>
131
+ </th>
132
+ <th>
133
+ <button class="btn btn-primary" id="addVideoTrackEncoding">Add</button>
134
+ </th>
135
+ </tr>
130
136
  </tfoot>
131
137
  <tbody id="videoTrackEncodingsTableBody"></tbody>
132
138
  </table>
@@ -137,29 +143,29 @@
137
143
  <table class="table" id="audioTracksTable">
138
144
  <caption class="caption-top">Audio tracks</caption>
139
145
  <thead>
140
- <tr>
141
- <th>Source</th>
142
- <th>Channels</th>
143
- <th>Action</th>
144
- </tr>
146
+ <tr>
147
+ <th>Source</th>
148
+ <th>Channels</th>
149
+ <th>Action</th>
150
+ </tr>
145
151
  </thead>
146
152
  <tfoot>
147
- <tr>
148
- <th>
149
- <select class="form-select-sm" id="addAudioTrackSource">
150
- <option value="mic" selected>mic</option>
151
- </select>
152
- </th>
153
- <th>
154
- <select class="form-select-sm" id="addAudioTrackChannels">
155
- <option value="1" selected>1</option>
156
- <option value="2">2</option>
157
- </select>
158
- </th>
159
- <th>
160
- <button id="addAudioTrack" class="btn btn-primary form-control-sm">Add</button>
161
- </th>
162
- </tr>
153
+ <tr>
154
+ <th>
155
+ <select class="form-select-sm" id="addAudioTrackSource">
156
+ <option value="mic" selected>mic</option>
157
+ </select>
158
+ </th>
159
+ <th>
160
+ <select class="form-select-sm" id="addAudioTrackChannels">
161
+ <option value="1" selected>1</option>
162
+ <option value="2">2</option>
163
+ </select>
164
+ </th>
165
+ <th>
166
+ <button id="addAudioTrack" class="btn btn-primary form-control-sm">Add</button>
167
+ </th>
168
+ </tr>
163
169
  </tfoot>
164
170
  <tbody></tbody>
165
171
  </table>
@@ -221,9 +227,17 @@
221
227
  <!-- Other options are populated dynamically by init() in main.js -->
222
228
  </select>
223
229
  </div>
230
+
231
+ <div class="row">
232
+ <label for="participantViewType">Participant View</label>
233
+ <select class="form-select" id="participantViewType">
234
+ <!-- Other options are populated dynamically by init() in main.js -->
235
+ </select>
236
+ </div>
224
237
  </div>
225
238
  <div class="modal-footer">
226
- <button type="button" class="btn btn-secondary" data-bs-dismiss="modal" onclick="cancel()">Close</button>
239
+ <button type="button" class="btn btn-secondary" data-bs-dismiss="modal" onclick="cancel()">Close
240
+ </button>
227
241
  <button class="btn btn-primary" id="startButton" onclick="connect()">Enter</button>
228
242
  </div>
229
243
  </div>
@@ -87,6 +87,14 @@ const init = function () {
87
87
  option.textContent = value;
88
88
  transportSelect.appendChild(option);
89
89
  });
90
+ // insert participant view types in entrance modal
91
+ const participantViewTypeSelect = document.getElementById("participantViewType");
92
+ Object.values(PARTICIPANT_VIEW_TYPE).forEach(value => {
93
+ const option = document.createElement('option');
94
+ option.value = value;
95
+ option.textContent = value;
96
+ participantViewTypeSelect.appendChild(option);
97
+ })
90
98
  //open entrance modal
91
99
  $('#entranceModal').modal('show');
92
100
  }
@@ -154,7 +162,7 @@ async function connect() {
154
162
  abrTryForUpperQuality: ABR_TRY_UPPER_QUALITY,
155
163
  interval: ABR_QUALITY_CHECK_PERIOD
156
164
  };
157
- initDefaultRemoteDisplay(room, remoteDisplay, displayOptions, abrOptions);
165
+ initDefaultRemoteDisplay(room, remoteDisplay, displayOptions, abrOptions, roomConfig.participantViewType);
158
166
 
159
167
  //get configured local video streams
160
168
  let streams = cControls.getVideoStreams();
@@ -316,6 +324,10 @@ const subscribeTrackToEndedEvent = function (room, track, pc) {
316
324
  pc.removeTrack(sender);
317
325
  //track found, set renegotiation flag
318
326
  negotiate = true;
327
+ if (sender.track) {
328
+ sender.track.stop();
329
+ sender.track.active = false;
330
+ }
319
331
  break;
320
332
  }
321
333
  }
@@ -324,6 +336,7 @@ const subscribeTrackToEndedEvent = function (room, track, pc) {
324
336
  if (negotiate) {
325
337
  //kickoff renegotiation
326
338
  await room.updateState();
339
+ pc.restartIce();
327
340
  }
328
341
  } catch (e) {
329
342
  onOperationFailed("Failed to update room state", e);
@@ -8,6 +8,11 @@ const QUALITY_COLORS = {
8
8
  SELECTED: "blue"
9
9
  };
10
10
 
11
+ const PARTICIPANT_VIEW_TYPE = {
12
+ ONE_TO_ONE: "One-to-one",
13
+ ONE_TO_MANY: "One-to-many",
14
+ }
15
+
11
16
  const initLocalDisplay = function (localDisplayElement) {
12
17
  const localDisplayDiv = localDisplayElement;
13
18
  const localDisplays = {};
@@ -678,12 +683,12 @@ const createVideoPlayer = function (participantDiv) {
678
683
  const repickQuality = function (qualityName) {
679
684
  for (const [quality, state] of qualityButtons.entries()) {
680
685
  state.layerButtons.temporalLayerButtons.forEach((lState, __) => {
681
- if(lState.btn.style.color === QUALITY_COLORS.SELECTED) {
686
+ if (lState.btn.style.color === QUALITY_COLORS.SELECTED) {
682
687
  lState.btn.style.color = QUALITY_COLORS.AVAILABLE;
683
688
  }
684
689
  });
685
690
  state.layerButtons.spatialLayerButtons.forEach((lState, __) => {
686
- if(lState.btn.style.color === QUALITY_COLORS.SELECTED) {
691
+ if (lState.btn.style.color === QUALITY_COLORS.SELECTED) {
687
692
  lState.btn.style.color = QUALITY_COLORS.AVAILABLE;
688
693
  }
689
694
  });
@@ -873,7 +878,7 @@ const createVideoPlayer = function (participantDiv) {
873
878
  const isSelectedQuality = qualityButton.style.color === QUALITY_COLORS.SELECTED;
874
879
 
875
880
  if (quality.available) {
876
- if(!isSelectedQuality) {
881
+ if (!isSelectedQuality) {
877
882
  qualityButton.style.color = QUALITY_COLORS.AVAILABLE;
878
883
  }
879
884
  } else {
@@ -1359,17 +1364,17 @@ const createOneToOneParticipantModel = function (userId, nickname, participantVi
1359
1364
  const quality = track.quality.find((q) => q.quality === remoteQualityInfo.quality);
1360
1365
  if (quality) {
1361
1366
  quality.available = remoteQualityInfo.available;
1362
- for(const info of remoteQualityInfo.layersInfo.temporalLayers) {
1367
+ for (const info of remoteQualityInfo.layersInfo.temporalLayers) {
1363
1368
  const localTidInfo = quality.layersInfo.temporalLayers.find((t) => t.tid === info.tid);
1364
- if(localTidInfo) {
1369
+ if (localTidInfo) {
1365
1370
  localTidInfo.available = info.available;
1366
1371
  } else {
1367
1372
  quality.layersInfo.temporalLayers.push(info);
1368
1373
  }
1369
1374
  }
1370
- for(const info of remoteQualityInfo.layersInfo.spatialLayers) {
1375
+ for (const info of remoteQualityInfo.layersInfo.spatialLayers) {
1371
1376
  const localSidInfo = quality.layersInfo.spatialLayers.find((s) => s.sid === info.sid);
1372
- if(localSidInfo) {
1377
+ if (localSidInfo) {
1373
1378
  localSidInfo.available = info.available;
1374
1379
  localSidInfo.resolution = info.resolution;
1375
1380
  } else {
@@ -1380,12 +1385,16 @@ const createOneToOneParticipantModel = function (userId, nickname, participantVi
1380
1385
  track.quality.push(remoteQualityInfo);
1381
1386
  }
1382
1387
  }
1383
- return;
1388
+ continue;
1384
1389
  }
1385
1390
  let abrManager = this.abrManagers.get(track.id);
1386
1391
  if (abrManager && track.quality.length === 0 && remoteTrackQuality.quality.length > 0) {
1387
1392
  const self = this;
1388
- participantView.addQuality(track, {quality:"Auto",available:true,layersInfo:{spatialLayers:[],temporalLayers:[]}}, async () => {
1393
+ participantView.addQuality(track, {
1394
+ quality: "Auto",
1395
+ available: true,
1396
+ layersInfo: {spatialLayers: [], temporalLayers: []}
1397
+ }, async () => {
1389
1398
  const manager = self.abrManagers.get(track.id);
1390
1399
  if (!manager) {
1391
1400
  return;
@@ -1404,17 +1413,17 @@ const createOneToOneParticipantModel = function (userId, nickname, participantVi
1404
1413
  const localQuality = track.quality.find((q) => q.quality === remoteQualityInfo.quality);
1405
1414
  if (localQuality) {
1406
1415
  localQuality.available = remoteQualityInfo.available;
1407
- for(const info of remoteQualityInfo.layersInfo.temporalLayers) {
1416
+ for (const info of remoteQualityInfo.layersInfo.temporalLayers) {
1408
1417
  const localTidInfo = localQuality.layersInfo.temporalLayers.find((t) => t.tid === info.tid);
1409
- if(localTidInfo) {
1418
+ if (localTidInfo) {
1410
1419
  localTidInfo.available = info.available;
1411
1420
  } else {
1412
1421
  localQuality.layersInfo.temporalLayers.push(info);
1413
1422
  }
1414
1423
  }
1415
- for(const info of remoteQualityInfo.layersInfo.spatialLayers) {
1424
+ for (const info of remoteQualityInfo.layersInfo.spatialLayers) {
1416
1425
  const localSidInfo = localQuality.layersInfo.spatialLayers.find((s) => s.sid === info.sid);
1417
- if(localSidInfo) {
1426
+ if (localSidInfo) {
1418
1427
  localSidInfo.available = info.available;
1419
1428
  localSidInfo.resolution = info.resolution;
1420
1429
  } else {
@@ -1447,7 +1456,6 @@ const createOneToOneParticipantModel = function (userId, nickname, participantVi
1447
1456
  }
1448
1457
  }
1449
1458
  }
1450
-
1451
1459
  },
1452
1460
  requestVideoTrack: async function (track, remoteTrack) {
1453
1461
  return new Promise((resolve, reject) => {
@@ -1474,7 +1482,11 @@ const createOneToOneParticipantModel = function (userId, nickname, participantVi
1474
1482
  abrManager.setTrack(remoteTrack);
1475
1483
  abrManager.stop();
1476
1484
  if (track.quality.length > 0) {
1477
- participantView.addQuality(track, {quality:"Auto",available:true, layersInfo:{spatialLayers:[],temporalLayers:[]}}, async () => {
1485
+ participantView.addQuality(track, {
1486
+ quality: "Auto",
1487
+ available: true,
1488
+ layersInfo: {spatialLayers: [], temporalLayers: []}
1489
+ }, async () => {
1478
1490
  const manager = self.abrManagers.get(track.id);
1479
1491
  if (!manager) {
1480
1492
  return;
@@ -1760,17 +1772,17 @@ const createOneToManyParticipantModel = function (userId, nickname, participantV
1760
1772
  const quality = track.quality.find((q) => q.quality === remoteQualityInfo.quality);
1761
1773
  if (quality) {
1762
1774
  quality.available = remoteQualityInfo.available;
1763
- for(const info of remoteQualityInfo.layersInfo.temporalLayers) {
1775
+ for (const info of remoteQualityInfo.layersInfo.temporalLayers) {
1764
1776
  const localTidInfo = quality.layersInfo.temporalLayers.find((t) => t.tid === info.tid);
1765
- if(localTidInfo) {
1777
+ if (localTidInfo) {
1766
1778
  localTidInfo.available = info.available;
1767
1779
  } else {
1768
1780
  quality.layersInfo.temporalLayers.push(info);
1769
1781
  }
1770
1782
  }
1771
- for(const info of remoteQualityInfo.layersInfo.spatialLayers) {
1783
+ for (const info of remoteQualityInfo.layersInfo.spatialLayers) {
1772
1784
  const localSidInfo = quality.layersInfo.spatialLayers.find((s) => s.sid === info.sid);
1773
- if(localSidInfo) {
1785
+ if (localSidInfo) {
1774
1786
  localSidInfo.available = info.available;
1775
1787
  localSidInfo.resolution = info.resolution;
1776
1788
  } else {
@@ -1785,7 +1797,11 @@ const createOneToManyParticipantModel = function (userId, nickname, participantV
1785
1797
  }
1786
1798
  if (this.abr && track.quality.length === 0 && remoteTrackQuality.quality.length > 0) {
1787
1799
  const self = this;
1788
- participantView.addQuality(track, {quality:"Auto",available:true, layersInfo:{spatialLayers:[],temporalLayers:[]}}, async () => {
1800
+ participantView.addQuality(track, {
1801
+ quality: "Auto",
1802
+ available: true,
1803
+ layersInfo: {spatialLayers: [], temporalLayers: []}
1804
+ }, async () => {
1789
1805
  if (!self.abr) {
1790
1806
  return;
1791
1807
  }
@@ -1803,17 +1819,17 @@ const createOneToManyParticipantModel = function (userId, nickname, participantV
1803
1819
  const localQuality = track.quality.find((q) => q.quality === remoteQualityInfo.quality);
1804
1820
  if (localQuality) {
1805
1821
  localQuality.available = remoteQualityInfo.available;
1806
- for(const info of remoteQualityInfo.layersInfo.temporalLayers) {
1822
+ for (const info of remoteQualityInfo.layersInfo.temporalLayers) {
1807
1823
  const localTidInfo = localQuality.layersInfo.temporalLayers.find((t) => t.tid === info.tid);
1808
- if(localTidInfo) {
1824
+ if (localTidInfo) {
1809
1825
  localTidInfo.available = info.available;
1810
1826
  } else {
1811
1827
  localQuality.layersInfo.temporalLayers.push(info);
1812
1828
  }
1813
1829
  }
1814
- for(const info of remoteQualityInfo.layersInfo.spatialLayers) {
1830
+ for (const info of remoteQualityInfo.layersInfo.spatialLayers) {
1815
1831
  const localSidInfo = localQuality.layersInfo.spatialLayers.find((s) => s.sid === info.sid);
1816
- if(localSidInfo) {
1832
+ if (localSidInfo) {
1817
1833
  localSidInfo.available = info.available;
1818
1834
  localSidInfo.resolution = info.resolution;
1819
1835
  } else {
@@ -1867,7 +1883,11 @@ const createOneToManyParticipantModel = function (userId, nickname, participantV
1867
1883
  self.abr.setTrack(remoteTrack);
1868
1884
 
1869
1885
  if (track.quality.length > 0) {
1870
- participantView.addQuality(track, {quality:"Auto",available:true,layersInfo:{spatialLayers:[],temporalLayers:[]}}, async () => {
1886
+ participantView.addQuality(track, {
1887
+ quality: "Auto",
1888
+ available: true,
1889
+ layersInfo: {spatialLayers: [], temporalLayers: []}
1890
+ }, async () => {
1871
1891
  if (!self.abr) {
1872
1892
  return;
1873
1893
  }
@@ -1975,8 +1995,15 @@ const remoteTrackProvider = function (room) {
1975
1995
  }
1976
1996
  }
1977
1997
  }
1978
- const initDefaultRemoteDisplay = function (room, div, displayOptions, abrOptions) {
1979
- const participantFactory = createParticipantFactory(remoteTrackProvider(room), createOneToManyParticipantView, createOneToManyParticipantModel);
1998
+ const initDefaultRemoteDisplay = function (room, div, displayOptions, abrOptions, participantViewType) {
1999
+ let participantFactory;
2000
+ if (participantViewType === PARTICIPANT_VIEW_TYPE.ONE_TO_ONE) {
2001
+ participantFactory = createParticipantFactory(remoteTrackProvider(room), createOneToOneParticipantView, createOneToOneParticipantModel);
2002
+ } else if (participantViewType === PARTICIPANT_VIEW_TYPE.ONE_TO_MANY) {
2003
+ participantFactory = createParticipantFactory(remoteTrackProvider(room), createOneToManyParticipantView, createOneToManyParticipantModel);
2004
+ } else {
2005
+ participantFactory = createParticipantFactory(remoteTrackProvider(room), createOneToManyParticipantView, createOneToManyParticipantModel);
2006
+ }
1980
2007
  return initRemoteDisplay(room, div, displayOptions, abrOptions, createDefaultMeetingController, createDefaultMeetingModel, createDefaultMeetingView, participantFactory)
1981
2008
  }
1982
2009
  /*
@@ -222,7 +222,7 @@ const playStreams = async function(state) {
222
222
  try {
223
223
  remoteDisplay = initDefaultRemoteDisplay(state.room, document.getElementById("remoteVideo"), {quality: true});
224
224
  // Start WebRTC negotiation
225
- await state.room.join(state.pc, null, null, 1);
225
+ await state.room.join(state.pc, null, null, 10);
226
226
  } catch(e) {
227
227
  if (e.type === constants.SFU_ROOM_EVENT.OPERATION_FAILED) {
228
228
  onOperationFailed(state, e);