@fishjam-cloud/webrtc-client 0.26.0-rc.1 → 0.26.1-rc.1

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/index.d.mts CHANGED
@@ -501,6 +501,8 @@ declare class ConnectionManager {
501
501
  isConnectionUnstable: () => boolean;
502
502
  getConnection: () => RTCPeerConnection;
503
503
  addTransceiversIfNeeded: (serverTracks: MediaEvent_OfferData_TrackTypes) => void;
504
+ private static isLiveRecvTransceiver;
505
+ private stopExcessRecvTransceivers;
504
506
  addTransceiver: (track: MediaStreamTrack, transceiverConfig: RTCRtpTransceiverInit) => void;
505
507
  setOnTrackReady: (onTrackReady: (event: RTCTrackEvent) => void) => void;
506
508
  setRemoteDescription: (data: RTCSessionDescriptionInit) => Promise<void>;
@@ -597,7 +599,9 @@ declare class WebRTCEndpoint extends WebRTCEndpoint_base {
597
599
  * webrtcChannel.on("mediaEvent", (event) => webrtc.receiveMediaEvent(event.data));
598
600
  * ```
599
601
  */
602
+ private mediaEventQueue;
600
603
  receiveMediaEvent: (mediaEvent: SerializedMediaEvent) => Promise<void>;
604
+ private handleConnected;
601
605
  private getEndpointId;
602
606
  private onTrackReady;
603
607
  /**
package/dist/index.mjs CHANGED
@@ -1484,7 +1484,7 @@ var CommandsQueue = class {
1484
1484
  };
1485
1485
 
1486
1486
  // src/ConnectionManager.ts
1487
- var ConnectionManager = class {
1487
+ var ConnectionManager = class _ConnectionManager {
1488
1488
  connection;
1489
1489
  constructor(iceServers) {
1490
1490
  this.connection = new RTCPeerConnection({
@@ -1504,15 +1504,29 @@ var ConnectionManager = class {
1504
1504
  return this.connection;
1505
1505
  };
1506
1506
  addTransceiversIfNeeded = (serverTracks) => {
1507
- const recvTransceivers = this.connection.getTransceivers().filter((elem) => elem.direction === "recvonly");
1507
+ const recvTransceivers = this.connection.getTransceivers().filter(_ConnectionManager.isLiveRecvTransceiver);
1508
1508
  const videoTransceiversAmount = recvTransceivers.filter((elem) => elem.receiver.track.kind === "video").length;
1509
1509
  const audioTransceiversAmount = recvTransceivers.filter((elem) => elem.receiver.track.kind === "audio").length;
1510
- const videoNeededTypes = Array(serverTracks.video - videoTransceiversAmount).fill("video");
1511
- const audioNeededTypes = Array(serverTracks.audio - audioTransceiversAmount).fill("audio");
1510
+ const videoDelta = serverTracks.video - videoTransceiversAmount;
1511
+ const audioDelta = serverTracks.audio - audioTransceiversAmount;
1512
+ this.stopExcessRecvTransceivers("video", -videoDelta);
1513
+ this.stopExcessRecvTransceivers("audio", -audioDelta);
1514
+ const videoNeededTypes = Array(Math.max(0, videoDelta)).fill("video");
1515
+ const audioNeededTypes = Array(Math.max(0, audioDelta)).fill("audio");
1512
1516
  [...videoNeededTypes, ...audioNeededTypes].forEach(
1513
1517
  (kind) => this.connection.addTransceiver(kind, { direction: "recvonly" })
1514
1518
  );
1515
1519
  };
1520
+ static isLiveRecvTransceiver = (t) => t.direction === "recvonly" && t.currentDirection !== "stopped";
1521
+ stopExcessRecvTransceivers = (kind, excess) => {
1522
+ if (excess <= 0) return;
1523
+ const candidates = this.connection.getTransceivers().filter((t) => _ConnectionManager.isLiveRecvTransceiver(t) && t.receiver.track?.kind === kind).sort((a, b) => {
1524
+ const aOrphan = a.mid === null ? 0 : 1;
1525
+ const bOrphan = b.mid === null ? 0 : 1;
1526
+ return aOrphan - bOrphan;
1527
+ });
1528
+ candidates.slice(0, excess).forEach((transceiver) => transceiver.stop());
1529
+ };
1516
1530
  addTransceiver = (track, transceiverConfig) => {
1517
1531
  this.connection.addTransceiver(track, transceiverConfig);
1518
1532
  };
@@ -4072,7 +4086,8 @@ var createSimulcastTransceiverConfig = (trackContext, maxBandwidth) => {
4072
4086
  // keep this array from low resolution to high resolution
4073
4087
  // in other case lower resolution encoding can get
4074
4088
  // higher max_bitrate
4075
- sendEncodings: calculateSimulcastEncodings(encodings, maxBandwidth)
4089
+ sendEncodings: calculateSimulcastEncodings(encodings, maxBandwidth),
4090
+ streams: trackContext.stream ? [trackContext.stream] : []
4076
4091
  };
4077
4092
  };
4078
4093
  var calculateSimulcastEncodings = (encodings, maxBandwidth) => {
@@ -4834,29 +4849,25 @@ var WebRTCEndpoint = class extends EventEmitter3 {
4834
4849
  * webrtcChannel.on("mediaEvent", (event) => webrtc.receiveMediaEvent(event.data));
4835
4850
  * ```
4836
4851
  */
4837
- receiveMediaEvent = async (mediaEvent) => {
4852
+ mediaEventQueue = Promise.resolve();
4853
+ receiveMediaEvent = (mediaEvent) => {
4838
4854
  const deserializedMediaEvent = deserializeServerMediaEvent(mediaEvent);
4839
- if (deserializedMediaEvent.connected) {
4840
- const connectedEvent = deserializedMediaEvent.connected;
4841
- this.proposedIceServers = connectedEvent.iceServers;
4842
- this.local.setLocalEndpointId(connectedEvent.endpointId);
4843
- const localEndpointMetadataJson = connectedEvent.endpointIdToEndpoint[connectedEvent.endpointId]?.metadataJson;
4844
- if (localEndpointMetadataJson) {
4845
- this.local.setEndpointMetadata(JSON.parse(localEndpointMetadataJson));
4846
- }
4847
- const connectedEndpoint = connectedEvent.endpointIdToEndpoint[connectedEvent.endpointId];
4848
- if (connectedEndpoint?.metadataJson) {
4849
- const parsedMetadata = JSON.parse(connectedEndpoint?.metadataJson);
4850
- this.local.setEndpointMetadata(parsedMetadata);
4851
- }
4852
- Object.entries(connectedEvent.endpointIdToEndpoint).filter(([endpointId]) => endpointId !== this.local.getEndpoint().id).forEach(([endpointId, endpoint]) => {
4853
- this.remote.addRemoteEndpoint(endpointId, endpoint.metadataJson, endpoint.trackIdToTrack);
4854
- });
4855
- const remoteEndpoints = Object.values(this.remote.getRemoteEndpoints());
4856
- this.emit("connected", this.local.getEndpoint().id, remoteEndpoints);
4857
- return;
4858
- }
4859
- if (this.getEndpointId()) await this.handleMediaEvent(deserializedMediaEvent);
4855
+ const next = this.mediaEventQueue.then(() => this.handleMediaEvent(deserializedMediaEvent));
4856
+ this.mediaEventQueue = next.catch(() => void 0);
4857
+ return next;
4858
+ };
4859
+ handleConnected = (connectedEvent) => {
4860
+ this.proposedIceServers = connectedEvent.iceServers;
4861
+ this.local.setLocalEndpointId(connectedEvent.endpointId);
4862
+ const localEndpoint = connectedEvent.endpointIdToEndpoint[connectedEvent.endpointId];
4863
+ if (localEndpoint?.metadataJson) {
4864
+ this.local.setEndpointMetadata(JSON.parse(localEndpoint.metadataJson));
4865
+ }
4866
+ Object.entries(connectedEvent.endpointIdToEndpoint).filter(([endpointId]) => endpointId !== this.local.getEndpoint().id).forEach(([endpointId, endpoint]) => {
4867
+ this.remote.addRemoteEndpoint(endpointId, endpoint.metadataJson, endpoint.trackIdToTrack);
4868
+ });
4869
+ const remoteEndpoints = Object.values(this.remote.getRemoteEndpoints());
4870
+ this.emit("connected", this.local.getEndpoint().id, remoteEndpoints);
4860
4871
  };
4861
4872
  getEndpointId = () => this.local.getEndpoint().id;
4862
4873
  onTrackReady = (event) => {
@@ -4905,6 +4916,11 @@ var WebRTCEndpoint = class extends EventEmitter3 {
4905
4916
  return this.dataChannelManager?.getChannelsReadiness() ?? false;
4906
4917
  }
4907
4918
  handleMediaEvent = async (event) => {
4919
+ if (event.connected) {
4920
+ this.handleConnected(event.connected);
4921
+ return;
4922
+ }
4923
+ if (!this.getEndpointId()) return;
4908
4924
  if (event.offerData) {
4909
4925
  await this.onOfferData(event.offerData);
4910
4926
  } else if (event.tracksAdded) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fishjam-cloud/webrtc-client",
3
- "version": "0.26.0-rc.1",
3
+ "version": "0.26.1-rc.1",
4
4
  "description": "Typescript client library for ExWebRTC/WebRTC endpoint in Membrane RTC Engine",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Fishjam Team",