@flashphoner/sfusdk 1.0.40 → 1.0.47

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,4 +1,4 @@
1
- SFU SDK - 1.0.40
1
+ SFU SDK - 1.0.47
2
2
 
3
3
  [Download builds](https://docs.flashphoner.com/display/SS1E/Release+notes)
4
4
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@flashphoner/sfusdk",
3
3
  "description": "Official Flashphoner WebCallServer SFU SDK package",
4
- "version": "1.0.40",
4
+ "version": "1.0.47",
5
5
  "scripts": {
6
6
  "test": "jest --runInBand"
7
7
  },
@@ -17,13 +17,15 @@
17
17
  "webrtc-adapter": "^7.2.6"
18
18
  },
19
19
  "devDependencies": {
20
+ "@mapbox/node-pre-gyp": "^1.0.8",
20
21
  "grunt": "^1.0.1",
21
22
  "grunt-browserify": "^5.0.0",
22
23
  "grunt-contrib-clean": "^1.0.0",
23
24
  "grunt-contrib-copy": "^1.0.0",
24
25
  "grunt-jsdoc": "^2.4.0",
25
26
  "grunt-run": "^0.8.1",
26
- "jest": "^27.4.7"
27
+ "jest": "^27.4.7",
28
+ "wrtc": "^0.4.7"
27
29
  },
28
30
  "keywords": [
29
31
  "Flashphoner",
@@ -33,6 +35,7 @@
33
35
  "author": "Flashphoner",
34
36
  "license": "MIT",
35
37
  "jest" : {
36
- "testEnvironment": "jsdom"
38
+ "testEnvironment": "jsdom",
39
+ "testRunner": "jest-jasmine2"
37
40
  }
38
41
  }
@@ -100,6 +100,9 @@ const connect = function(state) {
100
100
  roomConfig.url = $("#url").val();
101
101
  roomConfig.roomName = $("#roomName").val();
102
102
  roomConfig.nickname = $("#" + state.inputId()).val();
103
+ // clean state display items
104
+ setStatus(state.statusId(), "");
105
+ setStatus(state.errInfoId(), "");
103
106
  // connect to server and create a room if not
104
107
  const session = sfu.createRoom(roomConfig);
105
108
  session.on(constants.SFU_EVENT.CONNECTED, function(room) {
@@ -56,16 +56,37 @@ const CurrentState = function(prefix) {
56
56
  pc: null,
57
57
  session: null,
58
58
  room: null,
59
+ timer: null,
59
60
  set: function(pc, session, room) {
60
61
  state.pc = pc;
61
62
  state.session = session;
62
63
  state.room = room;
63
64
  },
64
65
  clear: function() {
66
+ state.stopWaiting();
65
67
  state.room = null;
66
68
  state.session = null;
67
69
  state.pc = null;
68
70
  },
71
+ waitFor: function(div, timeout) {
72
+ state.stopWaiting();
73
+ state.timer = setTimeout(function () {
74
+ if (div.innerHTML !== "") {
75
+ // Enable stop button
76
+ $("#" + state.buttonId()).prop('disabled', false);
77
+ }
78
+ else if (state.isConnected()) {
79
+ setStatus(state.errInfoId(), "No media capturing started in " + timeout + " ms, stopping", "red");
80
+ onStopClick(state);
81
+ }
82
+ }, timeout);
83
+ },
84
+ stopWaiting: function() {
85
+ if (state.timer) {
86
+ clearTimeout(state.timer);
87
+ state.timer = null;
88
+ }
89
+ },
69
90
  buttonId: function() {
70
91
  return state.prefix + "Btn";
71
92
  },
@@ -86,6 +107,12 @@ const CurrentState = function(prefix) {
86
107
  },
87
108
  is: function(value) {
88
109
  return (prefix === value);
110
+ },
111
+ isActive: function() {
112
+ return (state.room && state.pc);
113
+ },
114
+ isConnected: function() {
115
+ return (state.session && state.session.state() == constants.SFU_STATE.CONNECTED);
89
116
  }
90
117
  };
91
118
  return state;
@@ -165,14 +192,12 @@ const onConnected = function(state) {
165
192
  // Add errors displaying
166
193
  state.room.on(constants.SFU_ROOM_EVENT.FAILED, function(e) {
167
194
  setStatus(state.errInfoId(), e, "red");
195
+ stopStreaming(state);
168
196
  }).on(constants.SFU_ROOM_EVENT.OPERATION_FAILED, function (e) {
169
197
  setStatus(state.errInfoId(), e.operation + " failed: " + e.error, "red");
198
+ stopStreaming(state);
170
199
  });
171
- if (state.is(PUBLISH)) {
172
- publishStreams(state);
173
- } else if (state.is(PLAY)) {
174
- playStreams(state);
175
- }
200
+ startStreaming(state);
176
201
  }
177
202
 
178
203
  const onDisconnected = function(state) {
@@ -204,65 +229,67 @@ const onStartClick = function(state) {
204
229
 
205
230
  const onStopClick = function(state) {
206
231
  $("#" + state.buttonId()).prop('disabled', true);
232
+ stopStreaming(state);
233
+ if (state.isConnected()) {
234
+ state.session.disconnect();
235
+ }
236
+ }
237
+
238
+ const startStreaming = function(state) {
207
239
  if (state.is(PUBLISH)) {
208
- unPublishStreams(state);
240
+ publishStreams(state);
209
241
  } else if (state.is(PLAY)) {
210
- stopStreams(state);
211
- }
212
- state.session.disconnect();
242
+ playStreams(state);
243
+ }
213
244
  }
214
245
 
215
- const publishStreams = async function(state) {
216
- let timerId;
217
- //create local display item to show local streams
218
- localDisplay = initLocalDisplay(document.getElementById("localVideo"));
219
- try {
220
- //get configured local video streams
221
- let streams = await getVideoStreams(mainConfig);
222
- let audioStreams = await getAudioStreams(mainConfig);
223
- //combine local video streams with audio streams
224
- streams.push.apply(streams, audioStreams);
225
- let config = {};
226
- //add our local streams to the room (to PeerConnection)
227
- streams.forEach(function (s) {
228
- //add local stream to local display
229
- localDisplay.add(s.stream.id, $("#" + state.inputId()).val(), s.stream);
230
- //add each track to PeerConnection
231
- s.stream.getTracks().forEach((track) => {
232
- if (s.source === "screen") {
233
- config[track.id] = s.source;
234
- }
235
- addTrackToPeerConnection(state.pc, s.stream, track, s.encodings);
236
- subscribeTrackToEndedEvent(state.room, track, state.pc);
237
- });
238
- });
239
- state.room.join(config);
240
- // TODO: Use room state or promises to detect if publishing started to enable stop button
241
- timerId = waitFor(document.getElementById("localVideo"), 3000, state);
242
- } catch(e) {
243
- console.error("Failed to capture streams: " + e);
244
- setStatus(state.errInfoId(), e.name, "red");
245
- if (timerId) {
246
- clearTimeout(timerId);
247
- timerId = null;
248
- }
249
- onStopClick(state);
246
+ const stopStreaming = function(state) {
247
+ state.stopWaiting();
248
+ if (state.is(PUBLISH)) {
249
+ unPublishStreams(state);
250
+ } else if (state.is(PLAY)) {
251
+ stopStreams(state);
250
252
  }
251
253
  }
252
254
 
253
- // A workaround to check if publishing or playback is started
254
- const waitFor = function (div, timeout, state) {
255
- let timerId = setTimeout(function () {
256
- if (div.innerHTML !== "") {
257
- // Enable stop button
258
- $("#" + state.buttonId()).prop('disabled', false);
259
- }
260
- else {
261
- setStatus(state.errInfoId(), "Something went wrong, stopping", "red");
262
- onStopClick(state);
255
+ const publishStreams = async function(state) {
256
+ if (state.isConnected()) {
257
+ //create local display item to show local streams
258
+ localDisplay = initLocalDisplay(document.getElementById("localVideo"));
259
+ try {
260
+ //get configured local video streams
261
+ let streams = await getVideoStreams(mainConfig);
262
+ let audioStreams = await getAudioStreams(mainConfig);
263
+ if (state.isConnected() && state.isActive()) {
264
+ //combine local video streams with audio streams
265
+ streams.push.apply(streams, audioStreams);
266
+ let config = {};
267
+ //add our local streams to the room (to PeerConnection)
268
+ streams.forEach(function (s) {
269
+ //add local stream to local display
270
+ localDisplay.add(s.stream.id, $("#" + state.inputId()).val(), s.stream);
271
+ //add each track to PeerConnection
272
+ s.stream.getTracks().forEach((track) => {
273
+ if (s.source === "screen") {
274
+ config[track.id] = s.source;
275
+ }
276
+ addTrackToPeerConnection(state.pc, s.stream, track, s.encodings);
277
+ subscribeTrackToEndedEvent(state.room, track, state.pc);
278
+ });
279
+ });
280
+ state.room.join(config);
281
+ // TODO: Use room state or promises to detect if publishing started to enable stop button
282
+ state.waitFor(document.getElementById("localVideo"), 3000);
283
+ }
284
+ } catch(e) {
285
+ console.error("Failed to capture streams: " + e);
286
+ setStatus(state.errInfoId(), e.name, "red");
287
+ state.stopWaiting();
288
+ if (state.isConnected()) {
289
+ onStopClick(state);
290
+ }
263
291
  }
264
- }, timeout);
265
- return timerId;
292
+ }
266
293
  }
267
294
 
268
295
  const unPublishStreams = function(state) {
@@ -272,9 +299,11 @@ const unPublishStreams = function(state) {
272
299
  }
273
300
 
274
301
  const playStreams = function(state) {
275
- //create remote display item to show remote streams
276
- remoteDisplay = initRemoteDisplay(document.getElementById("remoteVideo"), state.room, state.pc);
277
- state.room.join();
302
+ if (state.isConnected() && state.isActive()) {
303
+ //create remote display item to show remote streams
304
+ remoteDisplay = initRemoteDisplay(document.getElementById("remoteVideo"), state.room, state.pc);
305
+ state.room.join();
306
+ }
278
307
  $("#" + state.buttonId()).prop('disabled', false);
279
308
  }
280
309
 
@@ -63,6 +63,10 @@ const constants = Object.freeze({
63
63
  CHAT_DELETED: "CHAT_DELETED",
64
64
  CHAT_UPDATED: "CHAT_UPDATED",
65
65
  MESSAGE_STATE: "MESSAGE_STATE",
66
+ CONTACT_UPDATE: "CONTACT_UPDATE",
67
+ CONTACT_REMOVED: "CONTACT_REMOVED",
68
+ CONTACT_INVITE: "CONTACT_INVITE",
69
+ PUBLIC_CHANNELS: "PUBLIC_CHANNELS",
66
70
 
67
71
  /**
68
72
  * @typedef {Object} UserCalendar
@@ -291,6 +295,7 @@ const constants = Object.freeze({
291
295
  * @memberof FlashphonerSFU.SFU_ROOM_EVENT
292
296
  */
293
297
  WAITING_LIST: "SFU_WAITING_LIST",
298
+ WAITING_ROOM_UPDATE: "SFU_WAITING_ROOM_UPDATE",
294
299
  /**
295
300
  * Fires when mute/unmute state of one of the Room's participating tracks changes
296
301
  * Event object {@link FlashphonerSFU.Room.TracksInfo}
@@ -388,7 +393,12 @@ const constants = Object.freeze({
388
393
  * Room failed, something went wrong during room operations
389
394
  * @memberOf FlashphonerSFU.SFU_ROOM_STATE
390
395
  */
391
- FAILED: "FAILED"
396
+ FAILED: "FAILED",
397
+ /**
398
+ * Room disposed, leaveRoom or destroyRoom was called
399
+ * @memberOf FlashphonerSFU.SFU_ROOM_STATE
400
+ */
401
+ DISPOSED: "DISPOSED"
392
402
  }),
393
403
  /**
394
404
  * Internal api constants such as server side methods
@@ -409,16 +419,26 @@ const constants = Object.freeze({
409
419
  USER_LIST: "SFU_USER_LIST",
410
420
  USER_CALENDAR: "SFU_USER_CALENDAR",
411
421
  USER_CHATS: "SFU_USER_CHATS",
422
+ PUBLIC_CHANNELS: "SFU_PUBLIC_CHANNELS",
412
423
  CHAT_LOADED: "SFU_CHAT_LOADED",
413
424
  NEW_CHAT: "SFU_NEW_CHAT",
414
425
  CHAT_DELETED: "SFU_CHAT_DELETED",
415
426
  CHAT_UPDATED: "SFU_UPDATE_CHAT",
427
+ CONTACT_UPDATED: "SFU_CONTACT_UPDATE",
428
+ CONTACT_INVITE: "SFU_CONTACT_INVITE",
429
+ CONTACT_REMOVED: "SFU_CONTACT_REMOVED",
416
430
  GET_USER_LIST: "getUserList",
417
431
  GET_USER_CALENDAR: "getUserCalendar",
418
432
  ADD_CALENDAR_EVENT: "addCalendarEvent",
419
433
  REMOVE_CALENDAR_EVENT: "removeCalendarEvent",
420
434
  MUTE_TRACK: "muteTrack",
435
+ SEND_MESSAGE: "sendMessage",
421
436
  SEND_CONTROL_MESSAGE: "sendControlMessage",
437
+ MARK_MESSAGE_READ: "markMessageRead",
438
+ MARK_MESSAGE_UNREAD: "markMessageUnread",
439
+ INVITE_CONTACT: "inviteContact",
440
+ REMOVE_CONTACT: "removeContact",
441
+ CONFIRM_CONTACT: "confirmContact",
422
442
  ASSIGN_ROLE: "assignRole",
423
443
  SUBSCRIBE_TO_WAITING_PARTICIPANT: "subscribeToWaitingParticipant",
424
444
  UNSUBSCRIBE_FROM_WAITING_PARTICIPANT: "unsubscribeFromWaitingParticipant",
@@ -426,12 +446,18 @@ const constants = Object.freeze({
426
446
  CONFIGURE_WAITING_ROOM: "configureWaitingRoom",
427
447
  TRACK_CONTENT_HEADER: "a=content:",
428
448
  GET_USER_CHATS: "getUserChats",
449
+ GET_PUBLIC_CHANNELS: "getPublicChannels",
429
450
  LOAD_CHAT: "loadChat",
430
451
  CREATE_CHAT: "createChat",
431
452
  DELETE_CHAT: "deleteChat",
432
453
  RENAME_CHAT: "renameChat",
433
454
  ADD_MEMBER_TO_CHAT: "addMemberToChat",
434
- REMOVE_MEMBER_FROM_CHAT: "removeMemberFromChat"
455
+ REMOVE_MEMBER_FROM_CHAT: "removeMemberFromChat",
456
+ UPDATE_CHANNEL_SEND_POLICY: "updateChannelSendPolicy",
457
+ ADD_CHANNEL_SEND_PERMISSION_LIST_MEMBER: "addChannelSendPermissionListMember",
458
+ REMOVE_CHANNEL_SEND_PERMISSION_LIST_MEMBER: "removeChannelSendPermissionListMember",
459
+ ADD_CHAT_TO_FAVOURITES: "addChatToFavourites",
460
+ REMOVE_CHAT_FROM_FAVOURITES: "removeChatFromFavourites"
435
461
  }),
436
462
  /**
437
463
  * @namespace FlashphonerSFUExtended.SFU_OPERATIONS
@@ -0,0 +1,16 @@
1
+ let prefix = () => {};
2
+ const setPrefix = (func) => {
3
+ if (typeof func !== "function") {
4
+ throw new Error("Prefix must be a function");
5
+ }
6
+ prefix = func;
7
+ };
8
+ const log = (...args) => {
9
+ console.log(prefix(), ...args);
10
+ };
11
+
12
+ module.exports = {
13
+ setPrefix: setPrefix,
14
+ log: log,
15
+ info: log
16
+ };