@flashphoner/websdk 2.0.208 → 2.0.212

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.
Files changed (38) hide show
  1. package/docTemplate/README.md +1 -1
  2. package/examples/demo/streaming/2players/2players.js +0 -5
  3. package/examples/demo/streaming/canvas_streaming/canvas_streaming.js +0 -12
  4. package/examples/demo/streaming/conference/conference.html +6 -0
  5. package/examples/demo/streaming/conference/conference.js +83 -23
  6. package/examples/demo/streaming/embed_player/player.js +127 -198
  7. package/examples/demo/streaming/firewall-traversal-streaming/firewall-traversal-streaming.js +0 -12
  8. package/examples/demo/streaming/mcu_client/mcu_client.js +0 -8
  9. package/examples/demo/streaming/media_devices_manager/manager.js +0 -12
  10. package/examples/demo/streaming/player/player.js +10 -9
  11. package/examples/demo/streaming/stream-auto-restore/stream-auto-restore.html +77 -1
  12. package/examples/demo/streaming/stream-auto-restore/stream-auto-restore.js +472 -84
  13. package/examples/demo/streaming/stream-diagnostic/stream-diagnostic.js +0 -8
  14. package/examples/demo/streaming/stream-local-snapshot/stream-local-snapshot.js +0 -6
  15. package/examples/demo/streaming/stream-snapshot/stream-snapshot.js +0 -6
  16. package/examples/demo/streaming/stream_recording/recording.js +0 -6
  17. package/examples/demo/streaming/streamer/streamer.js +0 -8
  18. package/examples/demo/streaming/two_way_streaming/two_way_streaming.js +0 -11
  19. package/examples/demo/streaming/webrtc-as-rtmp-republishing/webrtc-as-rtmp-republishing.js +0 -6
  20. package/flashphoner-no-flash.js +118 -14
  21. package/flashphoner-no-flash.min.js +2 -2
  22. package/flashphoner-no-webrtc.js +89 -5
  23. package/flashphoner-no-webrtc.min.js +1 -1
  24. package/flashphoner-no-wsplayer.js +118 -14
  25. package/flashphoner-no-wsplayer.min.js +2 -2
  26. package/flashphoner-room-api.js +104 -9
  27. package/flashphoner-room-api.min.js +2 -2
  28. package/flashphoner-temasys-flash-websocket-without-adapterjs.js +89 -5
  29. package/flashphoner-temasys-flash-websocket.js +89 -5
  30. package/flashphoner-temasys-flash-websocket.min.js +1 -1
  31. package/flashphoner-webrtc-only.js +118 -14
  32. package/flashphoner-webrtc-only.min.js +1 -1
  33. package/flashphoner.js +118 -14
  34. package/flashphoner.min.js +2 -2
  35. package/package.json +1 -1
  36. package/src/flashphoner-core.d.ts +22 -5
  37. package/src/flashphoner-core.js +79 -3
  38. package/src/webrtc-media-provider.js +25 -6
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flashphoner/websdk",
3
- "version": "2.0.208",
3
+ "version": "2.0.212",
4
4
  "description": "Official Flashphoner WebCallServer WebSDK package",
5
5
  "main": "./src/flashphoner-core.js",
6
6
  "types": "./src/flashphoner-core.d.ts",
@@ -6,7 +6,7 @@ export declare class Call {
6
6
  receiveAudio?: boolean | undefined;
7
7
  receiveVideo?: boolean | undefined;
8
8
  constraints?: string | undefined;
9
- stripCodecs?: Array<string> | undefined;
9
+ stripCodecs?: string | undefined;
10
10
  sipSDP?: Array<string> | undefined;
11
11
  sipHeaders?: Array<string> | undefined;
12
12
  }) => void;
@@ -91,12 +91,25 @@ export declare class Session {
91
91
  cacheLocalResources?: boolean | undefined;
92
92
  playWidth?: number | undefined;
93
93
  playHeight?: number | undefined;
94
-
94
+ record?: boolean | undefined;
95
+ display: any;
96
+ custom?: any | undefined;
97
+ stripCodecs?: string | undefined;
98
+ rtmpUrl?: string | undefined;
99
+ mediaConnectionConstraints?: any | undefined;
100
+ flashShowFullScreenButton?: boolean | undefined;
101
+ transport?: string | undefined;
102
+ cvoExtension?: boolean | undefined;
103
+ playoutDelay?: number | undefined;
104
+ useCanvasMediaStream?: boolean | undefined;
105
+ videoContentHint?: string | undefined;
106
+ unmutePlayOnStart?: boolean | undefined;
107
+ sdpHook?: any | undefined
95
108
  }) => Stream;
96
109
  createCall: (options: {
97
110
  callee: string;
98
111
  visibleName?: string | undefined;
99
- constraints: any;
112
+ constraints?: any | undefined;
100
113
  mediaProvider: string;
101
114
  receiveAudio?: boolean | undefined;
102
115
  receiveVideo?: boolean | undefined;
@@ -104,10 +117,11 @@ export declare class Session {
104
117
  localVideoDisplay: HTMLElement;
105
118
  remoteVideoDisplay: HTMLElement;
106
119
  custom?: any | undefined;
107
- stripCodecs?: Array<string> | undefined;
120
+ stripCodecs?: string | undefined;
108
121
  sipSDP?: Array<string> | undefined;
109
122
  sipHeaders?: Array<string> | undefined;
110
123
  videoContentHint?: string | undefined;
124
+ toStream?: string | undefined;
111
125
  }) => Call;
112
126
  getStream: (streamId: string) => any;
113
127
  getStreams: () => any[];
@@ -179,7 +193,10 @@ export function createSession(options: {
179
193
  custom?: any | undefined;
180
194
  sipOptions?: any | undefined;
181
195
  mediaOptions?: any | undefined;
182
- timeout?: any | undefined;
196
+ timeout?: number | undefined;
197
+ pingInterval?: number | undefined;
198
+ receiveProbes?: number | undefined;
199
+ probesInterval?: number | undefined;
183
200
  }): Session;
184
201
  export function playFirstSound (noise?: boolean): any;
185
202
  export function playFirstVideo (display: any, isLocal: boolean, src: any): any;
@@ -403,6 +403,9 @@ var getSession = function (id) {
403
403
  * @param {Object=} options.sipOptions Sip configuration
404
404
  * @param {Object=} options.mediaOptions Media connection configuration
405
405
  * @param {Integer=} options.timeout Connection timeout in milliseconds
406
+ * @param {Integer=} options.pingInterval Server ping interval in milliseconds [0]
407
+ * @param {Integer=} options.receiveProbes A maximum subsequental pings received missing count [0]
408
+ * @param {Integer=} options.probesInterval Interval to check subsequental pings received [0]
406
409
  * @returns {Session} Created session
407
410
  * @throws {Error} Error if API is not initialized
408
411
  * @throws {TypeError} Error if options.urlServer is not specified
@@ -427,6 +430,8 @@ var createSession = function (options) {
427
430
  var mediaOptions = options.mediaOptions;
428
431
  var keepAlive = options.keepAlive;
429
432
  var timeout = options.timeout;
433
+ var wsPingSender = new WSPingSender(options.pingInterval || 0);
434
+ var wsPingReceiver = new WSPingReceiver(options.receiveProbes || 0, options.probesInterval || 0);
430
435
  var connectionTimeout;
431
436
 
432
437
  var cConfig;
@@ -534,7 +539,7 @@ var createSession = function (options) {
534
539
  mediaProviders: Object.keys(MediaProvider),
535
540
  keepAlive: keepAlive,
536
541
  authToken:authToken,
537
- clientVersion: "2.0.208",
542
+ clientVersion: "2.0.212",
538
543
  clientOSVersion: window.navigator.appVersion,
539
544
  clientBrowserVersion: window.navigator.userAgent,
540
545
  msePacketizationVersion: 2,
@@ -546,6 +551,10 @@ var createSession = function (options) {
546
551
  //connect to REST App
547
552
  send("connection", cConfig);
548
553
  logger.setConnection(wsConnection);
554
+ // Send ping messages to server to check if connection is still alive #WCS-3410
555
+ wsPingSender.start();
556
+ // Check subsequintel pings received from server to check if connection is still alive #WCS-3410
557
+ wsPingReceiver.start();
549
558
  };
550
559
  wsConnection.onmessage = function (event) {
551
560
  var data = {};
@@ -558,6 +567,7 @@ var createSession = function (options) {
558
567
  switch (data.message) {
559
568
  case 'ping':
560
569
  send("pong", null);
570
+ wsPingReceiver.success();
561
571
  break;
562
572
  case 'getUserData':
563
573
  authToken = obj.authToken;
@@ -684,6 +694,10 @@ var createSession = function (options) {
684
694
  function onSessionStatusChange(newStatus, obj) {
685
695
  sessionStatus = newStatus;
686
696
  if (sessionStatus == SESSION_STATUS.DISCONNECTED || sessionStatus == SESSION_STATUS.FAILED) {
697
+ // Stop pinging server #WCS-3410
698
+ wsPingSender.stop();
699
+ // Stop checking pings received #WCS-3410
700
+ wsPingReceiver.stop();
687
701
  //remove streams
688
702
  for (var prop in streamRefreshHandlers) {
689
703
  if (streamRefreshHandlers.hasOwnProperty(prop) && typeof streamRefreshHandlers[prop] === 'function') {
@@ -698,6 +712,65 @@ var createSession = function (options) {
698
712
  }
699
713
  }
700
714
 
715
+ // Websocket periodic ping sender
716
+ function WSPingSender(interval) {
717
+ this.interval = interval || 0;
718
+ this.intervalId = null;
719
+ this.start = function() {
720
+ if (this.interval > 0) {
721
+ this.intervalId = setInterval(function() {
722
+ send("ping", null);
723
+ }, this.interval);
724
+ }
725
+ };
726
+ this.stop = function() {
727
+ if (this.intervalId) {
728
+ clearInterval(this.intervalId);
729
+ }
730
+ };
731
+
732
+ return(this);
733
+ }
734
+
735
+ // Websocket ping receive prober
736
+ function WSPingReceiver(receiveProbes, probesInterval) {
737
+ this.maxPings = receiveProbes || 0;
738
+ this.interval = probesInterval || 0;
739
+ this.intervalId = null;
740
+ this.pingsMissing = 0;
741
+ this.start = function() {
742
+ if (this.maxPings > 0 && this.interval > 0) {
743
+ let receiver = this;
744
+ this.intervalId = setInterval(function() {
745
+ receiver.checkPingsReceived();
746
+ }, this.interval);
747
+ }
748
+ };
749
+ this.stop = function() {
750
+ if (this.intervalId) {
751
+ clearInterval(this.intervalId);
752
+ }
753
+ this.pingsMissing = 0;
754
+ };
755
+ this.checkPingsReceived = function() {
756
+ this.pingsMissing++;
757
+ if (this.pingsMissing >= this.maxPings) {
758
+ this.failure();
759
+ }
760
+ };
761
+ this.success = function() {
762
+ this.pingsMissing = 0;
763
+ };
764
+ this.failure = function() {
765
+ logger.info(LOG_PREFIX, "Missing " + this.pingsMissing + " pings from server, connection seems to be down");
766
+ onSessionStatusChange(SESSION_STATUS.FAILED);
767
+ wsConnection.close();
768
+ };
769
+
770
+ return(this);
771
+ }
772
+
773
+
701
774
  /**
702
775
  * @callback sdpHook
703
776
  * @param {Object} sdp Callback options
@@ -1472,7 +1545,7 @@ var createSession = function (options) {
1472
1545
  * @param {HTMLElement} options.display Div element stream should be displayed in
1473
1546
  * @param {Object=} options.custom User provided custom object that will be available in REST App code
1474
1547
  * @param {Integer} [options.flashBufferTime=0] Specifies how long to buffer messages before starting to display the stream (Flash-only)
1475
- * @param {String=} options.stripCodecs Comma separated string of codecs which should be stripped from WebRTC SDP (ex. "H264,PCMA,PCMU,G722")
1548
+ * @param {string=} options.stripCodecs Comma separated string of codecs which should be stripped from WebRTC SDP (ex. "H264,PCMA,PCMU,G722")
1476
1549
  * @param {string=} options.rtmpUrl Rtmp url stream should be forwarded to
1477
1550
  * @param {Object=} options.mediaConnectionConstraints Stream specific constraints for underlying RTCPeerConnection
1478
1551
  * @param {Boolean=} options.flashShowFullScreenButton Show full screen button in flash
@@ -1481,6 +1554,7 @@ var createSession = function (options) {
1481
1554
  * @param {Integer=} options.playoutDelay Time delay between network reception of media and playout
1482
1555
  * @param {string=} options.useCanvasMediaStream EXPERIMENTAL: when publish bind browser's media stream to the canvas. It can be useful for image filtering
1483
1556
  * @param {string=} options.videoContentHint Video content hint for browser ('detail' by default to maintain resolution), {@link Flashphoner.constants.CONTENT_HINT_TYPE}
1557
+ * @param {Boolean=} options.unmutePlayOnStart Unmute playback on start. May be used after user gesture only, so set 'unmutePlayOnStart: false' for autoplay
1484
1558
  * @param {sdpHook} sdpHook The callback that handles sdp from the server
1485
1559
  * @returns {Stream} Stream
1486
1560
  * @throws {TypeError} Error if no options provided
@@ -1584,6 +1658,7 @@ var createSession = function (options) {
1584
1658
  var playoutDelay = options.playoutDelay;
1585
1659
  var useCanvasMediaStream = options.useCanvasMediaStream;
1586
1660
  var videoContentHint = options.videoContentHint;
1661
+ var unmutePlayOnStart = options.unmutePlayOnStart;
1587
1662
 
1588
1663
  var audioState_;
1589
1664
  var videoState_;
@@ -1758,7 +1833,8 @@ var createSession = function (options) {
1758
1833
  connectionConstraints: mediaConnectionConstraints,
1759
1834
  audioOutputId: audioOutputId,
1760
1835
  remoteVideo: remoteVideo,
1761
- playoutDelay: playoutDelay
1836
+ playoutDelay: playoutDelay,
1837
+ unmutePlayOnStart: unmutePlayOnStart
1762
1838
  }, streamRefreshHandlers[id_]).then(function (newConnection) {
1763
1839
  mediaConnection = newConnection;
1764
1840
  try {
@@ -52,6 +52,8 @@ var createConnection = function (options) {
52
52
  var playoutDelay = options.playoutDelay;
53
53
  // Set video track contentHint to `detail` by default to workaround Chromium 91 bug #WCS-3257
54
54
  var videoContentHint = options.videoContentHint ? options.videoContentHint : 'detail';
55
+ // Pass the option to unmute automatically (true by default) #WCS-2425
56
+ var unmutePlayOnStart = options.unmutePlayOnStart !== undefined ? options.unmutePlayOnStart : true;
55
57
 
56
58
  if (bidirectional) {
57
59
  localVideo = getCacheInstance(localDisplay);
@@ -67,7 +69,7 @@ var createConnection = function (options) {
67
69
  }
68
70
  remoteVideo = getCacheInstance(remoteDisplay);
69
71
  if (!remoteVideo) {
70
- remoteVideo = document.createElement('video');
72
+ remoteVideo = createVideoElement();
71
73
  remoteDisplay.appendChild(remoteVideo);
72
74
  }
73
75
  remoteVideo.id = id + "-remote";
@@ -88,7 +90,7 @@ var createConnection = function (options) {
88
90
  if (cachedVideo) {
89
91
  remoteVideo = cachedVideo;
90
92
  } else {
91
- remoteVideo = document.createElement('video');
93
+ remoteVideo = createVideoElement();
92
94
  display.appendChild(remoteVideo);
93
95
  }
94
96
  remoteVideo.id = id;
@@ -141,7 +143,12 @@ var createConnection = function (options) {
141
143
  remoteVideo.srcObject = event.streams[0];
142
144
  remoteVideo.onloadedmetadata = function (e) {
143
145
  if (remoteVideo) {
144
- remoteVideo.play().catch(function (e) {
146
+ remoteVideo.play().then(function() {
147
+ // Automatically unmute video if needed #WCS-2425
148
+ if (unmutePlayOnStart) {
149
+ remoteVideo.muted = false;
150
+ }
151
+ }).catch(function (e) {
145
152
  if (validBrowsers.includes(browserDetails.browser)) {
146
153
  //WCS-1698. fixed autoplay in chromium based browsers
147
154
  //WCS-2375. fixed autoplay in ios safari
@@ -714,6 +721,7 @@ var createConnection = function (options) {
714
721
  };
715
722
 
716
723
 
724
+
717
725
  var mixAudioTracks = function (stream1, stream2) {
718
726
  var stream1Sound = audioContext.createMediaStreamSource(stream1);
719
727
  var stream2Sound = audioContext.createMediaStreamSource(stream2);
@@ -845,13 +853,11 @@ var getMediaAccess = function (constraints, display, disableConstraintsNormaliza
845
853
  var loadOrdinaryVideo = function(display, stream, screenShare, constraints, video) {
846
854
  let vEl = video;
847
855
  if (!vEl) {
848
- vEl = document.createElement('video');
856
+ vEl = createVideoElement();
849
857
  display.appendChild(vEl);
850
858
  }
851
859
  vEl.id = uuid_v1() + LOCAL_CACHED_VIDEO;
852
860
  vEl.srcObject = stream;
853
- //mute audio
854
- vEl.muted = true;
855
861
  vEl.onloadedmetadata = function (e) {
856
862
  //WCS-2751 Add screen capture using getDisplayMedia in Safari
857
863
  if (screenShare && !screenCaptureSupportedBrowsers()) {
@@ -1185,6 +1191,17 @@ function getCacheInstance(display) {
1185
1191
  }
1186
1192
  }
1187
1193
 
1194
+ function createVideoElement() {
1195
+ let video = document.createElement('video');
1196
+ // Prepare video tag to auto play and add specific Safari tweaks #WCS-2425
1197
+ video.muted = true;
1198
+ if(util.Browser.isSafariWebRTC()) {
1199
+ video.setAttribute("playsinline", "");
1200
+ video.setAttribute("webkit-playsinline", "");
1201
+ }
1202
+ return(video);
1203
+ }
1204
+
1188
1205
  function removeVideoElement(video) {
1189
1206
  if (video.srcObject) {
1190
1207
  //pause
@@ -1382,6 +1399,8 @@ var playFirstVideo = function (display, isLocal, src) {
1382
1399
  var video = document.createElement('video');
1383
1400
  video.setAttribute("playsinline", "");
1384
1401
  video.setAttribute("webkit-playsinline", "");
1402
+ //Mute video tag to prevent local audio playback in Safari #WCS-3430
1403
+ video.muted = true;
1385
1404
  video.id = uuid_v1() + (isLocal ? LOCAL_CACHED_VIDEO : REMOTE_CACHED_VIDEO);
1386
1405
 
1387
1406
  //in WCS-1560 we removed video.play() call, because it triggers the “Unhandled Promise Rejection” exception in iOS Safari