@flashphoner/websdk 2.0.223 → 2.0.224

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.
@@ -9955,6 +9955,7 @@ var createSession = function (options) {
9955
9955
  * @param {Array<string>=} options.sipSDP Array of custom SDP params (ex. bandwidth (b=))
9956
9956
  * @param {Array<string>=} options.sipHeaders Array of custom SIP headers
9957
9957
  * @param {string=} options.videoContentHint Video content hint for browser ('detail' by default to maintain resolution), {@link Flashphoner.constants.CONTENT_HINT_TYPE}
9958
+ * @param {Boolean=} options.useControls Use a standard HTML5 video controls (play, pause, fullscreen). May be a workaround for fullscreen mode to work in Safari 16
9958
9959
  * @param {Object=} options.logger Call logger options
9959
9960
  * @param {sdpHook} sdpHook The callback that handles sdp from the server
9960
9961
  * @returns {Call} Call
@@ -10019,6 +10020,7 @@ var createSession = function (options) {
10019
10020
  var sipSDP = options.sipSDP;
10020
10021
  var sipHeaders = options.sipHeaders;
10021
10022
  var videoContentHint = options.videoContentHint;
10023
+ var useControls = options.useControls;
10022
10024
  /**
10023
10025
  * Represents sip call.
10024
10026
  *
@@ -10115,6 +10117,7 @@ var createSession = function (options) {
10115
10117
  connectionConfig: mediaOptions,
10116
10118
  audioOutputId: audioOutputId,
10117
10119
  videoContentHint: videoContentHint,
10120
+ useControls: useControls,
10118
10121
  logger: logger
10119
10122
  }).then(function (newConnection) {
10120
10123
  mediaConnection = newConnection;
@@ -10253,7 +10256,8 @@ var createSession = function (options) {
10253
10256
  login: cConfig.sipLogin,
10254
10257
  constraints: constraints,
10255
10258
  connectionConfig: mediaOptions,
10256
- audioOutputId: audioOutputId
10259
+ audioOutputId: audioOutputId,
10260
+ useControls: useControls
10257
10261
  }).then(function (newConnection) {
10258
10262
  mediaConnection = newConnection;
10259
10263
  return mediaConnection.setRemoteSdp(sdp);
@@ -10731,6 +10735,7 @@ var createSession = function (options) {
10731
10735
  * @param {string=} options.useCanvasMediaStream EXPERIMENTAL: when publish bind browser's media stream to the canvas. It can be useful for image filtering
10732
10736
  * @param {string=} options.videoContentHint Video content hint for browser ('detail' by default to maintain resolution), {@link Flashphoner.constants.CONTENT_HINT_TYPE}
10733
10737
  * @param {Boolean=} options.unmutePlayOnStart Unmute playback on start. May be used after user gesture only, so set 'unmutePlayOnStart: false' for autoplay
10738
+ * @param {Boolean=} options.useControls Use a standard HTML5 video controls (play, pause, fullscreen). May be a workaround for fullscreen mode to work in Safari 16
10734
10739
  * @param {Object=} options.logger Stream logger options
10735
10740
  * @param {sdpHook} sdpHook The callback that handles sdp from the server
10736
10741
  * @returns {Stream} Stream
@@ -10841,6 +10846,7 @@ var createSession = function (options) {
10841
10846
  var useCanvasMediaStream = options.useCanvasMediaStream;
10842
10847
  var videoContentHint = options.videoContentHint;
10843
10848
  var unmutePlayOnStart = options.unmutePlayOnStart;
10849
+ var useControls = options.useControls;
10844
10850
 
10845
10851
  var audioState_;
10846
10852
  var videoState_;
@@ -11026,6 +11032,7 @@ var createSession = function (options) {
11026
11032
  remoteVideo: remoteVideo,
11027
11033
  playoutDelay: playoutDelay,
11028
11034
  unmutePlayOnStart: unmutePlayOnStart,
11035
+ useControls: useControls,
11029
11036
  logger: logger
11030
11037
  }, streamRefreshHandlers[id_]).then(function (newConnection) {
11031
11038
  mediaConnection = newConnection;
@@ -11115,6 +11122,7 @@ var createSession = function (options) {
11115
11122
  connectionConstraints: mediaConnectionConstraints,
11116
11123
  customStream: constraints && constraints.customStream ? constraints.customStream : false,
11117
11124
  videoContentHint: videoContentHint,
11125
+ useControls: useControls,
11118
11126
  logger: logger
11119
11127
  }).then(function (newConnection) {
11120
11128
  mediaConnection = newConnection;
@@ -13234,7 +13242,7 @@ const Browser = {
13234
13242
  return !!window.chrome && /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor) && !/OPR/.test(navigator.userAgent);
13235
13243
  },
13236
13244
  isEdge: function () {
13237
- return !isIE && !!window.StyleMedia;
13245
+ return !this.isIE() && !!window.StyleMedia;
13238
13246
  },
13239
13247
  isOpera: function () {
13240
13248
  return (!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
@@ -13260,6 +13268,33 @@ const Browser = {
13260
13268
  },
13261
13269
  isChromiumEdge: function () {
13262
13270
  return /Chrome/i.test(navigator.userAgent) && /Edg/i.test(navigator.userAgent);
13271
+ },
13272
+ version: function () {
13273
+ var version = navigator.userAgent.match(/version\/(\d+)/i);
13274
+ if (version) {
13275
+ return version[1];
13276
+ } else {
13277
+ if (this.isEdge()) {
13278
+ version = /\brv[ :]+(\d+)/g.exec(navigator.userAgent) || [];
13279
+ }
13280
+ if (this.isOpera()) {
13281
+ version = navigator.userAgent.match(/\b(OPR)\/(\d+)/) || [];
13282
+ }
13283
+ if (this.isChromiumEdge()) {
13284
+ version = navigator.userAgent.match(/\b(Edg)\/(\d+)/) || [];
13285
+ }
13286
+ if (this.isSamsungBrowser()) {
13287
+ version = navigator.userAgent.match(/\b(SamsungBrowser)\/(\d+)/) || [];
13288
+ }
13289
+ if (this.isChrome()) {
13290
+ version = navigator.userAgent.match(/\b(Chrome)\/(\d+)/) || [];
13291
+ }
13292
+ if (this.isFirefox()) {
13293
+ version = navigator.userAgent.match(/\b(Firefox)\/(\d+)/) || [];
13294
+ }
13295
+ return version[2] || 0;
13296
+ }
13297
+ return 0;
13263
13298
  }
13264
13299
  };
13265
13300
 
@@ -13526,6 +13561,16 @@ const getCurrentCodecAndSampleRate = function(sdp, mediaType) {
13526
13561
  return ret;
13527
13562
  };
13528
13563
 
13564
+ const isPromise = function(object) {
13565
+ if (object !== null &&
13566
+ typeof object === 'object' &&
13567
+ typeof object.then === 'function' &&
13568
+ typeof object.catch === 'function') {
13569
+ return true;
13570
+ }
13571
+
13572
+ return false;
13573
+ };
13529
13574
 
13530
13575
  module.exports = {
13531
13576
  isEmptyObject,
@@ -13536,11 +13581,12 @@ module.exports = {
13536
13581
  SDP,
13537
13582
  logger,
13538
13583
  stripCodecs,
13539
- getCurrentCodecAndSampleRate
13584
+ getCurrentCodecAndSampleRate,
13585
+ isPromise
13540
13586
  };
13541
13587
 
13542
13588
  },{}],45:[function(require,module,exports){
13543
- 'use strict';
13589
+ -'use strict';
13544
13590
 
13545
13591
  var browserDetails = require('webrtc-adapter').default.browserDetails;
13546
13592
  const { v1: uuid_v1 } = require('uuid');
@@ -13601,6 +13647,8 @@ var createConnection = function (options) {
13601
13647
  var videoContentHint = options.videoContentHint ? options.videoContentHint : 'detail';
13602
13648
  // Pass the option to unmute automatically (true by default) #WCS-2425
13603
13649
  var unmutePlayOnStart = options.unmutePlayOnStart !== undefined ? options.unmutePlayOnStart : true;
13650
+ // Use a standard HTML5 video controls if needed (to enable fullscreen in Safari 16 for example) #WCS-3606
13651
+ var useControls = options.useControls || false;
13604
13652
 
13605
13653
  if (bidirectional) {
13606
13654
  localVideo = getCacheInstance(localDisplay);
@@ -13616,7 +13664,7 @@ var createConnection = function (options) {
13616
13664
  }
13617
13665
  remoteVideo = getCacheInstance(remoteDisplay);
13618
13666
  if (!remoteVideo) {
13619
- remoteVideo = createVideoElement();
13667
+ remoteVideo = createVideoElement(useControls);
13620
13668
  remoteDisplay.appendChild(remoteVideo);
13621
13669
  }
13622
13670
  remoteVideo.id = id + "-remote";
@@ -13637,7 +13685,7 @@ var createConnection = function (options) {
13637
13685
  if (cachedVideo) {
13638
13686
  remoteVideo = cachedVideo;
13639
13687
  } else {
13640
- remoteVideo = createVideoElement();
13688
+ remoteVideo = createVideoElement(useControls);
13641
13689
  display.appendChild(remoteVideo);
13642
13690
  }
13643
13691
  remoteVideo.id = id;
@@ -13655,9 +13703,18 @@ var createConnection = function (options) {
13655
13703
  setContentHint(localVideo.srcObject, videoContentHint);
13656
13704
  connection.addStream(localVideo.srcObject);
13657
13705
  }
13706
+ } else {
13707
+ // There is a custom video element, get its id if set #WCS-3606
13708
+ if (remoteVideo.id) {
13709
+ id = remoteVideo.id;
13710
+ }
13658
13711
  }
13659
13712
  }
13660
13713
  if (localVideo) {
13714
+ // Enable local video controls if option requires #WCS-3606
13715
+ if (useControls) {
13716
+ enableVideoControls(localVideo);
13717
+ }
13661
13718
  var videoTrack = localVideo.srcObject.getVideoTracks()[0];
13662
13719
  if (videoTrack) {
13663
13720
  videoCams.forEach((cam, index) => {
@@ -13675,6 +13732,12 @@ var createConnection = function (options) {
13675
13732
  });
13676
13733
  }
13677
13734
  }
13735
+ if (remoteVideo) {
13736
+ // Enable remote video controls if option requires #WCS-3606
13737
+ if (useControls) {
13738
+ enableVideoControls(remoteVideo);
13739
+ }
13740
+ }
13678
13741
  function setContentHint(stream, hint) {
13679
13742
  stream.getVideoTracks().forEach(function(track) {
13680
13743
  if(track.contentHint === undefined) {
@@ -14022,7 +14085,13 @@ var createConnection = function (options) {
14022
14085
  if (!document.fullscreenElement && !document.mozFullScreenElement &&
14023
14086
  !document.webkitFullscreenElement && !document.msFullscreenElement) {
14024
14087
  if (video.requestFullscreen) {
14025
- video.requestFullscreen();
14088
+ var result = video.requestFullscreen();
14089
+ // Chromium based browsers return a promise which is rejected although user click is present #WCS-3606
14090
+ if (util.isPromise(result)) {
14091
+ result.catch(function(e) {
14092
+ logger.debug(LOG_PREFIX, e);
14093
+ });
14094
+ }
14026
14095
  } else if (video.msRequestFullscreen) {
14027
14096
  video.msRequestFullscreen();
14028
14097
  } else if (video.mozRequestFullScreen) {
@@ -14031,10 +14100,18 @@ var createConnection = function (options) {
14031
14100
  video.webkitRequestFullscreen();
14032
14101
  } else if (video.webkitEnterFullscreen) {
14033
14102
  video.webkitEnterFullscreen();
14034
- //hack for iOS safari. Video is getting paused when switching from fullscreen to normal mode.
14103
+ // iOS (all versions)/MacOS (since 15) Safari hack: video is paused when leaving fullscreen mode #WCS-3606
14104
+ var needRestart = false;
14035
14105
  video.addEventListener("pause", function () {
14036
- video.play();
14106
+ if(needRestart) {
14107
+ video.play();
14108
+ needRestart = false;
14109
+ }
14037
14110
  });
14111
+ video.addEventListener("webkitendfullscreen", function () {
14112
+ video.play();
14113
+ needRestart = true;
14114
+ });
14038
14115
  }
14039
14116
  } else {
14040
14117
  if (document.exitFullscreen) {
@@ -14410,7 +14487,9 @@ var loadOrdinaryVideo = function(display, stream, screenShare, constraints, vide
14410
14487
  vEl = createVideoElement();
14411
14488
  display.appendChild(vEl);
14412
14489
  }
14413
- vEl.id = uuid_v1() + LOCAL_CACHED_VIDEO;
14490
+ if (!vEl.id) {
14491
+ vEl.id = uuid_v1() + LOCAL_CACHED_VIDEO;
14492
+ }
14414
14493
  vEl.srcObject = stream;
14415
14494
  vEl.onloadedmetadata = function (e) {
14416
14495
  //WCS-2751 Add screen capture using getDisplayMedia in Safari
@@ -14438,7 +14517,9 @@ var loadCanvasVideo = function (display, stream, video) {
14438
14517
  vEl = canvas;
14439
14518
  }
14440
14519
  }
14441
- vEl.id = uuid_v1() + LOCAL_CACHED_VIDEO;
14520
+ if (!vEl.id) {
14521
+ vEl.id = uuid_v1() + LOCAL_CACHED_VIDEO;
14522
+ }
14442
14523
 
14443
14524
  let child = vEl.children[0];
14444
14525
  child.srcObject = stream;
@@ -14745,13 +14826,16 @@ function getCacheInstance(display) {
14745
14826
  }
14746
14827
  }
14747
14828
 
14748
- function createVideoElement() {
14829
+ function createVideoElement(useControls = false) {
14749
14830
  let video = document.createElement('video');
14750
14831
  // Prepare video tag to auto play and add specific Safari tweaks #WCS-2425
14751
14832
  video.muted = true;
14752
- if(util.Browser.isSafariWebRTC()) {
14753
- video.setAttribute("playsinline", "");
14754
- video.setAttribute("webkit-playsinline", "");
14833
+ if (util.Browser.isSafariWebRTC()) {
14834
+ video.setAttribute("playsinline", "");
14835
+ video.setAttribute("webkit-playsinline", "");
14836
+ }
14837
+ if (useControls) {
14838
+ enableVideoControls(video);
14755
14839
  }
14756
14840
  return(video);
14757
14841
  }
@@ -14777,6 +14861,12 @@ function removeVideoElement(video) {
14777
14861
  }
14778
14862
  }
14779
14863
 
14864
+ function enableVideoControls(video) {
14865
+ if(video && !video.controls) {
14866
+ video.setAttribute("controls", "controls");
14867
+ }
14868
+ }
14869
+
14780
14870
  /**
14781
14871
  * Check WebRTC available
14782
14872
  *
@@ -14947,12 +15037,10 @@ var playFirstSound = function () {
14947
15037
  return false;
14948
15038
  };
14949
15039
 
14950
- var playFirstVideo = function (display, isLocal, src) {
15040
+ var playFirstVideo = function (display, isLocal, src, useControls = false) {
14951
15041
  return new Promise(function (resolve, reject) {
14952
15042
  if (!getCacheInstance(display)) {
14953
- var video = document.createElement('video');
14954
- video.setAttribute("playsinline", "");
14955
- video.setAttribute("webkit-playsinline", "");
15043
+ var video = createVideoElement(useControls);
14956
15044
  //Mute video tag to prevent local audio playback in Safari #WCS-3430
14957
15045
  video.muted = true;
14958
15046
  video.id = uuid_v1() + (isLocal ? LOCAL_CACHED_VIDEO : REMOTE_CACHED_VIDEO);
@@ -14963,6 +15051,7 @@ var playFirstVideo = function (display, isLocal, src) {
14963
15051
  video.src = src;
14964
15052
  video.play().then(function () {
14965
15053
  display.appendChild(video);
15054
+ video.removeAttribute("src");
14966
15055
  resolve();
14967
15056
  }).catch(function () {
14968
15057
  //WCS-2375. fixed autoplay in ios safari
@@ -14970,6 +15059,7 @@ var playFirstVideo = function (display, isLocal, src) {
14970
15059
  video.muted = true;
14971
15060
  video.play().then(function () {
14972
15061
  display.appendChild(video);
15062
+ video.removeAttribute("src");
14973
15063
  resolve();
14974
15064
  });
14975
15065
  //WCS-2375. low power mode suspends video play