@stream-io/video-client 1.11.3 → 1.11.4

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/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
4
4
 
5
+ ## [1.11.4](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.11.3...@stream-io/video-client-1.11.4) (2024-11-21)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * experimental option to force single codec preference in the SDP ([#1581](https://github.com/GetStream/stream-video-js/issues/1581)) ([894a86e](https://github.com/GetStream/stream-video-js/commit/894a86e407dc0dd36b7463bb964c86da0c3055d1))
11
+
5
12
  ## [1.11.3](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.11.2...@stream-io/video-client-1.11.3) (2024-11-20)
6
13
 
7
14
 
@@ -3335,7 +3335,7 @@ const retryable = async (rpc, signal) => {
3335
3335
  return result;
3336
3336
  };
3337
3337
 
3338
- const version = "1.11.3";
3338
+ const version = "1.11.4";
3339
3339
  const [major, minor, patch] = version.split('.');
3340
3340
  let sdkInfo = {
3341
3341
  type: SdkType.PLAIN_JAVASCRIPT,
@@ -3470,7 +3470,7 @@ const getPreferredCodecs = (kind, preferredCodec, codecToRemove) => {
3470
3470
  continue;
3471
3471
  }
3472
3472
  const sdpFmtpLine = codec.sdpFmtpLine;
3473
- if (!sdpFmtpLine || !sdpFmtpLine.includes('profile-level-id=42e01f')) {
3473
+ if (!sdpFmtpLine || !sdpFmtpLine.includes('profile-level-id=42')) {
3474
3474
  // this is not the baseline h264 codec, prioritize it lower
3475
3475
  partiallyPreferred.push(codec);
3476
3476
  continue;
@@ -5497,6 +5497,50 @@ const toggleDtx = (sdp, enable) => {
5497
5497
  : `${opusFmtp.original};${requiredDtxConfig}`;
5498
5498
  return sdp.replace(opusFmtp.original, newFmtp);
5499
5499
  };
5500
+ /**
5501
+ * Returns and SDP with all the codecs except the given codec removed.
5502
+ */
5503
+ const preserveCodec = (sdp, mid, codec) => {
5504
+ const [kind, codecName] = codec.mimeType.toLowerCase().split('/');
5505
+ const toSet = (fmtpLine) => new Set(fmtpLine.split(';').map((f) => f.trim().toLowerCase()));
5506
+ const equal = (a, b) => {
5507
+ if (a.size !== b.size)
5508
+ return false;
5509
+ for (const item of a)
5510
+ if (!b.has(item))
5511
+ return false;
5512
+ return true;
5513
+ };
5514
+ const codecFmtp = toSet(codec.sdpFmtpLine || '');
5515
+ const parsedSdp = SDP.parse(sdp);
5516
+ for (const media of parsedSdp.media) {
5517
+ if (media.type !== kind || String(media.mid) !== mid)
5518
+ continue;
5519
+ // find the payload id of the desired codec
5520
+ const payloads = new Set();
5521
+ for (const rtp of media.rtp) {
5522
+ if (rtp.codec.toLowerCase() === codecName &&
5523
+ media.fmtp.some((f) => f.payload === rtp.payload && equal(toSet(f.config), codecFmtp))) {
5524
+ payloads.add(rtp.payload);
5525
+ }
5526
+ }
5527
+ // find the corresponding rtx codec by matching apt=<preserved-codec-payload>
5528
+ for (const fmtp of media.fmtp) {
5529
+ const match = fmtp.config.match(/(apt)=(\d+)/);
5530
+ if (!match)
5531
+ continue;
5532
+ const [, , preservedCodecPayload] = match;
5533
+ if (payloads.has(Number(preservedCodecPayload))) {
5534
+ payloads.add(fmtp.payload);
5535
+ }
5536
+ }
5537
+ media.rtp = media.rtp.filter((r) => payloads.has(r.payload));
5538
+ media.fmtp = media.fmtp.filter((f) => payloads.has(f.payload));
5539
+ media.rtcpFb = media.rtcpFb?.filter((f) => payloads.has(f.payload));
5540
+ media.payloads = Array.from(payloads).join(' ');
5541
+ }
5542
+ return SDP.write(parsedSdp);
5543
+ };
5500
5544
  /**
5501
5545
  * Enables high-quality audio through SDP munging for the given trackMid.
5502
5546
  *
@@ -5900,6 +5944,12 @@ class Publisher {
5900
5944
  if (this.isPublishing(TrackType.SCREEN_SHARE_AUDIO)) {
5901
5945
  offer.sdp = this.enableHighQualityAudio(offer.sdp);
5902
5946
  }
5947
+ if (this.isPublishing(TrackType.VIDEO)) {
5948
+ // Hotfix for platforms that don't respect the ordered codec list
5949
+ // (Firefox, Android, Linux, etc...).
5950
+ // We remove all the codecs from the SDP except the one we want to use.
5951
+ offer.sdp = this.removeUnpreferredCodecs(offer.sdp, TrackType.VIDEO);
5952
+ }
5903
5953
  }
5904
5954
  const trackInfos = this.getAnnouncedTracks(offer.sdp);
5905
5955
  if (trackInfos.length === 0) {
@@ -6061,6 +6111,22 @@ class Publisher {
6061
6111
  });
6062
6112
  });
6063
6113
  }
6114
+ removeUnpreferredCodecs(sdp, trackType) {
6115
+ const opts = this.publishOptsForTrack.get(trackType);
6116
+ if (!opts || !opts.forceSingleCodec)
6117
+ return sdp;
6118
+ const codec = opts.forceCodec || opts.preferredCodec;
6119
+ const orderedCodecs = this.getCodecPreferences(trackType, codec);
6120
+ if (!orderedCodecs || orderedCodecs.length === 0)
6121
+ return sdp;
6122
+ const transceiver = this.transceiverCache.get(trackType);
6123
+ if (!transceiver)
6124
+ return sdp;
6125
+ const index = this.transceiverInitOrder.indexOf(trackType);
6126
+ const mid = extractMid(transceiver, index, sdp);
6127
+ const [codecToPreserve] = orderedCodecs;
6128
+ return preserveCodec(sdp, mid, codecToPreserve);
6129
+ }
6064
6130
  }
6065
6131
 
6066
6132
  /**
@@ -12978,7 +13044,7 @@ class StreamClient {
12978
13044
  });
12979
13045
  };
12980
13046
  this.getUserAgent = () => {
12981
- const version = "1.11.3";
13047
+ const version = "1.11.4";
12982
13048
  return (this.userAgent ||
12983
13049
  `stream-video-javascript-client-${this.node ? 'node' : 'browser'}-${version}`);
12984
13050
  };