@whereby.com/browser-sdk 2.0.0-alpha15 → 2.0.0-alpha17

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/dist/lib.cjs CHANGED
@@ -150,7 +150,7 @@ heresy.define("WherebyEmbed", {
150
150
  if (roomUrl.searchParams.get("roomKey")) {
151
151
  this.url.searchParams.append("roomKey", roomUrl.searchParams.get("roomKey"));
152
152
  }
153
- Object.entries(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ jsApi: true, we: "2.0.0-alpha15", iframeSource: subdomain }, (displayName && { displayName })), (lang && { lang })), (metadata && { metadata })), (groups && { groups })), (virtualBackgroundUrl && { virtualBackgroundUrl })), (avatarUrl && { avatarUrl })), (minimal != null && { embed: minimal })), boolAttrs.reduce(
153
+ Object.entries(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ jsApi: true, we: "2.0.0-alpha17", iframeSource: subdomain }, (displayName && { displayName })), (lang && { lang })), (metadata && { metadata })), (groups && { groups })), (virtualBackgroundUrl && { virtualBackgroundUrl })), (avatarUrl && { avatarUrl })), (minimal != null && { embed: minimal })), boolAttrs.reduce(
154
154
  // add to URL if set in any way
155
155
  (o, v) => (this[v.toLowerCase()] != null ? Object.assign(Object.assign({}, o), { [v]: this[v.toLowerCase()] }) : o), {}))).forEach(([k, v]) => {
156
156
  if (!this.url.searchParams.has(k) && typeof v === "string") {
@@ -670,21 +670,21 @@ var rtcManagerEvents = {
670
670
  DOMINANT_SPEAKER: "dominant_speaker",
671
671
  };
672
672
 
673
- const browserName$3 = adapter__default["default"].browserDetails.browser;
673
+ const browserName$2 = adapter__default["default"].browserDetails.browser;
674
674
  const browserVersion$1 = adapter__default["default"].browserDetails.version;
675
675
 
676
676
  // SDP mangling for deprioritizing H264
677
677
  function deprioritizeH264(sdp) {
678
678
  return SDPUtils__default["default"].splitSections(sdp)
679
- .map((section) => {
679
+ .map(section => {
680
680
  // only modify video sections
681
681
  if (SDPUtils__default["default"].getKind(section) !== "video") return section;
682
682
 
683
683
  // list of payloadTypes used in this sdp/section
684
684
  const h264payloadTypes = SDPUtils__default["default"].matchPrefix(section, "a=rtpmap:")
685
- .map((line) => SDPUtils__default["default"].parseRtpMap(line))
686
- .filter((codec) => /h264/i.test(codec.name))
687
- .map((codec) => "" + codec.payloadType);
685
+ .map(line => SDPUtils__default["default"].parseRtpMap(line))
686
+ .filter(codec => /h264/i.test(codec.name))
687
+ .map(codec => "" + codec.payloadType);
688
688
 
689
689
  // return as is if no h264 found
690
690
  if (!h264payloadTypes.length) return section;
@@ -694,7 +694,7 @@ function deprioritizeH264(sdp) {
694
694
  const mlinePayloadsSection = /(\s\d+)+$/i.exec(mline)[0];
695
695
  const mlinePayloadsNonH264 = mlinePayloadsSection
696
696
  .split(" ")
697
- .filter((payloadType) => payloadType && !h264payloadTypes.includes(payloadType));
697
+ .filter(payloadType => payloadType && !h264payloadTypes.includes(payloadType));
698
698
  const reorderedPayloads = [...mlinePayloadsNonH264, ...h264payloadTypes].join(" ");
699
699
  const newmline = mline.replace(mlinePayloadsSection, " " + reorderedPayloads);
700
700
  return section.replace(mline, newmline);
@@ -722,12 +722,12 @@ function replaceSSRCs(currentDescription, newDescription) {
722
722
  // https://bugzilla.mozilla.org/show_bug.cgi?id=1478685
723
723
  // filter out the mid rtp header extension
724
724
  function filterMidExtension(sdp) {
725
- if (browserName$3 !== "safari" && (browserName$3 !== "firefox" || browserVersion$1 >= 63 || browserVersion$1 === 60)) {
725
+ if (browserName$2 !== "safari" && (browserName$2 !== "firefox" || browserVersion$1 >= 63 || browserVersion$1 === 60)) {
726
726
  return sdp;
727
727
  }
728
728
  return (
729
729
  SDPUtils__default["default"].splitLines(sdp.trim())
730
- .filter((line) => {
730
+ .filter(line => {
731
731
  if (!line.startsWith("a=extmap:")) {
732
732
  return true;
733
733
  }
@@ -743,21 +743,21 @@ function filterMidExtension(sdp) {
743
743
  // https://bugzilla.mozilla.org/show_bug.cgi?id=1534673
744
744
  // Filter out a:msid-semantic header
745
745
  function filterMsidSemantic(sdp) {
746
- if (browserName$3 !== "firefox") {
746
+ if (browserName$2 !== "firefox") {
747
747
  return sdp;
748
748
  }
749
749
  return (
750
750
  SDPUtils__default["default"].splitLines(sdp.trim())
751
- .map((line) => (line.startsWith("a=msid-semantic:") ? "a=msid-semantic: WMS *" : line))
751
+ .map(line => (line.startsWith("a=msid-semantic:") ? "a=msid-semantic: WMS *" : line))
752
752
  .join("\r\n") + "\r\n"
753
753
  );
754
754
  }
755
755
 
756
756
  function isRelayed(pc) {
757
- return pc.getStats(null).then((result) => {
757
+ return pc.getStats(null).then(result => {
758
758
  let localCandidateType;
759
759
  let remoteCandidateType;
760
- result.forEach((report) => {
760
+ result.forEach(report => {
761
761
  // Chrome 58+ / spec
762
762
  if (report.type === "transport" && report.selectedCandidatePairId) {
763
763
  const transport = result.get(report.selectedCandidatePairId);
@@ -787,7 +787,7 @@ const logger$4 = console;
787
787
 
788
788
  // use https://w3c.github.io/webrtc-pc/#dom-rtcrtpsender-setparameters to change the video bandwidth.
789
789
  function setVideoBandwidthUsingSetParameters(pc, bandwidth) {
790
- const sender = pc.getSenders().find((s) => s.track && s.track.kind === "video");
790
+ const sender = pc.getSenders().find(s => s.track && s.track.kind === "video");
791
791
  if (!sender) {
792
792
  return Promise.resolve();
793
793
  }
@@ -808,7 +808,7 @@ function setVideoBandwidthUsingSetParameters(pc, bandwidth) {
808
808
  parameters.encodings[0].maxBitrate = bandwidth * 1000; // convert to bps
809
809
  }
810
810
 
811
- return sender.setParameters(parameters).catch((err) => {
811
+ return sender.setParameters(parameters).catch(err => {
812
812
  logger$4.error("setParameters err: ", err);
813
813
  });
814
814
  }
@@ -833,7 +833,7 @@ class Session {
833
833
  this.streamIds = [];
834
834
  this.streams = [];
835
835
  this.earlyIceCandidates = [];
836
- this.afterConnected = new Promise((resolve) => {
836
+ this.afterConnected = new Promise(resolve => {
837
837
  this.registerConnected = resolve;
838
838
  });
839
839
  this.offerOptions = { offerToReceiveAudio: true, offerToReceiveVideo: true };
@@ -870,10 +870,10 @@ class Session {
870
870
  this.streamIds.push(stream.id);
871
871
  this.streams.push(stream);
872
872
  if (RTCPeerConnection.prototype.addTrack) {
873
- stream.getAudioTracks().forEach((track) => {
873
+ stream.getAudioTracks().forEach(track => {
874
874
  this.pc.addTrack(track, stream);
875
875
  });
876
- stream.getVideoTracks().forEach((track) => {
876
+ stream.getVideoTracks().forEach(track => {
877
877
  this.pc.addTrack(track, stream);
878
878
  });
879
879
  } else {
@@ -893,7 +893,7 @@ class Session {
893
893
  removeTrack(track) {
894
894
  const stream = this.streams[0];
895
895
  stream.removeTrack(track);
896
- const sender = this.pc.getSenders().find((sender) => sender.track === track);
896
+ const sender = this.pc.getSenders().find(sender => sender.track === track);
897
897
  if (sender) {
898
898
  this.pc.removeTrack(sender);
899
899
  }
@@ -909,8 +909,8 @@ class Session {
909
909
 
910
910
  if (this.pc) {
911
911
  if (this.pc.removeTrack) {
912
- stream.getTracks().forEach((track) => {
913
- const sender = this.pc.getSenders().find((sender) => sender.track === track);
912
+ stream.getTracks().forEach(track => {
913
+ const sender = this.pc.getSenders().find(sender => sender.track === track);
914
914
  if (sender) {
915
915
  this.pc.removeTrack(sender);
916
916
  }
@@ -928,14 +928,14 @@ class Session {
928
928
  // wrapper around SRD which stores a promise
929
929
  this.srdComplete = this.pc.setRemoteDescription(desc);
930
930
  return this.srdComplete.then(() => {
931
- this.earlyIceCandidates.forEach((candidate) => this.pc.addIceCandidate(candidate));
931
+ this.earlyIceCandidates.forEach(candidate => this.pc.addIceCandidate(candidate));
932
932
  this.earlyIceCandidates = [];
933
933
  });
934
934
  }
935
935
 
936
936
  handleOffer(message) {
937
937
  if (!this.canModifyPeerConnection()) {
938
- return new Promise((resolve) => {
938
+ return new Promise(resolve => {
939
939
  this.pending.push(() => this.handleOffer(message).then(resolve));
940
940
  });
941
941
  }
@@ -953,7 +953,7 @@ class Session {
953
953
  .then(() => {
954
954
  return this.pc.createAnswer();
955
955
  })
956
- .then((answer) => {
956
+ .then(answer => {
957
957
  answerToSignal = answer;
958
958
  return this.pc.setLocalDescription(answer);
959
959
  })
@@ -981,7 +981,7 @@ class Session {
981
981
  () => {
982
982
  return setVideoBandwidthUsingSetParameters(this.pc, this.bandwidth);
983
983
  },
984
- (e) => {
984
+ e => {
985
985
  logger$3.warn("Could not set remote description from remote answer: ", e);
986
986
  }
987
987
  );
@@ -1002,7 +1002,7 @@ class Session {
1002
1002
  // filter due to https://github.com/webrtcHacks/adapter/issues/863
1003
1003
  return;
1004
1004
  }
1005
- this.pc.addIceCandidate(candidate).catch((e) => {
1005
+ this.pc.addIceCandidate(candidate).catch(e => {
1006
1006
  logger$3.warn("Failed to add ICE candidate ('%s'): %s", candidate ? candidate.candidate : null, e);
1007
1007
  });
1008
1008
  });
@@ -1040,11 +1040,11 @@ class Session {
1040
1040
  if (!pc) return false;
1041
1041
  const senders = pc.getSenders();
1042
1042
  function dbg(msg) {
1043
- const tr = (t) => t && `id:${t.id},kind:${t.kind},state:${t.readyState}`;
1043
+ const tr = t => t && `id:${t.id},kind:${t.kind},state:${t.readyState}`;
1044
1044
  logger$3.warn(
1045
1045
  `${msg}. newTrack:${tr(newTrack)}, oldTrack:${tr(oldTrack)}, sender tracks: ${JSON.stringify(
1046
- senders.map((s) => `s ${tr(s.track)}`)
1047
- )}, sender first codecs: ${JSON.stringify(senders.map((s) => (s.getParameters().codecs || [])[0]))}`
1046
+ senders.map(s => `s ${tr(s.track)}`)
1047
+ )}, sender first codecs: ${JSON.stringify(senders.map(s => (s.getParameters().codecs || [])[0]))}`
1048
1048
  );
1049
1049
  }
1050
1050
  if (!senders.length) {
@@ -1052,7 +1052,7 @@ class Session {
1052
1052
  }
1053
1053
  // If we didn't specify oldTrack, replace with first of its kind
1054
1054
  if (!oldTrack) {
1055
- oldTrack = (senders.find((s) => s.track && s.track.kind === newTrack.kind) || {}).track;
1055
+ oldTrack = (senders.find(s => s.track && s.track.kind === newTrack.kind) || {}).track;
1056
1056
  if (!oldTrack) {
1057
1057
  // odin: Temporary debug data, remove if you see after 2020-12-01
1058
1058
  dbg("No sender with same kind! Add new track then.");
@@ -1109,7 +1109,7 @@ class Session {
1109
1109
  // we already know that the track has been added at least to the mediastream
1110
1110
  return result;
1111
1111
  }
1112
- const stream = this.streams.find((s) => s.getTracks().find((t) => t.id === newTrack.id)) || this.streams[0];
1112
+ const stream = this.streams.find(s => s.getTracks().find(t => t.id === newTrack.id)) || this.streams[0];
1113
1113
  if (!stream) {
1114
1114
  dbg("No stream?");
1115
1115
  return Promise.reject(new Error("replaceTrack: No stream?"));
@@ -1138,7 +1138,7 @@ class Session {
1138
1138
  if (pc.localDescription.type === "offer") {
1139
1139
  return pc
1140
1140
  .createOffer()
1141
- .then((offer) => {
1141
+ .then(offer => {
1142
1142
  offer.sdp = replaceSSRCs(pc.localDescription.sdp, offer.sdp);
1143
1143
  return pc.setLocalDescription(offer);
1144
1144
  })
@@ -1150,7 +1150,7 @@ class Session {
1150
1150
  .then(() => {
1151
1151
  return pc.createAnswer();
1152
1152
  })
1153
- .then((answer) => {
1153
+ .then(answer => {
1154
1154
  answer.sdp = replaceSSRCs(pc.localDescription.sdp, answer.sdp);
1155
1155
  return pc.setLocalDescription(answer);
1156
1156
  });
@@ -1165,7 +1165,7 @@ class Session {
1165
1165
  if (!this.pc.getStats) {
1166
1166
  return;
1167
1167
  }
1168
- isRelayed(this.pc).then((isRelayed) => {
1168
+ isRelayed(this.pc).then(isRelayed => {
1169
1169
  if (isRelayed && this.bandwidth === 0) {
1170
1170
  this.changeBandwidth(this.maximumTurnBandwidth);
1171
1171
  }
@@ -4261,7 +4261,7 @@ const CAMERA_STREAM_ID = "0";
4261
4261
 
4262
4262
  const logger$2 = console;
4263
4263
 
4264
- const browserName$2 = adapter__default["default"].browserDetails.browser;
4264
+ const browserName$1 = adapter__default["default"].browserDetails.browser;
4265
4265
  const browserVersion = adapter__default["default"].browserDetails.version;
4266
4266
 
4267
4267
  class BaseRtcManager {
@@ -4301,7 +4301,7 @@ class BaseRtcManager {
4301
4301
  }
4302
4302
 
4303
4303
  numberOfRemotePeers() {
4304
- return Object.values(this.peerConnections).filter((session) => session.clientId !== this._selfId).length;
4304
+ return Object.values(this.peerConnections).filter(session => session.clientId !== this._selfId).length;
4305
4305
  }
4306
4306
 
4307
4307
  _setConnectionStatus(session, newStatus, clientId) {
@@ -4375,7 +4375,7 @@ class BaseRtcManager {
4375
4375
  // Some macs + ios devices have troubles using h264 encoder since safari 14
4376
4376
  // this will make them encode VP8 instead if available
4377
4377
  const deprioritizeH264Encoding =
4378
- browserName$2 === "safari" && browserVersion >= 14 && this._features.deprioritizeH264OnSafari;
4378
+ browserName$1 === "safari" && browserVersion >= 14 && this._features.deprioritizeH264OnSafari;
4379
4379
 
4380
4380
  this.peerConnections[peerConnectionId] = session = new Session({
4381
4381
  peerConnectionId,
@@ -4394,7 +4394,7 @@ class BaseRtcManager {
4394
4394
  }
4395
4395
 
4396
4396
  _getNonLocalCameraStreamIds() {
4397
- return Object.keys(this.localStreams).filter((streamId) => streamId !== CAMERA_STREAM_ID);
4397
+ return Object.keys(this.localStreams).filter(streamId => streamId !== CAMERA_STREAM_ID);
4398
4398
  }
4399
4399
 
4400
4400
  _isScreensharingLocally() {
@@ -4423,7 +4423,7 @@ class BaseRtcManager {
4423
4423
  }
4424
4424
  const session = this._getOrCreateSession(peerConnectionId, initialBandwidth);
4425
4425
  const constraints = { optional: [] };
4426
- if (browserName$2 === "chrome") {
4426
+ if (browserName$1 === "chrome") {
4427
4427
  constraints.optional.push({
4428
4428
  googCpuOveruseDetection: true,
4429
4429
  });
@@ -4436,13 +4436,13 @@ class BaseRtcManager {
4436
4436
  const host = this._features.turnServerOverrideHost;
4437
4437
  const port = host.indexOf(":") > 0 ? "" : ":443";
4438
4438
  const override = ":" + host + port;
4439
- peerConnectionConfig.iceServers = peerConnectionConfig.iceServers.map((original) => {
4439
+ peerConnectionConfig.iceServers = peerConnectionConfig.iceServers.map(original => {
4440
4440
  const entry = Object.assign({}, original);
4441
4441
  if (entry.url) {
4442
4442
  entry.url = entry.url.replace(/:[^?]*/, override);
4443
4443
  }
4444
4444
  if (entry.urls) {
4445
- entry.urls = entry.urls.map((url) => url.replace(/:[^?]*/, override));
4445
+ entry.urls = entry.urls.map(url => url.replace(/:[^?]*/, override));
4446
4446
  }
4447
4447
  return entry;
4448
4448
  });
@@ -4456,12 +4456,12 @@ class BaseRtcManager {
4456
4456
  }[this._features.useOnlyTURN];
4457
4457
  if (filter) {
4458
4458
  peerConnectionConfig.iceServers = peerConnectionConfig.iceServers.filter(
4459
- (entry) => entry.url && entry.url.match(filter)
4459
+ entry => entry.url && entry.url.match(filter)
4460
4460
  );
4461
4461
  }
4462
4462
  }
4463
4463
 
4464
- if (browserName$2 === "chrome") {
4464
+ if (browserName$1 === "chrome") {
4465
4465
  peerConnectionConfig.sdpSemantics = "unified-plan";
4466
4466
  }
4467
4467
 
@@ -4472,7 +4472,7 @@ class BaseRtcManager {
4472
4472
  clientId,
4473
4473
  });
4474
4474
 
4475
- pc.ontrack = (event) => {
4475
+ pc.ontrack = event => {
4476
4476
  const stream = event.streams[0];
4477
4477
  if (stream.id === "default" && stream.getAudioTracks().length === 0) {
4478
4478
  // due to our PlanB / UnifiedPlan conversion we can run into this:
@@ -4514,7 +4514,7 @@ class BaseRtcManager {
4514
4514
  case "completed":
4515
4515
  newStatus = TYPES.CONNECTION_SUCCESSFUL;
4516
4516
  if (!session.wasEverConnected) {
4517
- this._pendingActionsForConnectedPeerConnections.forEach((action) => {
4517
+ this._pendingActionsForConnectedPeerConnections.forEach(action => {
4518
4518
  if (typeof action === "function") {
4519
4519
  action();
4520
4520
  }
@@ -4526,7 +4526,7 @@ class BaseRtcManager {
4526
4526
  if (
4527
4527
  !session.wasEverConnected &&
4528
4528
  (pc.iceConnectionState.match(/connected|completed/) ||
4529
- (browserName$2 === "chrome" && pc.localDescription && pc.localDescription.type === "answer"))
4529
+ (browserName$1 === "chrome" && pc.localDescription && pc.localDescription.type === "answer"))
4530
4530
  ) {
4531
4531
  session.wasEverConnected = true;
4532
4532
  if (this._features.bandwidth !== "false") {
@@ -4597,7 +4597,7 @@ class BaseRtcManager {
4597
4597
  // Don't add existing screenshare-streams when using SFU as those will be
4598
4598
  // added in a separate session/peerConnection
4599
4599
  if (shouldAddLocalVideo) {
4600
- Object.keys(this.localStreams).forEach((id) => {
4600
+ Object.keys(this.localStreams).forEach(id => {
4601
4601
  if (id === CAMERA_STREAM_ID) {
4602
4602
  return;
4603
4603
  }
@@ -4634,27 +4634,27 @@ class BaseRtcManager {
4634
4634
  }
4635
4635
 
4636
4636
  _forEachPeerConnection(func) {
4637
- Object.keys(this.peerConnections).forEach((peerConnectionId) => {
4637
+ Object.keys(this.peerConnections).forEach(peerConnectionId => {
4638
4638
  const peerConnection = this.peerConnections[peerConnectionId];
4639
4639
  func(peerConnection);
4640
4640
  });
4641
4641
  }
4642
4642
 
4643
4643
  _addStreamToPeerConnections(stream) {
4644
- this._forEachPeerConnection((session) => {
4644
+ this._forEachPeerConnection(session => {
4645
4645
  this._withForcedRenegotiation(session, () => session.addStream(stream));
4646
4646
  });
4647
4647
  }
4648
4648
 
4649
4649
  _addTrackToPeerConnections(track, stream) {
4650
- this._forEachPeerConnection((session) => {
4650
+ this._forEachPeerConnection(session => {
4651
4651
  this._withForcedRenegotiation(session, () => session.addTrack(track, stream));
4652
4652
  });
4653
4653
  }
4654
4654
 
4655
4655
  _replaceTrackToPeerConnections(oldTrack, newTrack) {
4656
4656
  const promises = [];
4657
- this._forEachPeerConnection((session) => {
4657
+ this._forEachPeerConnection(session => {
4658
4658
  if (!session.hasConnectedPeerConnection()) {
4659
4659
  logger$2.log("Session doesn't have a connected PeerConnection, adding pending action!");
4660
4660
  const pendingActions = this._pendingActionsForConnectedPeerConnections;
@@ -4672,7 +4672,7 @@ class BaseRtcManager {
4672
4672
  reject(`ReplaceTrack returned false`);
4673
4673
  return;
4674
4674
  }
4675
- replacedTrackPromise.then((track) => resolve(track)).catch((error) => reject(error));
4675
+ replacedTrackPromise.then(track => resolve(track)).catch(error => reject(error));
4676
4676
  };
4677
4677
  pendingActions.push(action);
4678
4678
  });
@@ -4690,13 +4690,13 @@ class BaseRtcManager {
4690
4690
  }
4691
4691
 
4692
4692
  _removeStreamFromPeerConnections(stream) {
4693
- this._forEachPeerConnection((session) => {
4693
+ this._forEachPeerConnection(session => {
4694
4694
  this._withForcedRenegotiation(session, () => session.removeStream(stream));
4695
4695
  });
4696
4696
  }
4697
4697
 
4698
4698
  _removeTrackFromPeerConnections(track) {
4699
- this._forEachPeerConnection((session) => {
4699
+ this._forEachPeerConnection(session => {
4700
4700
  this._withForcedRenegotiation(session, () => session.removeTrack(track));
4701
4701
  });
4702
4702
  }
@@ -4749,11 +4749,11 @@ class BaseRtcManager {
4749
4749
  }
4750
4750
 
4751
4751
  disconnectAll() {
4752
- Object.keys(this.peerConnections).forEach((peerConnectionId) => {
4752
+ Object.keys(this.peerConnections).forEach(peerConnectionId => {
4753
4753
  this.disconnect(peerConnectionId);
4754
4754
  });
4755
4755
  this.peerConnections = {};
4756
- this._socketListenerDeregisterFunctions.forEach((func) => {
4756
+ this._socketListenerDeregisterFunctions.forEach(func => {
4757
4757
  func();
4758
4758
  });
4759
4759
  this._socketListenerDeregisterFunctions = [];
@@ -4770,7 +4770,7 @@ class BaseRtcManager {
4770
4770
  * used in getUserMedia.
4771
4771
  */
4772
4772
  fixChromeAudio(constraints) {
4773
- if (browserName$2 !== "chrome") {
4773
+ if (browserName$1 !== "chrome") {
4774
4774
  return;
4775
4775
  }
4776
4776
  const localStream = this._getLocalCameraStream();
@@ -4778,7 +4778,7 @@ class BaseRtcManager {
4778
4778
  if (!audioTrack || audioTrack.readyState !== "ended") {
4779
4779
  return;
4780
4780
  }
4781
- return navigator.mediaDevices.getUserMedia({ audio: constraints }).then((stream) => {
4781
+ return navigator.mediaDevices.getUserMedia({ audio: constraints }).then(stream => {
4782
4782
  const track = stream.getAudioTracks()[0];
4783
4783
  track.enabled = audioTrack.enabled; // retain mute state and don't accidentally unmute.
4784
4784
  localStream.removeTrack(audioTrack); // remove the old track.
@@ -4812,7 +4812,7 @@ class BaseRtcManager {
4812
4812
  this._socketListenerDeregisterFunctions = [
4813
4813
  () => this._clearMediaServersRefresh(),
4814
4814
 
4815
- this._serverSocket.on(PROTOCOL_RESPONSES.MEDIASERVER_CONFIG, (data) => {
4815
+ this._serverSocket.on(PROTOCOL_RESPONSES.MEDIASERVER_CONFIG, data => {
4816
4816
  if (data.error) {
4817
4817
  logger$2.warn("FETCH_MEDIASERVER_CONFIG failed:", data.error);
4818
4818
  return;
@@ -4820,11 +4820,11 @@ class BaseRtcManager {
4820
4820
  this._updateAndScheduleMediaServersRefresh(data);
4821
4821
  }),
4822
4822
 
4823
- this._serverSocket.on(RELAY_MESSAGES.READY_TO_RECEIVE_OFFER, (data) => {
4823
+ this._serverSocket.on(RELAY_MESSAGES.READY_TO_RECEIVE_OFFER, data => {
4824
4824
  this._connect(data.clientId);
4825
4825
  }),
4826
4826
 
4827
- this._serverSocket.on(RELAY_MESSAGES.ICE_CANDIDATE, (data) => {
4827
+ this._serverSocket.on(RELAY_MESSAGES.ICE_CANDIDATE, data => {
4828
4828
  const session = this._getSession(data.clientId);
4829
4829
  if (!session) {
4830
4830
  logger$2.warn("No RTCPeerConnection on ICE_CANDIDATE", data);
@@ -4833,7 +4833,7 @@ class BaseRtcManager {
4833
4833
  session.addIceCandidate(data.message);
4834
4834
  }),
4835
4835
 
4836
- this._serverSocket.on(RELAY_MESSAGES.ICE_END_OF_CANDIDATES, (data) => {
4836
+ this._serverSocket.on(RELAY_MESSAGES.ICE_END_OF_CANDIDATES, data => {
4837
4837
  const session = this._getSession(data.clientId);
4838
4838
  if (!session) {
4839
4839
  logger$2.warn("No RTCPeerConnection on ICE_END_OF_CANDIDATES", data);
@@ -4843,14 +4843,14 @@ class BaseRtcManager {
4843
4843
  }),
4844
4844
 
4845
4845
  // when a new SDP offer is received from another client
4846
- this._serverSocket.on(RELAY_MESSAGES.SDP_OFFER, (data) => {
4846
+ this._serverSocket.on(RELAY_MESSAGES.SDP_OFFER, data => {
4847
4847
  const session = this._getSession(data.clientId);
4848
4848
  if (!session) {
4849
4849
  logger$2.warn("No RTCPeerConnection on SDP_OFFER", data);
4850
4850
  return;
4851
4851
  }
4852
4852
  const offer = this._transformIncomingSdp(data.message, session.pc);
4853
- session.handleOffer(offer).then((answer) => {
4853
+ session.handleOffer(offer).then(answer => {
4854
4854
  this._emitServerEvent(RELAY_MESSAGES.SDP_ANSWER, {
4855
4855
  receiverId: data.clientId,
4856
4856
  message: this._transformOutgoingSdp(answer),
@@ -4859,7 +4859,7 @@ class BaseRtcManager {
4859
4859
  }),
4860
4860
 
4861
4861
  // when a new SDP answer is received from another client
4862
- this._serverSocket.on(RELAY_MESSAGES.SDP_ANSWER, (data) => {
4862
+ this._serverSocket.on(RELAY_MESSAGES.SDP_ANSWER, data => {
4863
4863
  const session = this._getSession(data.clientId);
4864
4864
  if (!session) {
4865
4865
  logger$2.warn("No RTCPeerConnection on SDP_ANSWER", data);
@@ -4877,7 +4877,7 @@ class BaseRtcManager {
4877
4877
  }
4878
4878
 
4879
4879
  const logger$1 = console;
4880
- const browserName$1 = adapter__default["default"].browserDetails.browser;
4880
+ const browserName = adapter__default["default"].browserDetails.browser;
4881
4881
  class P2pRtcManager extends BaseRtcManager {
4882
4882
  _connect(clientId) {
4883
4883
  const shouldAddLocalVideo = true;
@@ -4929,7 +4929,7 @@ class P2pRtcManager extends BaseRtcManager {
4929
4929
  session.isOperationPending = true;
4930
4930
 
4931
4931
  pc.createOffer(constraints || this.offerOptions)
4932
- .then((offer) => {
4932
+ .then(offer => {
4933
4933
  this._emitServerEvent(RELAY_MESSAGES.SDP_OFFER, {
4934
4934
  receiverId: clientId,
4935
4935
  message: this._transformOutgoingSdp(offer),
@@ -4938,17 +4938,17 @@ class P2pRtcManager extends BaseRtcManager {
4938
4938
  // workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=1394602
4939
4939
  // make Chrome send media later when there are two (more more?) video tracks.
4940
4940
  if (
4941
- browserName$1 === "chrome" &&
4942
- pc.getSenders().filter((sender) => sender.track && sender.track.kind === "video").length >= 2
4941
+ browserName === "chrome" &&
4942
+ pc.getSenders().filter(sender => sender.track && sender.track.kind === "video").length >= 2
4943
4943
  ) {
4944
4944
  session.pendingOffer = offer;
4945
4945
  return;
4946
4946
  }
4947
- pc.setLocalDescription(offer).catch((e) => {
4947
+ pc.setLocalDescription(offer).catch(e => {
4948
4948
  logger$1.warn("RTCPeerConnection.setLocalDescription() failed with local offer", e);
4949
4949
  });
4950
4950
  })
4951
- .catch((e) => {
4951
+ .catch(e => {
4952
4952
  logger$1.warn("RTCPeerConnection.createOffer() failed to create local offer", e);
4953
4953
  });
4954
4954
  }
@@ -4998,7 +4998,7 @@ class P2pRtcManager extends BaseRtcManager {
4998
4998
  return 0;
4999
4999
  }
5000
5000
 
5001
- this._forEachPeerConnection((session) => {
5001
+ this._forEachPeerConnection(session => {
5002
5002
  session.changeBandwidth(bandwidth);
5003
5003
  });
5004
5004
 
@@ -5029,7 +5029,7 @@ class P2pRtcManager extends BaseRtcManager {
5029
5029
  pc.addTrack(this._stoppedVideoTrack, localCameraStream);
5030
5030
  }
5031
5031
 
5032
- pc.onicecandidate = (event) => {
5032
+ pc.onicecandidate = event => {
5033
5033
  if (event.candidate) {
5034
5034
  session.relayCandidateSeen = session.relayCandidateSeen || event.candidate.type === "relay";
5035
5035
  this._emitServerEvent(RELAY_MESSAGES.ICE_CANDIDATE, {
@@ -5086,7 +5086,7 @@ class P2pRtcManager extends BaseRtcManager {
5086
5086
  const numPeers = this.numberOfPeerconnections();
5087
5087
  if (numPeers === 0) {
5088
5088
  setTimeout(() => {
5089
- this.numberOfPeerconnections();
5089
+ //const numPeers = this.numberOfPeerconnections();
5090
5090
  }, 60 * 1000);
5091
5091
  }
5092
5092
  }
@@ -5100,13 +5100,13 @@ class P2pRtcManager extends BaseRtcManager {
5100
5100
 
5101
5101
  stopOrResumeVideo(localStream, enable) {
5102
5102
  // actually turn off the camera. Chrome-only (Firefox has different plans)
5103
- if (browserName$1 !== "chrome") {
5103
+ if (browserName !== "chrome") {
5104
5104
  return;
5105
5105
  }
5106
5106
  if (enable === false) {
5107
5107
  // try to stop the local camera so the camera light goes off.
5108
5108
  setTimeout(() => {
5109
- localStream.getVideoTracks().forEach((track) => {
5109
+ localStream.getVideoTracks().forEach(track => {
5110
5110
  if (track.enabled === false) {
5111
5111
  track.stop();
5112
5112
  localStream.removeTrack(track);
@@ -5145,7 +5145,7 @@ class P2pRtcManager extends BaseRtcManager {
5145
5145
  // device has been plugged out or similar
5146
5146
  return;
5147
5147
  }
5148
- navigator.mediaDevices.getUserMedia({ video: constraints }).then((stream) => {
5148
+ navigator.mediaDevices.getUserMedia({ video: constraints }).then(stream => {
5149
5149
  const track = stream.getVideoTracks()[0];
5150
5150
  localStream.addTrack(track);
5151
5151
  this._emit(EVENTS.LOCAL_STREAM_TRACK_ADDED, {
@@ -5331,7 +5331,7 @@ class VegaConnection extends EventEmitter.EventEmitter {
5331
5331
  this.socket.onerror = null;
5332
5332
  this.socket = null;
5333
5333
 
5334
- this.sents.forEach((sent) => sent.close());
5334
+ this.sents.forEach(sent => sent.close());
5335
5335
 
5336
5336
  this.emit("close");
5337
5337
  }
@@ -5405,13 +5405,13 @@ class VegaConnection extends EventEmitter.EventEmitter {
5405
5405
  const sent = {
5406
5406
  id: request.id,
5407
5407
  method: request.method,
5408
- resolve: (data2) => {
5408
+ resolve: data2 => {
5409
5409
  if (!this.sents.delete(request.id)) return;
5410
5410
 
5411
5411
  clearTimeout(sent.timer);
5412
5412
  pResolve(data2);
5413
5413
  },
5414
- reject: (error) => {
5414
+ reject: error => {
5415
5415
  if (!this.sents.delete(request.id)) return;
5416
5416
 
5417
5417
  clearTimeout(sent.timer);
@@ -5509,30 +5509,30 @@ const modifyMediaCapabilities = (routerRtpCapabilities, features) => {
5509
5509
 
5510
5510
  if (vp9On) {
5511
5511
  const { preferredPayloadType } = routerRtpCapabilities.codecs.find(
5512
- (codec) => codec.mimeType.toLowerCase() === "video/vp9"
5512
+ codec => codec.mimeType.toLowerCase() === "video/vp9"
5513
5513
  );
5514
5514
 
5515
5515
  const { preferredPayloadType: aptPreferredPayloadType } = routerRtpCapabilities.codecs.find(
5516
- (codec) => codec.mimeType.toLowerCase() === "video/rtx" && codec.parameters.apt === preferredPayloadType
5516
+ codec => codec.mimeType.toLowerCase() === "video/rtx" && codec.parameters.apt === preferredPayloadType
5517
5517
  );
5518
5518
 
5519
5519
  routerRtpCapabilities.codecs = routerRtpCapabilities.codecs.filter(
5520
- (codec) =>
5520
+ codec =>
5521
5521
  codec.kind === "audio" ||
5522
5522
  codec.preferredPayloadType === preferredPayloadType ||
5523
5523
  codec.preferredPayloadType === aptPreferredPayloadType
5524
5524
  );
5525
5525
  } else if (h264On) {
5526
5526
  const { preferredPayloadType } = routerRtpCapabilities.codecs.find(
5527
- (codec) => codec.mimeType.toLowerCase() === "video/h264"
5527
+ codec => codec.mimeType.toLowerCase() === "video/h264"
5528
5528
  );
5529
5529
 
5530
5530
  const { preferredPayloadType: aptPreferredPayloadType } = routerRtpCapabilities.codecs.find(
5531
- (codec) => codec.mimeType.toLowerCase() === "video/rtx" && codec.parameters.apt === preferredPayloadType
5531
+ codec => codec.mimeType.toLowerCase() === "video/rtx" && codec.parameters.apt === preferredPayloadType
5532
5532
  );
5533
5533
 
5534
5534
  routerRtpCapabilities.codecs = routerRtpCapabilities.codecs.filter(
5535
- (codec) =>
5535
+ codec =>
5536
5536
  codec.kind === "audio" ||
5537
5537
  codec.preferredPayloadType === preferredPayloadType ||
5538
5538
  codec.preferredPayloadType === aptPreferredPayloadType
@@ -5566,7 +5566,7 @@ const maybeTurnOnly = (transportConfig, features) => {
5566
5566
  }[features.useOnlyTURN];
5567
5567
 
5568
5568
  if (filter) {
5569
- transportConfig.iceServers = transportConfig.iceServers.filter((entry) => entry.url && entry.url.match(filter));
5569
+ transportConfig.iceServers = transportConfig.iceServers.filter(entry => entry.url && entry.url.match(filter));
5570
5570
  }
5571
5571
  };
5572
5572
 
@@ -5670,7 +5670,7 @@ class VegaRtcManager {
5670
5670
  this._socketListenerDeregisterFunctions.push(
5671
5671
  () => this._clearMediaServersRefresh(),
5672
5672
 
5673
- this._serverSocket.on(PROTOCOL_RESPONSES.MEDIASERVER_CONFIG, (data) => {
5673
+ this._serverSocket.on(PROTOCOL_RESPONSES.MEDIASERVER_CONFIG, data => {
5674
5674
  if (data.error) {
5675
5675
  logger.warn("FETCH_MEDIASERVER_CONFIG failed:", data.error);
5676
5676
  return;
@@ -5707,7 +5707,7 @@ class VegaRtcManager {
5707
5707
  this._vegaConnection = new VegaConnection(wsUrl, logger);
5708
5708
  this._vegaConnection.on("open", () => this._join());
5709
5709
  this._vegaConnection.on("close", () => this._onClose());
5710
- this._vegaConnection.on("message", (message) => this._onMessage(message));
5710
+ this._vegaConnection.on("message", message => this._onMessage(message));
5711
5711
  }
5712
5712
 
5713
5713
  _onClose() {
@@ -5788,7 +5788,7 @@ class VegaRtcManager {
5788
5788
  maybeTurnOnly(transportOptions, this._features);
5789
5789
 
5790
5790
  const transport = this._mediasoupDevice[creator](transportOptions);
5791
- const onConnectionStateListener = async (connectionState) => {
5791
+ const onConnectionStateListener = async connectionState => {
5792
5792
  logger.debug(`Transport ConnectionStateChanged ${connectionState}`);
5793
5793
  if (connectionState !== "disconnected" && connectionState !== "failed") {
5794
5794
  return;
@@ -5900,7 +5900,7 @@ class VegaRtcManager {
5900
5900
  const error = await transport
5901
5901
  .restartIce({ iceParameters })
5902
5902
  .then(() => null)
5903
- .catch((err) => err);
5903
+ .catch(err => err);
5904
5904
 
5905
5905
  if (error) {
5906
5906
  logger.error(`_restartIce: ICE restart failed: ${error}`);
@@ -5911,7 +5911,7 @@ class VegaRtcManager {
5911
5911
  break;
5912
5912
  default:
5913
5913
  // exponential backoff
5914
- await new Promise((resolve) => {
5914
+ await new Promise(resolve => {
5915
5915
  setTimeout(() => {
5916
5916
  resolve();
5917
5917
  }, Math.min(RESTARTICE_ERROR_RETRY_THRESHOLD_IN_MS * 2 ** retried, 60000));
@@ -5921,7 +5921,7 @@ class VegaRtcManager {
5921
5921
  }
5922
5922
  return;
5923
5923
  }
5924
- await new Promise((resolve) => {
5924
+ await new Promise(resolve => {
5925
5925
  setTimeout(() => {
5926
5926
  resolve();
5927
5927
  }, 60000 * Math.min(8, retried + 1));
@@ -6495,54 +6495,6 @@ class VegaRtcManager {
6495
6495
  this._webcamPaused = !enable;
6496
6496
 
6497
6497
  this._pauseResumeWebcam();
6498
-
6499
- if (browserName === "chrome") {
6500
- // actually turn off the camera. Chrome-only (Firefox etc. has different plans)
6501
-
6502
- if (!enable) {
6503
- clearTimeout(this._stopCameraTimeout);
6504
-
6505
- // try to stop the local camera so the camera light goes off.
6506
- this._stopCameraTimeout = setTimeout(() => {
6507
- localStream.getVideoTracks().forEach((track) => {
6508
- if (track.enabled === false) {
6509
- track.stop();
6510
- localStream.removeTrack(track);
6511
-
6512
- this._emitToPWA(EVENTS.LOCAL_STREAM_TRACK_REMOVED, {
6513
- stream: localStream,
6514
- track,
6515
- });
6516
-
6517
- if (
6518
- this._webcamProducer &&
6519
- !this._webcamProducer.closed &&
6520
- this._webcamProducer.track === track
6521
- ) {
6522
- this._stopProducer(this._webcamProducer);
6523
- this._webcamProducer = null;
6524
- this._webcamTrack = null;
6525
- }
6526
- }
6527
- });
6528
- }, 5000);
6529
- } else if (localStream.getVideoTracks().length === 0) {
6530
- // re-enable the stream
6531
- const constraints = this._webrtcProvider.getMediaConstraints().video;
6532
- navigator.mediaDevices.getUserMedia({ video: constraints }).then((stream) => {
6533
- const track = stream.getVideoTracks()[0];
6534
- localStream.addTrack(track);
6535
-
6536
- this._emitToPWA(EVENTS.LOCAL_STREAM_TRACK_ADDED, {
6537
- streamId: localStream.id,
6538
- tracks: [track],
6539
- screenShare: false,
6540
- });
6541
-
6542
- this._sendWebcam(track);
6543
- });
6544
- }
6545
- }
6546
6498
  }
6547
6499
 
6548
6500
  supportsScreenShareAudio() {
@@ -6609,7 +6561,7 @@ class VegaRtcManager {
6609
6561
  }
6610
6562
 
6611
6563
  disconnectAll() {
6612
- this._socketListenerDeregisterFunctions.forEach((func) => {
6564
+ this._socketListenerDeregisterFunctions.forEach(func => {
6613
6565
  func();
6614
6566
  });
6615
6567
 
@@ -6652,7 +6604,7 @@ class VegaRtcManager {
6652
6604
  return;
6653
6605
  }
6654
6606
  })
6655
- .catch((error) => {
6607
+ .catch(error => {
6656
6608
  console.error('"message" failed [error:%o]', error);
6657
6609
  });
6658
6610
  }
@@ -6787,7 +6739,7 @@ class VegaRtcManager {
6787
6739
  const toPauseConsumers = [];
6788
6740
  const toResumeConsumers = [];
6789
6741
 
6790
- this._consumers.forEach((consumer) => {
6742
+ this._consumers.forEach(consumer => {
6791
6743
  if (consumer.appData.sourceClientId !== clientId) return;
6792
6744
 
6793
6745
  const hasAccepted = consumer.appData.screenShare ? hasAcceptedScreenStream : hasAcceptedWebcamStream;
@@ -6825,6 +6777,7 @@ class VegaRtcManager {
6825
6777
  clientId,
6826
6778
  stream: webcamStream,
6827
6779
  streamId: camStreamId,
6780
+ streamType: "webcam",
6828
6781
  });
6829
6782
 
6830
6783
  clientState.hasEmittedWebcamStream = true;
@@ -6836,6 +6789,7 @@ class VegaRtcManager {
6836
6789
  clientId,
6837
6790
  stream: screenStream,
6838
6791
  streamId: screenShareStreamId,
6792
+ streamType: "screenshare",
6839
6793
  });
6840
6794
 
6841
6795
  clientState.hasEmittedScreenStream = true;
@@ -8338,6 +8292,15 @@ class RemoteParticipant extends RoomParticipant {
8338
8292
  this.newJoiner = newJoiner;
8339
8293
  this.streams = streams.map((streamId) => ({ id: streamId, state: newJoiner ? "new_accept" : "to_accept" }));
8340
8294
  }
8295
+ addStream(streamId, state) {
8296
+ this.streams.push({ id: streamId, state });
8297
+ }
8298
+ removeStream(streamId) {
8299
+ const index = this.streams.findIndex((s) => s.id === streamId);
8300
+ if (index !== -1) {
8301
+ this.streams.splice(index, 1);
8302
+ }
8303
+ }
8341
8304
  updateStreamState(streamId, state) {
8342
8305
  const stream = this.streams.find((s) => s.id === streamId);
8343
8306
  if (stream) {
@@ -8379,6 +8342,7 @@ class RoomConnection extends TypedEventTarget {
8379
8342
  super();
8380
8343
  this.localParticipant = null;
8381
8344
  this.remoteParticipants = [];
8345
+ this.screenshares = [];
8382
8346
  this._deviceCredentials = null;
8383
8347
  this._ownsLocalMedia = false;
8384
8348
  this.organizationId = "";
@@ -8440,6 +8404,8 @@ class RoomConnection extends TypedEventTarget {
8440
8404
  this.signalSocket.on("room_joined", this._handleRoomJoined.bind(this));
8441
8405
  this.signalSocket.on("room_knocked", this._handleRoomKnocked.bind(this));
8442
8406
  this.signalSocket.on("cloud_recording_stopped", this._handleCloudRecordingStopped.bind(this));
8407
+ this.signalSocket.on("screenshare_started", this._handleScreenshareStarted.bind(this));
8408
+ this.signalSocket.on("screenshare_stopped", this._handleScreenshareStopped.bind(this));
8443
8409
  this.signalSocket.on("streaming_stopped", this._handleStreamingStopped.bind(this));
8444
8410
  this.signalSocket.on("disconnect", this._handleDisconnect.bind(this));
8445
8411
  this.signalSocket.on("connect_error", this._handleDisconnect.bind(this));
@@ -8657,6 +8623,33 @@ class RoomConnection extends TypedEventTarget {
8657
8623
  _handleStreamingStopped() {
8658
8624
  this.dispatchEvent(new CustomEvent("streaming_stopped"));
8659
8625
  }
8626
+ _handleScreenshareStarted(screenshare) {
8627
+ const { clientId: participantId, streamId: id, hasAudioTrack } = screenshare;
8628
+ const remoteParticipant = this.remoteParticipants.find((p) => p.id === participantId);
8629
+ if (!remoteParticipant) {
8630
+ this.logger.log("WARN: Could not find participant for screenshare");
8631
+ return;
8632
+ }
8633
+ const foundScreenshare = this.screenshares.find((s) => s.id === id);
8634
+ if (foundScreenshare) {
8635
+ this.logger.log("WARN: Screenshare already exists");
8636
+ return;
8637
+ }
8638
+ remoteParticipant.addStream(id, "to_accept");
8639
+ this._handleAcceptStreams([remoteParticipant]);
8640
+ this.screenshares = [...this.screenshares, { participantId, id, hasAudioTrack, stream: undefined }];
8641
+ }
8642
+ _handleScreenshareStopped(screenshare) {
8643
+ const { clientId: participantId, streamId: id } = screenshare;
8644
+ const remoteParticipant = this.remoteParticipants.find((p) => p.id === participantId);
8645
+ if (!remoteParticipant) {
8646
+ this.logger.log("WARN: Could not find participant for screenshare");
8647
+ return;
8648
+ }
8649
+ remoteParticipant.removeStream(id);
8650
+ this.screenshares = this.screenshares.filter((s) => !(s.participantId === participantId && s.id === id));
8651
+ this.dispatchEvent(new CustomEvent("screenshare_stopped", { detail: { participantId, id } }));
8652
+ }
8660
8653
  _handleRtcEvent(eventName, data) {
8661
8654
  if (eventName === "rtc_manager_created") {
8662
8655
  return this._handleRtcManagerCreated(data);
@@ -8733,13 +8726,24 @@ class RoomConnection extends TypedEventTarget {
8733
8726
  });
8734
8727
  });
8735
8728
  }
8736
- _handleStreamAdded({ clientId, stream, streamId }) {
8729
+ _handleStreamAdded({ clientId, stream, streamId, streamType }) {
8737
8730
  const remoteParticipant = this.remoteParticipants.find((p) => p.id === clientId);
8738
8731
  if (!remoteParticipant) {
8739
8732
  this.logger.log("WARN: Could not find participant for incoming stream");
8740
8733
  return;
8741
8734
  }
8742
- this.dispatchEvent(new CustomEvent("participant_stream_added", { detail: { participantId: clientId, stream, streamId } }));
8735
+ const remoteParticipantStream = remoteParticipant.streams.find((s) => s.id === streamId);
8736
+ if ((remoteParticipant.stream && remoteParticipant.stream.id === streamId) ||
8737
+ (!remoteParticipant.stream && streamType === "webcam") ||
8738
+ (!remoteParticipant.stream &&
8739
+ !streamType &&
8740
+ remoteParticipantStream &&
8741
+ remoteParticipant.streams.indexOf(remoteParticipantStream) < 1)) {
8742
+ this.dispatchEvent(new CustomEvent("participant_stream_added", { detail: { participantId: clientId, stream, streamId } }));
8743
+ return;
8744
+ }
8745
+ // screenshare
8746
+ this.dispatchEvent(new CustomEvent("screenshare_started", { detail: { participantId: clientId, stream, id: streamId } }));
8743
8747
  }
8744
8748
  _joinRoom() {
8745
8749
  this.signalSocket.emit("join_room", {
@@ -8865,6 +8869,7 @@ const initialState = {
8865
8869
  mostRecentChatMessage: null,
8866
8870
  remoteParticipants: [],
8867
8871
  roomConnectionStatus: "",
8872
+ screenshares: [],
8868
8873
  streaming: {
8869
8874
  status: "",
8870
8875
  startedAt: null,
@@ -8883,6 +8888,13 @@ function updateParticipant(remoteParticipants, participantId, updates) {
8883
8888
  ...remoteParticipants.slice(index + 1),
8884
8889
  ];
8885
8890
  }
8891
+ function addScreenshare(screenshares, screenshare) {
8892
+ const existingScreenshare = screenshares.find((ss) => ss.id === screenshare.id);
8893
+ if (existingScreenshare) {
8894
+ return screenshares;
8895
+ }
8896
+ return [...screenshares, screenshare];
8897
+ }
8886
8898
  function reducer(state, action) {
8887
8899
  switch (action.type) {
8888
8900
  case "CHAT_MESSAGE":
@@ -8925,6 +8937,15 @@ function reducer(state, action) {
8925
8937
  if (!state.localParticipant)
8926
8938
  return state;
8927
8939
  return Object.assign(Object.assign({}, state), { localParticipant: Object.assign(Object.assign({}, state.localParticipant), { displayName: action.payload.displayName }) });
8940
+ case "SCREENSHARE_STARTED":
8941
+ return Object.assign(Object.assign({}, state), { screenshares: addScreenshare(state.screenshares, {
8942
+ participantId: action.payload.participantId,
8943
+ id: action.payload.id,
8944
+ hasAudioTrack: action.payload.hasAudioTrack,
8945
+ stream: action.payload.stream,
8946
+ }) });
8947
+ case "SCREENSHARE_STOPPED":
8948
+ return Object.assign(Object.assign({}, state), { screenshares: state.screenshares.filter((ss) => ss.participantId !== action.payload.participantId || ss.id !== action.payload.id) });
8928
8949
  case "STREAMING_STARTED":
8929
8950
  return Object.assign(Object.assign({}, state), { streaming: {
8930
8951
  status: action.payload.status,
@@ -8996,6 +9017,14 @@ function useRoomConnection(roomUrl, roomConnectionOptions) {
8996
9017
  const { participantId, displayName } = e.detail;
8997
9018
  dispatch({ type: "PARTICIPANT_METADATA_CHANGED", payload: { participantId, displayName } });
8998
9019
  });
9020
+ roomConnection.addEventListener("screenshare_started", (e) => {
9021
+ const { participantId, id, hasAudioTrack, stream } = e.detail;
9022
+ dispatch({ type: "SCREENSHARE_STARTED", payload: { participantId, id, hasAudioTrack, stream } });
9023
+ });
9024
+ roomConnection.addEventListener("screenshare_stopped", (e) => {
9025
+ const { participantId, id } = e.detail;
9026
+ dispatch({ type: "SCREENSHARE_STOPPED", payload: { participantId, id } });
9027
+ });
8999
9028
  roomConnection.addEventListener("streaming_started", (e) => {
9000
9029
  const { status, startedAt } = e.detail;
9001
9030
  dispatch({ type: "STREAMING_STARTED", payload: { status, startedAt } });
@@ -9049,7 +9078,7 @@ function useRoomConnection(roomUrl, roomConnectionOptions) {
9049
9078
  };
9050
9079
  }
9051
9080
 
9052
- const sdkVersion = "2.0.0-alpha15";
9081
+ const sdkVersion = "2.0.0-alpha17";
9053
9082
 
9054
9083
  exports.VideoView = VideoView;
9055
9084
  exports.sdkVersion = sdkVersion;