@whereby.com/media 2.2.0 → 2.4.0

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.cjs CHANGED
@@ -3989,6 +3989,37 @@ function getNumberOfTemporalLayers(consumer) {
3989
3989
  var _a, _b, _c;
3990
3990
  return /T3/.test(((_c = (_b = (_a = consumer._rtpParameters) === null || _a === void 0 ? void 0 : _a.encodings) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.scalabilityMode) || "") ? 3 : 2;
3991
3991
  }
3992
+ function addProducerCpuOveruseWatch({ producer, onOveruse }) {
3993
+ var _a;
3994
+ const encodings = (_a = producer.rtpParameters) === null || _a === void 0 ? void 0 : _a.encodings;
3995
+ let interval = null;
3996
+ if ((encodings === null || encodings === void 0 ? void 0 : encodings.length) === 3) {
3997
+ const { ssrc, rid } = encodings[0];
3998
+ let maxHeight = 0;
3999
+ let ticks = 0;
4000
+ const targetTicksForTrigger = 2;
4001
+ interval = setInterval(() => __awaiter(this, void 0, void 0, function* () {
4002
+ (yield producer.getStats()).forEach((report) => {
4003
+ if (report.type === "outbound-rtp" && ((ssrc && report.ssrc === ssrc) || (rid && report.rid === rid))) {
4004
+ if (maxHeight && report.frameHeight && report.frameHeight < maxHeight) {
4005
+ ticks++;
4006
+ if (ticks >= targetTicksForTrigger) {
4007
+ onOveruse();
4008
+ }
4009
+ }
4010
+ else {
4011
+ ticks = 0;
4012
+ }
4013
+ maxHeight = Math.max(maxHeight, report.frameHeight || 0);
4014
+ }
4015
+ });
4016
+ }), 2000);
4017
+ }
4018
+ return () => {
4019
+ if (interval)
4020
+ clearInterval(interval);
4021
+ };
4022
+ }
3992
4023
 
3993
4024
  class SfuV2Parser {
3994
4025
  static parse(raw) {
@@ -4454,6 +4485,7 @@ class VegaRtcManager {
4454
4485
  this._emitToPWA(PROTOCOL_EVENTS.MEDIA_QUALITY_CHANGED, payload);
4455
4486
  });
4456
4487
  this._networkIsDetectedUpBySignal = false;
4488
+ this._cpuOveruseDetected = false;
4457
4489
  }
4458
4490
  _updateAndScheduleMediaServersRefresh({ iceServers, turnServers, sfuServer, sfuServers, mediaserverConfigTtlSeconds, }) {
4459
4491
  var _a, _b, _c;
@@ -4945,6 +4977,23 @@ class VegaRtcManager {
4945
4977
  this._internalSetupMicScore();
4946
4978
  }
4947
4979
  }
4980
+ _syncResourceUsage() {
4981
+ var _a;
4982
+ if (this._webcamProducer) {
4983
+ const simulcastLayer3ShouldBeActive = !this._cpuOveruseDetected;
4984
+ const params = this._webcamProducer.rtpParameters;
4985
+ if (((_a = params === null || params === void 0 ? void 0 : params.encodings) === null || _a === void 0 ? void 0 : _a.length) === 3) {
4986
+ const targetMaxSpatialLayer = simulcastLayer3ShouldBeActive ? 2 : 1;
4987
+ if (this._webcamProducer.maxSpatialLayer !== targetMaxSpatialLayer) {
4988
+ this._webcamProducer.setMaxSpatialLayer(targetMaxSpatialLayer);
4989
+ rtcStats.sendEvent("simulcast_layer_activation_changed", {
4990
+ layerIndex: 2,
4991
+ active: simulcastLayer3ShouldBeActive,
4992
+ });
4993
+ }
4994
+ }
4995
+ }
4996
+ }
4948
4997
  _internalSendWebcam() {
4949
4998
  return __awaiter(this, void 0, void 0, function* () {
4950
4999
  var _a;
@@ -4967,6 +5016,17 @@ class VegaRtcManager {
4967
5016
  paused: currentPaused,
4968
5017
  } }));
4969
5018
  currentPaused ? producer.pause() : producer.resume();
5019
+ const cleanUpCpuWatch = this._features.producerCpuOveruseWatchOn
5020
+ ? addProducerCpuOveruseWatch({
5021
+ producer,
5022
+ onOveruse: () => {
5023
+ rtcStats.sendEvent("producer_cpuoveruse_detected", {});
5024
+ cleanUpCpuWatch();
5025
+ this._cpuOveruseDetected = true;
5026
+ this._syncResourceUsage();
5027
+ },
5028
+ })
5029
+ : () => { };
4970
5030
  this._webcamProducer = producer;
4971
5031
  this._qualityMonitor.addProducer(this._selfId, producer.id);
4972
5032
  producer.observer.once("close", () => {
@@ -4974,6 +5034,7 @@ class VegaRtcManager {
4974
5034
  logger$2.info('webcamProducer "close" event');
4975
5035
  if (producer.appData.localClosed)
4976
5036
  (_a = this._vegaConnection) === null || _a === void 0 ? void 0 : _a.message("closeProducers", { producerIds: [producer.id] });
5037
+ cleanUpCpuWatch();
4977
5038
  this._webcamProducer = null;
4978
5039
  this._webcamProducerPromise = null;
4979
5040
  this._qualityMonitor.removeProducer(this._selfId, producer.id);
@@ -6085,6 +6146,17 @@ const metrics = [
6085
6146
  enabled: ({ hasLiveTrack, track, trackStats, ssrc0, kind }) => hasLiveTrack && kind === "video" && !!trackStats && !!track && !!ssrc0 && !!ssrc0.height,
6086
6147
  value: ({ trackStats }) => Object.values((trackStats === null || trackStats === void 0 ? void 0 : trackStats.ssrcs) || {}).reduce((max, ssrc) => Math.max(max, ssrc.fps || 0 > 0 ? ssrc.height || 0 : 0), 0),
6087
6148
  },
6149
+ {
6150
+ id: "layer0-height",
6151
+ enabled: ({ hasLiveTrack, track, ssrc0, kind }) => hasLiveTrack &&
6152
+ kind === "video" &&
6153
+ !!track &&
6154
+ !!ssrc0 &&
6155
+ !!ssrc0.height &&
6156
+ !!ssrc0.fps &&
6157
+ ssrc0.direction === "out",
6158
+ value: ({ ssrc0 }) => (ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.height) || 0,
6159
+ },
6088
6160
  {
6089
6161
  id: "sourceHeight",
6090
6162
  enabled: ({ hasLiveTrack, track, ssrc0, kind }) => hasLiveTrack && kind === "video" && !!track && !!ssrc0 && !!ssrc0.sourceHeight && ssrc0.direction === "out",
package/dist/index.d.cts CHANGED
@@ -1546,6 +1546,7 @@ declare class VegaRtcManager implements RtcManager {
1546
1546
  _isConnectingOrConnected: boolean;
1547
1547
  _vegaConnectionManager?: ReturnType<typeof createVegaConnectionManager>;
1548
1548
  _networkIsDetectedUpBySignal: boolean;
1549
+ _cpuOveruseDetected: boolean;
1549
1550
  constructor({ selfId, room, emitter, serverSocket, webrtcProvider, features, eventClaim, }: {
1550
1551
  selfId: any;
1551
1552
  room: any;
@@ -1579,6 +1580,7 @@ declare class VegaRtcManager implements RtcManager {
1579
1580
  _pauseResumeMic(): void;
1580
1581
  _sendMic(track: MediaStreamTrack): Promise<void>;
1581
1582
  _sendMicScore(score: number): void;
1583
+ _syncResourceUsage(): void;
1582
1584
  _internalSendWebcam(): Promise<void>;
1583
1585
  _replaceWebcamTrack(): Promise<void>;
1584
1586
  _pauseResumeWebcam(): void;
package/dist/index.d.mts CHANGED
@@ -1546,6 +1546,7 @@ declare class VegaRtcManager implements RtcManager {
1546
1546
  _isConnectingOrConnected: boolean;
1547
1547
  _vegaConnectionManager?: ReturnType<typeof createVegaConnectionManager>;
1548
1548
  _networkIsDetectedUpBySignal: boolean;
1549
+ _cpuOveruseDetected: boolean;
1549
1550
  constructor({ selfId, room, emitter, serverSocket, webrtcProvider, features, eventClaim, }: {
1550
1551
  selfId: any;
1551
1552
  room: any;
@@ -1579,6 +1580,7 @@ declare class VegaRtcManager implements RtcManager {
1579
1580
  _pauseResumeMic(): void;
1580
1581
  _sendMic(track: MediaStreamTrack): Promise<void>;
1581
1582
  _sendMicScore(score: number): void;
1583
+ _syncResourceUsage(): void;
1582
1584
  _internalSendWebcam(): Promise<void>;
1583
1585
  _replaceWebcamTrack(): Promise<void>;
1584
1586
  _pauseResumeWebcam(): void;
package/dist/index.d.ts CHANGED
@@ -1546,6 +1546,7 @@ declare class VegaRtcManager implements RtcManager {
1546
1546
  _isConnectingOrConnected: boolean;
1547
1547
  _vegaConnectionManager?: ReturnType<typeof createVegaConnectionManager>;
1548
1548
  _networkIsDetectedUpBySignal: boolean;
1549
+ _cpuOveruseDetected: boolean;
1549
1550
  constructor({ selfId, room, emitter, serverSocket, webrtcProvider, features, eventClaim, }: {
1550
1551
  selfId: any;
1551
1552
  room: any;
@@ -1579,6 +1580,7 @@ declare class VegaRtcManager implements RtcManager {
1579
1580
  _pauseResumeMic(): void;
1580
1581
  _sendMic(track: MediaStreamTrack): Promise<void>;
1581
1582
  _sendMicScore(score: number): void;
1583
+ _syncResourceUsage(): void;
1582
1584
  _internalSendWebcam(): Promise<void>;
1583
1585
  _replaceWebcamTrack(): Promise<void>;
1584
1586
  _pauseResumeWebcam(): void;
package/dist/index.mjs CHANGED
@@ -3968,6 +3968,37 @@ function getNumberOfTemporalLayers(consumer) {
3968
3968
  var _a, _b, _c;
3969
3969
  return /T3/.test(((_c = (_b = (_a = consumer._rtpParameters) === null || _a === void 0 ? void 0 : _a.encodings) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.scalabilityMode) || "") ? 3 : 2;
3970
3970
  }
3971
+ function addProducerCpuOveruseWatch({ producer, onOveruse }) {
3972
+ var _a;
3973
+ const encodings = (_a = producer.rtpParameters) === null || _a === void 0 ? void 0 : _a.encodings;
3974
+ let interval = null;
3975
+ if ((encodings === null || encodings === void 0 ? void 0 : encodings.length) === 3) {
3976
+ const { ssrc, rid } = encodings[0];
3977
+ let maxHeight = 0;
3978
+ let ticks = 0;
3979
+ const targetTicksForTrigger = 2;
3980
+ interval = setInterval(() => __awaiter(this, void 0, void 0, function* () {
3981
+ (yield producer.getStats()).forEach((report) => {
3982
+ if (report.type === "outbound-rtp" && ((ssrc && report.ssrc === ssrc) || (rid && report.rid === rid))) {
3983
+ if (maxHeight && report.frameHeight && report.frameHeight < maxHeight) {
3984
+ ticks++;
3985
+ if (ticks >= targetTicksForTrigger) {
3986
+ onOveruse();
3987
+ }
3988
+ }
3989
+ else {
3990
+ ticks = 0;
3991
+ }
3992
+ maxHeight = Math.max(maxHeight, report.frameHeight || 0);
3993
+ }
3994
+ });
3995
+ }), 2000);
3996
+ }
3997
+ return () => {
3998
+ if (interval)
3999
+ clearInterval(interval);
4000
+ };
4001
+ }
3971
4002
 
3972
4003
  class SfuV2Parser {
3973
4004
  static parse(raw) {
@@ -4433,6 +4464,7 @@ class VegaRtcManager {
4433
4464
  this._emitToPWA(PROTOCOL_EVENTS.MEDIA_QUALITY_CHANGED, payload);
4434
4465
  });
4435
4466
  this._networkIsDetectedUpBySignal = false;
4467
+ this._cpuOveruseDetected = false;
4436
4468
  }
4437
4469
  _updateAndScheduleMediaServersRefresh({ iceServers, turnServers, sfuServer, sfuServers, mediaserverConfigTtlSeconds, }) {
4438
4470
  var _a, _b, _c;
@@ -4924,6 +4956,23 @@ class VegaRtcManager {
4924
4956
  this._internalSetupMicScore();
4925
4957
  }
4926
4958
  }
4959
+ _syncResourceUsage() {
4960
+ var _a;
4961
+ if (this._webcamProducer) {
4962
+ const simulcastLayer3ShouldBeActive = !this._cpuOveruseDetected;
4963
+ const params = this._webcamProducer.rtpParameters;
4964
+ if (((_a = params === null || params === void 0 ? void 0 : params.encodings) === null || _a === void 0 ? void 0 : _a.length) === 3) {
4965
+ const targetMaxSpatialLayer = simulcastLayer3ShouldBeActive ? 2 : 1;
4966
+ if (this._webcamProducer.maxSpatialLayer !== targetMaxSpatialLayer) {
4967
+ this._webcamProducer.setMaxSpatialLayer(targetMaxSpatialLayer);
4968
+ rtcStats.sendEvent("simulcast_layer_activation_changed", {
4969
+ layerIndex: 2,
4970
+ active: simulcastLayer3ShouldBeActive,
4971
+ });
4972
+ }
4973
+ }
4974
+ }
4975
+ }
4927
4976
  _internalSendWebcam() {
4928
4977
  return __awaiter(this, void 0, void 0, function* () {
4929
4978
  var _a;
@@ -4946,6 +4995,17 @@ class VegaRtcManager {
4946
4995
  paused: currentPaused,
4947
4996
  } }));
4948
4997
  currentPaused ? producer.pause() : producer.resume();
4998
+ const cleanUpCpuWatch = this._features.producerCpuOveruseWatchOn
4999
+ ? addProducerCpuOveruseWatch({
5000
+ producer,
5001
+ onOveruse: () => {
5002
+ rtcStats.sendEvent("producer_cpuoveruse_detected", {});
5003
+ cleanUpCpuWatch();
5004
+ this._cpuOveruseDetected = true;
5005
+ this._syncResourceUsage();
5006
+ },
5007
+ })
5008
+ : () => { };
4949
5009
  this._webcamProducer = producer;
4950
5010
  this._qualityMonitor.addProducer(this._selfId, producer.id);
4951
5011
  producer.observer.once("close", () => {
@@ -4953,6 +5013,7 @@ class VegaRtcManager {
4953
5013
  logger$2.info('webcamProducer "close" event');
4954
5014
  if (producer.appData.localClosed)
4955
5015
  (_a = this._vegaConnection) === null || _a === void 0 ? void 0 : _a.message("closeProducers", { producerIds: [producer.id] });
5016
+ cleanUpCpuWatch();
4956
5017
  this._webcamProducer = null;
4957
5018
  this._webcamProducerPromise = null;
4958
5019
  this._qualityMonitor.removeProducer(this._selfId, producer.id);
@@ -6064,6 +6125,17 @@ const metrics = [
6064
6125
  enabled: ({ hasLiveTrack, track, trackStats, ssrc0, kind }) => hasLiveTrack && kind === "video" && !!trackStats && !!track && !!ssrc0 && !!ssrc0.height,
6065
6126
  value: ({ trackStats }) => Object.values((trackStats === null || trackStats === void 0 ? void 0 : trackStats.ssrcs) || {}).reduce((max, ssrc) => Math.max(max, ssrc.fps || 0 > 0 ? ssrc.height || 0 : 0), 0),
6066
6127
  },
6128
+ {
6129
+ id: "layer0-height",
6130
+ enabled: ({ hasLiveTrack, track, ssrc0, kind }) => hasLiveTrack &&
6131
+ kind === "video" &&
6132
+ !!track &&
6133
+ !!ssrc0 &&
6134
+ !!ssrc0.height &&
6135
+ !!ssrc0.fps &&
6136
+ ssrc0.direction === "out",
6137
+ value: ({ ssrc0 }) => (ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.height) || 0,
6138
+ },
6067
6139
  {
6068
6140
  id: "sourceHeight",
6069
6141
  enabled: ({ hasLiveTrack, track, ssrc0, kind }) => hasLiveTrack && kind === "video" && !!track && !!ssrc0 && !!ssrc0.sourceHeight && ssrc0.direction === "out",
@@ -3968,6 +3968,37 @@ function getNumberOfTemporalLayers(consumer) {
3968
3968
  var _a, _b, _c;
3969
3969
  return /T3/.test(((_c = (_b = (_a = consumer._rtpParameters) === null || _a === void 0 ? void 0 : _a.encodings) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.scalabilityMode) || "") ? 3 : 2;
3970
3970
  }
3971
+ function addProducerCpuOveruseWatch({ producer, onOveruse }) {
3972
+ var _a;
3973
+ const encodings = (_a = producer.rtpParameters) === null || _a === void 0 ? void 0 : _a.encodings;
3974
+ let interval = null;
3975
+ if ((encodings === null || encodings === void 0 ? void 0 : encodings.length) === 3) {
3976
+ const { ssrc, rid } = encodings[0];
3977
+ let maxHeight = 0;
3978
+ let ticks = 0;
3979
+ const targetTicksForTrigger = 2;
3980
+ interval = setInterval(() => __awaiter(this, void 0, void 0, function* () {
3981
+ (yield producer.getStats()).forEach((report) => {
3982
+ if (report.type === "outbound-rtp" && ((ssrc && report.ssrc === ssrc) || (rid && report.rid === rid))) {
3983
+ if (maxHeight && report.frameHeight && report.frameHeight < maxHeight) {
3984
+ ticks++;
3985
+ if (ticks >= targetTicksForTrigger) {
3986
+ onOveruse();
3987
+ }
3988
+ }
3989
+ else {
3990
+ ticks = 0;
3991
+ }
3992
+ maxHeight = Math.max(maxHeight, report.frameHeight || 0);
3993
+ }
3994
+ });
3995
+ }), 2000);
3996
+ }
3997
+ return () => {
3998
+ if (interval)
3999
+ clearInterval(interval);
4000
+ };
4001
+ }
3971
4002
 
3972
4003
  class SfuV2Parser {
3973
4004
  static parse(raw) {
@@ -4433,6 +4464,7 @@ class VegaRtcManager {
4433
4464
  this._emitToPWA(PROTOCOL_EVENTS.MEDIA_QUALITY_CHANGED, payload);
4434
4465
  });
4435
4466
  this._networkIsDetectedUpBySignal = false;
4467
+ this._cpuOveruseDetected = false;
4436
4468
  }
4437
4469
  _updateAndScheduleMediaServersRefresh({ iceServers, turnServers, sfuServer, sfuServers, mediaserverConfigTtlSeconds, }) {
4438
4470
  var _a, _b, _c;
@@ -4924,6 +4956,23 @@ class VegaRtcManager {
4924
4956
  this._internalSetupMicScore();
4925
4957
  }
4926
4958
  }
4959
+ _syncResourceUsage() {
4960
+ var _a;
4961
+ if (this._webcamProducer) {
4962
+ const simulcastLayer3ShouldBeActive = !this._cpuOveruseDetected;
4963
+ const params = this._webcamProducer.rtpParameters;
4964
+ if (((_a = params === null || params === void 0 ? void 0 : params.encodings) === null || _a === void 0 ? void 0 : _a.length) === 3) {
4965
+ const targetMaxSpatialLayer = simulcastLayer3ShouldBeActive ? 2 : 1;
4966
+ if (this._webcamProducer.maxSpatialLayer !== targetMaxSpatialLayer) {
4967
+ this._webcamProducer.setMaxSpatialLayer(targetMaxSpatialLayer);
4968
+ rtcStats.sendEvent("simulcast_layer_activation_changed", {
4969
+ layerIndex: 2,
4970
+ active: simulcastLayer3ShouldBeActive,
4971
+ });
4972
+ }
4973
+ }
4974
+ }
4975
+ }
4927
4976
  _internalSendWebcam() {
4928
4977
  return __awaiter(this, void 0, void 0, function* () {
4929
4978
  var _a;
@@ -4946,6 +4995,17 @@ class VegaRtcManager {
4946
4995
  paused: currentPaused,
4947
4996
  } }));
4948
4997
  currentPaused ? producer.pause() : producer.resume();
4998
+ const cleanUpCpuWatch = this._features.producerCpuOveruseWatchOn
4999
+ ? addProducerCpuOveruseWatch({
5000
+ producer,
5001
+ onOveruse: () => {
5002
+ rtcStats.sendEvent("producer_cpuoveruse_detected", {});
5003
+ cleanUpCpuWatch();
5004
+ this._cpuOveruseDetected = true;
5005
+ this._syncResourceUsage();
5006
+ },
5007
+ })
5008
+ : () => { };
4949
5009
  this._webcamProducer = producer;
4950
5010
  this._qualityMonitor.addProducer(this._selfId, producer.id);
4951
5011
  producer.observer.once("close", () => {
@@ -4953,6 +5013,7 @@ class VegaRtcManager {
4953
5013
  logger$2.info('webcamProducer "close" event');
4954
5014
  if (producer.appData.localClosed)
4955
5015
  (_a = this._vegaConnection) === null || _a === void 0 ? void 0 : _a.message("closeProducers", { producerIds: [producer.id] });
5016
+ cleanUpCpuWatch();
4956
5017
  this._webcamProducer = null;
4957
5018
  this._webcamProducerPromise = null;
4958
5019
  this._qualityMonitor.removeProducer(this._selfId, producer.id);
@@ -6064,6 +6125,17 @@ const metrics = [
6064
6125
  enabled: ({ hasLiveTrack, track, trackStats, ssrc0, kind }) => hasLiveTrack && kind === "video" && !!trackStats && !!track && !!ssrc0 && !!ssrc0.height,
6065
6126
  value: ({ trackStats }) => Object.values((trackStats === null || trackStats === void 0 ? void 0 : trackStats.ssrcs) || {}).reduce((max, ssrc) => Math.max(max, ssrc.fps || 0 > 0 ? ssrc.height || 0 : 0), 0),
6066
6127
  },
6128
+ {
6129
+ id: "layer0-height",
6130
+ enabled: ({ hasLiveTrack, track, ssrc0, kind }) => hasLiveTrack &&
6131
+ kind === "video" &&
6132
+ !!track &&
6133
+ !!ssrc0 &&
6134
+ !!ssrc0.height &&
6135
+ !!ssrc0.fps &&
6136
+ ssrc0.direction === "out",
6137
+ value: ({ ssrc0 }) => (ssrc0 === null || ssrc0 === void 0 ? void 0 : ssrc0.height) || 0,
6138
+ },
6067
6139
  {
6068
6140
  id: "sourceHeight",
6069
6141
  enabled: ({ hasLiveTrack, track, ssrc0, kind }) => hasLiveTrack && kind === "video" && !!track && !!ssrc0 && !!ssrc0.sourceHeight && ssrc0.direction === "out",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@whereby.com/media",
3
3
  "description": "Media library for Whereby",
4
- "version": "2.2.0",
4
+ "version": "2.4.0",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/whereby/sdk",
7
7
  "repository": {