@flashphoner/sfusdk-examples 2.0.244 → 2.0.249

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.
@@ -1,502 +0,0 @@
1
- const initLocalDisplay = function(localDisplayElement){
2
- const localDisplayDiv = localDisplayElement;
3
- const localDisplays = {};
4
-
5
- const removeLocalDisplay = function(id) {
6
- delete localDisplays[id];
7
- $('#' + id).remove();
8
- reassembleLocalLayout();
9
- }
10
-
11
- const getAudioContainer = function() {
12
- for (const [key, value] of Object.entries(localDisplays)) {
13
- let video = value.getElementsByTagName("video");
14
- if (video && video[0]) {
15
- let audioStateButton = value.getElementsByTagName("button");
16
- let audioTracks = video[0].srcObject.getAudioTracks();
17
- if (!audioTracks || audioTracks.length === 0) {
18
- return {
19
- id: value.id,
20
- video: video[0],
21
- audioStateDisplay: audioStateButton[0]
22
- }
23
- }
24
- }
25
- }
26
- };
27
-
28
- const add = function(id, name, stream) {
29
- if (stream.getAudioTracks().length > 0) {
30
- let videoElement = getAudioContainer();
31
- if (videoElement) {
32
- let track = stream.getAudioTracks()[0];
33
- videoElement.video.srcObject.addTrack(track);
34
- videoElement.audioStateDisplay.innerHTML = "Audio state: " + stream.getAudioTracks()[0].enabled;
35
- track.addEventListener("ended", function() {
36
- videoElement.video.srcObject.removeTrack(track);
37
- videoElement.audioStateDisplay.innerHTML = "Audio state: " + false;
38
- //check video element has no tracks left
39
- for (const [key, vTrack] of Object.entries(videoElement.video.srcObject.getTracks())) {
40
- if (vTrack.readyState !== "ended") {
41
- return;
42
- }
43
- }
44
- removeLocalDisplay(videoElement.id);
45
- });
46
- return;
47
- }
48
- }
49
-
50
- const coreDisplay = document.createElement('div');
51
- coreDisplay.setAttribute("style","width:200px; height:auto; border: solid; border-width: 1px");
52
- coreDisplay.id = stream.id;
53
- const streamNameDisplay = document.createElement("div");
54
- streamNameDisplay.innerHTML = "Name: " + name;
55
- streamNameDisplay.setAttribute("style","width:auto; height:30px");
56
- coreDisplay.appendChild(streamNameDisplay);
57
-
58
- const audioStateDisplay = document.createElement("button");
59
- audioStateDisplay.setAttribute("style","width:auto; height:30px");
60
- audioStateDisplay.innerHTML = "Audio state: " + (stream.getAudioTracks().length > 0 ? stream.getAudioTracks()[0].enabled : false);
61
- audioStateDisplay.addEventListener('click', function(){
62
- if (stream.getAudioTracks().length > 0) {
63
- stream.getAudioTracks()[0].enabled = !(stream.getAudioTracks()[0].enabled);
64
- audioStateDisplay.innerHTML = "Audio state: " + stream.getAudioTracks()[0].enabled;
65
- }
66
- });
67
- coreDisplay.appendChild(audioStateDisplay);
68
-
69
- const streamDisplay = document.createElement('div');
70
- streamDisplay.id = id;
71
- streamDisplay.setAttribute("style","width:auto; height:auto");
72
- coreDisplay.appendChild(streamDisplay);
73
- const video = document.createElement("video");
74
- streamDisplay.appendChild(video);
75
- video.srcObject = stream;
76
- video.muted = true;
77
- video.onloadedmetadata = function (e) {
78
- video.play();
79
- };
80
- stream.getTracks().forEach(function(track){
81
- track.addEventListener("ended", function() {
82
- video.srcObject.removeTrack(track);
83
- //check video element has no tracks left
84
- for (const [key, vTrack] of Object.entries(video.srcObject.getTracks())) {
85
- if (vTrack.readyState !== "ended") {
86
- return;
87
- }
88
- }
89
- removeLocalDisplay(id);
90
- });
91
- });
92
- video.addEventListener('resize', function (event) {
93
- streamNameDisplay.innerHTML = "Name: " + name + " " + video.videoWidth + "x" + video.videoHeight;
94
- resizeVideo(event.target);
95
- });
96
- localDisplays[id] = coreDisplay;
97
- reassembleLocalLayout();
98
- return coreDisplay;
99
- }
100
-
101
- const reassembleLocalLayout = function() {
102
- let gridWidth = gridSize(Object.keys(localDisplays).length).x;
103
- let container = document.createElement('div');
104
- let row;
105
- let rowI = 1;
106
- let colI = 0;
107
- for (const [key, value] of Object.entries(localDisplays)) {
108
- if (row) {
109
- if (colI >= gridWidth) {
110
- row = createRow(container);
111
- rowI++;
112
- colI = 0;
113
- }
114
- } else {
115
- row = createRow(container);
116
- }
117
- $("#" + key).detach();
118
- let col = createCol(row);
119
- col.appendChild(value);
120
- colI++;
121
- }
122
- $(localDisplayDiv).empty();
123
- localDisplayDiv.appendChild(container);
124
- }
125
-
126
- return {
127
- add: add
128
- }
129
- }
130
-
131
- const initRemoteDisplay = function(room, mainDiv, peerConnection) {
132
- const constants = SFU.constants;
133
- const remoteParticipants = {};
134
- room.on(constants.SFU_ROOM_EVENT.ADD_TRACKS, function(e) {
135
- let participant = remoteParticipants[e.info.nickName];
136
- if (!participant) {
137
- participant = {};
138
- participant.nickName = e.info.nickName;
139
- participant.tracks = [];
140
- participant.displays = [];
141
- remoteParticipants[participant.nickName] = participant;
142
- }
143
- participant.tracks.push.apply(participant.tracks, e.info.info);
144
- for (const pTrack of e.info.info) {
145
- let createDisplay = true;
146
- for (let i = 0; i < participant.displays.length; i++) {
147
- let display = participant.displays[i];
148
- if (pTrack.type === "VIDEO") {
149
- if (display.hasVideo()) {
150
- continue;
151
- }
152
- display.videoMid = pTrack.mid;
153
- display.setTrackInfo(pTrack);
154
- createDisplay = false;
155
- break;
156
- } else if (pTrack.type === "AUDIO") {
157
- if (display.hasAudio()) {
158
- continue;
159
- }
160
- display.audioMid = pTrack.mid;
161
- createDisplay = false;
162
- break;
163
- }
164
- }
165
- if (!createDisplay) {
166
- continue;
167
- }
168
- let display = createRemoteDisplay(participant.nickName, participant.nickName, mainDiv);
169
- participant.displays.push(display);
170
- if (pTrack.type === "VIDEO") {
171
- display.videoMid = pTrack.mid;
172
- display.setTrackInfo(pTrack);
173
- } else if (pTrack.type === "AUDIO") {
174
- display.audioMid = pTrack.mid;
175
- }
176
- }
177
- }).on(constants.SFU_ROOM_EVENT.REMOVE_TRACKS, function(e) {
178
- const participant = remoteParticipants[e.info.nickName];
179
- if (!participant) {
180
- return;
181
- }
182
- for (const rTrack of e.info.info) {
183
- for (let i = 0; i < participant.tracks.length; i++) {
184
- if (rTrack.mid === participant.tracks[i].mid) {
185
- participant.tracks.splice(i, 1);
186
- break;
187
- }
188
- }
189
- for (let i = 0; i < participant.displays.length; i++) {
190
- let found = false;
191
- const display = participant.displays[i];
192
- if (display.audioMid === rTrack.mid) {
193
- display.setAudio(null);
194
- found = true;
195
- } else if (display.videoMid === rTrack.mid) {
196
- display.setVideo(null);
197
- found = true;
198
- }
199
- if (found) {
200
- if (!display.hasAudio() && !display.hasVideo()) {
201
- display.dispose();
202
- participant.displays.splice(i, 1);
203
- }
204
- break;
205
- }
206
- }
207
- }
208
- }).on(constants.SFU_ROOM_EVENT.LEFT, function(e) {
209
- let participant = remoteParticipants[e.name];
210
- if (!participant) {
211
- return;
212
- }
213
- participant.displays.forEach(function(display){
214
- display.dispose();
215
- })
216
- delete remoteParticipants[e.name];
217
- }).on(constants.SFU_ROOM_EVENT.TRACK_QUALITY_STATE, function(e){
218
- console.log("Received track quality state");
219
- const participant = remoteParticipants[e.info.nickName];
220
- if (!participant) {
221
- return;
222
- }
223
-
224
- for (const rTrack of e.info.tracks) {
225
- const mid = rTrack.mid;
226
- for (let i = 0; i < participant.displays.length; i++) {
227
- const display = participant.displays[i];
228
- if (display.videoMid === mid) {
229
- display.updateQualityInfo(rTrack.quality);
230
- break;
231
- }
232
- }
233
- }
234
- });
235
-
236
- const createRemoteDisplay = function(id, name, mainDiv) {
237
- const cell = document.createElement("div");
238
- cell.setAttribute("class", "grid-item");
239
- cell.id = id;
240
- mainDiv.appendChild(cell);
241
- const streamNameDisplay = document.createElement("div");
242
- streamNameDisplay.innerHTML = "Name: " + name;
243
- streamNameDisplay.setAttribute("style","width:auto; height:20px");
244
- cell.appendChild(streamNameDisplay);
245
- const qualityDisplay = document.createElement("div");
246
- qualityDisplay.setAttribute("style","width:auto; height:20px");
247
- cell.appendChild(qualityDisplay);
248
- const tidDisplay = document.createElement("div");
249
- tidDisplay.setAttribute("style","width:auto; height:20px");
250
- cell.appendChild(tidDisplay);
251
-
252
- let qualityDivs = [];
253
- let tidDivs = [];
254
-
255
- const rootDisplay = document.createElement("div");
256
- rootDisplay.setAttribute("style","width:auto; height:auto");
257
- cell.appendChild(rootDisplay);
258
- const streamDisplay = document.createElement("div");
259
- streamDisplay.setAttribute("style","width:auto; height:auto");
260
- rootDisplay.appendChild(streamDisplay);
261
-
262
- let audio = null;
263
- let video = null;
264
- return {
265
- dispose: function() {
266
- cell.remove();
267
- },
268
- hide: function(value) {
269
- if (value) {
270
- cell.style.display = "none";
271
- } else {
272
- cell.style.display = "block";
273
- }
274
- },
275
- setAudio: function(stream) {
276
- if (audio) {
277
- audio.remove();
278
- }
279
- if (!stream) {
280
- audio = null;
281
- this.audioMid = undefined;
282
- return;
283
- }
284
- audio = document.createElement("audio");
285
- audio.controls = "controls";
286
- cell.appendChild(audio);
287
- audio.srcObject = stream;
288
- audio.play();
289
- },
290
- hasAudio: function() {
291
- return audio !== null || this.audioMid !== undefined;
292
- },
293
- setVideo: function(stream) {
294
- if (video) {
295
- video.remove();
296
- }
297
-
298
- if (stream == null) {
299
- video = null;
300
- this.videoMid = undefined;
301
- qualityDivs.forEach(function(div) {
302
- div.remove();
303
- });
304
- qualityDivs = [];
305
- tidDivs.forEach(function(div) {
306
- div.remove();
307
- });
308
- tidDivs = [];
309
- return;
310
- }
311
- video = document.createElement("video");
312
- streamDisplay.appendChild(video);
313
- video.srcObject = stream;
314
- video.onloadedmetadata = function (e) {
315
- video.play();
316
- };
317
- video.addEventListener("resize", function (event) {
318
- streamNameDisplay.innerHTML = "Name: " + name + " " + video.videoWidth + "x" + video.videoHeight;
319
- resizeVideo(event.target);
320
- });
321
- },
322
- setTrackInfo: function(trackInfo) {
323
- if (trackInfo && trackInfo.quality) {
324
- for (let i = 0; i < trackInfo.quality.length; i++) {
325
- const qualityDiv = document.createElement("button");
326
- qualityDivs.push(qualityDiv);
327
- qualityDiv.innerText = trackInfo.quality[i];
328
- qualityDiv.setAttribute("style", "display:inline-block; border: solid; border-width: 1px");
329
- qualityDiv.style.color = "red";
330
- qualityDiv.addEventListener('click', async function(){
331
- console.log("Clicked on quality " + trackInfo.quality[i] + " trackId " + trackInfo.id);
332
- if (qualityDiv.style.color === "red") {
333
- return;
334
- }
335
- for (let c = 0; c < qualityDivs.length; c++) {
336
- if (qualityDivs[c].style.color !== "red") {
337
- qualityDivs[c].style.color = "gray";
338
- }
339
- }
340
- qualityDiv.style.color = "blue";
341
- await room.changeQuality(trackInfo.id, trackInfo.quality[i]);
342
- });
343
- qualityDisplay.appendChild(qualityDiv);
344
- }
345
- for (let i = 0; i < 3; i++) {
346
- const tidDiv = document.createElement("button");
347
- tidDivs.push(tidDiv);
348
- tidDiv.innerText = "TID"+i;
349
- tidDiv.setAttribute("style", "display:inline-block; border: solid; border-width: 1px");
350
- tidDiv.style.color = "gray";
351
- tidDiv.addEventListener('click', async function(){
352
- console.log("Clicked on TID " + i + " trackId " + trackInfo.id);
353
- for (let c = 0; c < tidDivs.length; c++) {
354
- tidDivs[c].style.color = "gray";
355
- }
356
- tidDiv.style.color = "blue";
357
- await room.changeQuality(trackInfo.id, null, i);
358
- });
359
- tidDisplay.appendChild(tidDiv);
360
- }
361
- }
362
- },
363
- updateQualityInfo: function(videoQuality) {
364
- for (const qualityInfo of videoQuality) {
365
- for (const qualityDiv of qualityDivs) {
366
- if (qualityDiv.innerText === qualityInfo.quality){
367
- if (qualityInfo.available === true) {
368
- qualityDiv.style.color = "gray";
369
- } else {
370
- qualityDiv.style.color = "red";
371
- }
372
- break;
373
- }
374
- }
375
- }
376
- },
377
- hasVideo: function() {
378
- return video !== null || this.videoMid !== undefined;
379
- },
380
- audioMid: undefined,
381
- videoMid: undefined
382
- };
383
- };
384
-
385
- peerConnection.ontrack = ({transceiver}) => {
386
- let rParticipant;
387
- console.log("Attach remote track " + transceiver.receiver.track.id + " kind " + transceiver.receiver.track.kind + " mid " + transceiver.mid);
388
- for (const [nickName, participant] of Object.entries(remoteParticipants)) {
389
- for (const pTrack of participant.tracks) {
390
- console.log("Participant " + participant.nickName + " track " + pTrack.id + " mid " + pTrack.mid);
391
- if (pTrack.mid === transceiver.mid) {
392
- rParticipant = participant;
393
- break;
394
- }
395
- }
396
- if (rParticipant) {
397
- break;
398
- }
399
- }
400
- if (rParticipant) {
401
- for (const display of rParticipant.displays) {
402
- if (transceiver.receiver.track.kind === "video") {
403
- if (display.videoMid === transceiver.mid) {
404
- let stream = new MediaStream();
405
- stream.addTrack(transceiver.receiver.track);
406
- display.setVideo(stream);
407
- break;
408
- }
409
- } else if (transceiver.receiver.track.kind === "audio") {
410
- if (display.audioMid === transceiver.mid) {
411
- let stream = new MediaStream();
412
- stream.addTrack(transceiver.receiver.track);
413
- display.setAudio(stream);
414
- break;
415
- }
416
- }
417
- }
418
- } else {
419
- console.warn("Failed to find participant for track " + transceiver.receiver.track.id);
420
- }
421
- }
422
- }
423
-
424
- const createRow = function(container) {
425
- const row = document.createElement('div');
426
- row.setAttribute("class","row");
427
- container.appendChild(row);
428
- return row;
429
- }
430
-
431
- const createCol = function(row) {
432
- const col = document.createElement('div');
433
- col.setAttribute("class","col local-video-display");
434
- row.appendChild(col);
435
- return col;
436
- }
437
-
438
- const gridSize = function(frames) {
439
- let x = 1;
440
- let y = 1;
441
- let fSqrt = Math.sqrt(frames);
442
- if (fSqrt % 1 === 0) {
443
- x = y = Math.sqrt(frames);
444
- } else {
445
- x = Math.ceil(fSqrt);
446
- while(x * y < frames) {
447
- y++;
448
- }
449
- }
450
- return {
451
- x: x,
452
- y: y
453
- }
454
- }
455
-
456
- const resizeVideo = function(video, width, height) {
457
- if (!video.parentNode) {
458
- return;
459
- }
460
- if (video instanceof HTMLCanvasElement) {
461
- video.videoWidth = video.width;
462
- video.videoHeight = video.height;
463
- }
464
- var display = video.parentNode;
465
- var parentSize = {
466
- w: display.parentNode.clientWidth,
467
- h: display.parentNode.clientHeight
468
- };
469
- var newSize;
470
- if (width && height) {
471
- newSize = downScaleToFitSize(width, height, parentSize.w, parentSize.h);
472
- } else {
473
- newSize = downScaleToFitSize(video.videoWidth, video.videoHeight, parentSize.w, parentSize.h);
474
- }
475
- display.style.width = newSize.w + "px";
476
- display.style.height = newSize.h + "px";
477
-
478
- //vertical align
479
- var margin = 0;
480
- if (parentSize.h - newSize.h > 1) {
481
- margin = Math.floor((parentSize.h - newSize.h) / 2);
482
- }
483
- display.style.margin = margin + "px auto";
484
- console.log("Resize from " + video.videoWidth + "x" + video.videoHeight + " to " + display.offsetWidth + "x" + display.offsetHeight);
485
- }
486
-
487
- const downScaleToFitSize = function(videoWidth, videoHeight, dstWidth, dstHeight) {
488
- var newWidth, newHeight;
489
- var videoRatio = videoWidth / videoHeight;
490
- var dstRatio = dstWidth / dstHeight;
491
- if (dstRatio > videoRatio) {
492
- newHeight = dstHeight;
493
- newWidth = Math.floor(videoRatio * dstHeight);
494
- } else {
495
- newWidth = dstWidth;
496
- newHeight = Math.floor(dstWidth / videoRatio);
497
- }
498
- return {
499
- w: newWidth,
500
- h: newHeight
501
- };
502
- }
@@ -1,67 +0,0 @@
1
- const stripCodecs = function(sdp, codecs) {
2
- if (!codecs.length) return sdp;
3
- var sdpArray = sdp.split("\n");
4
- var codecsArray = codecs.split(",");
5
-
6
- //search and delete codecs line
7
- var pt = [];
8
- var i;
9
- for (var p = 0; p < codecsArray.length; p++) {
10
- console.log("Searching for codec " + codecsArray[p]);
11
- for (i = 0; i < sdpArray.length; i++) {
12
- if (sdpArray[i].search(new RegExp(codecsArray[p],'i')) !== -1 && sdpArray[i].indexOf("a=rtpmap") === 0) {
13
- console.log(codecsArray[p] + " detected");
14
- pt.push(sdpArray[i].match(/[0-9]+/)[0]);
15
- sdpArray[i] = "";
16
- }
17
- }
18
- }
19
- if (pt.length) {
20
- //searching for fmtp
21
- for (p = 0; p < pt.length; p++) {
22
- for (i = 0; i < sdpArray.length; i++) {
23
- if (sdpArray[i].search("a=fmtp:" + pt[p]) !== -1 || sdpArray[i].search("a=rtcp-fb:" + pt[p]) !== -1) {
24
- sdpArray[i] = "";
25
- }
26
- }
27
- }
28
-
29
- //delete entries from m= line
30
- for (i = 0; i < sdpArray.length; i++) {
31
- if (sdpArray[i].search("m=audio") !== -1 || sdpArray[i].search("m=video") !== -1) {
32
- var mLineSplitted = sdpArray[i].split(" ");
33
- var newMLine = "";
34
- for (var m = 0; m < mLineSplitted.length; m++) {
35
- if (pt.indexOf(mLineSplitted[m].trim()) === -1 || m <= 2) {
36
- newMLine += mLineSplitted[m];
37
- if (m < mLineSplitted.length - 1) {
38
- newMLine = newMLine + " ";
39
- }
40
- }
41
- }
42
- sdpArray[i] = newMLine;
43
- }
44
- }
45
- }
46
-
47
- //normalize sdp after modifications
48
- var result = "";
49
- for (i = 0; i < sdpArray.length; i++) {
50
- if (sdpArray[i] !== "") {
51
- result += sdpArray[i] + "\n";
52
- }
53
- }
54
- return result;
55
- }
56
-
57
- const stripVideoCodecsExcept = function (sdp, codec) {
58
- let actualStripCodec = "rtx";
59
- if (codec === "VP8") {
60
- actualStripCodec += ",H264";
61
- } else if (codec === "H264") {
62
- actualStripCodec += ",VP8";
63
- } else {
64
- return sdp;
65
- }
66
- return stripCodecs(sdp, actualStripCodec);
67
- }