@stream-io/video-client 1.11.7 → 1.11.9

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,20 @@
2
2
 
3
3
  This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
4
4
 
5
+ ## [1.11.9](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.11.8...@stream-io/video-client-1.11.9) (2024-11-27)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * cover some device selection edge cases ([#1604](https://github.com/GetStream/stream-video-js/issues/1604)) ([a8fc0ea](https://github.com/GetStream/stream-video-js/commit/a8fc0eaf1ed6c79ce24f77f52351a1e90701bd02))
11
+
12
+ ## [1.11.8](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.11.7...@stream-io/video-client-1.11.8) (2024-11-27)
13
+
14
+
15
+ ### Bug Fixes
16
+
17
+ * **ios:** use vp8 when h264 constrainted baseline isn't available ([#1597](https://github.com/GetStream/stream-video-js/issues/1597)) ([6281216](https://github.com/GetStream/stream-video-js/commit/62812161cef5e9917c504dbc4cd9257709ea5fa1))
18
+
5
19
  ## [1.11.7](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.11.6...@stream-io/video-client-1.11.7) (2024-11-26)
6
20
 
7
21
 
@@ -3297,7 +3297,7 @@ const retryable = async (rpc, signal) => {
3297
3297
  return result;
3298
3298
  };
3299
3299
 
3300
- const version = "1.11.7";
3300
+ const version = "1.11.9";
3301
3301
  const [major, minor, patch] = version.split('.');
3302
3302
  let sdkInfo = {
3303
3303
  type: SdkType.PLAIN_JAVASCRIPT,
@@ -3403,7 +3403,7 @@ var browsers = /*#__PURE__*/Object.freeze({
3403
3403
  * @param codecToRemove the codec to exclude from the list.
3404
3404
  * @param codecPreferencesSource the source of the codec preferences.
3405
3405
  */
3406
- const getPreferredCodecs = (kind, preferredCodec, codecToRemove, codecPreferencesSource = 'receiver') => {
3406
+ const getPreferredCodecs = (kind, preferredCodec, codecToRemove, codecPreferencesSource) => {
3407
3407
  const source = codecPreferencesSource === 'receiver' ? RTCRtpReceiver : RTCRtpSender;
3408
3408
  if (!('getCapabilities' in source))
3409
3409
  return;
@@ -3439,10 +3439,7 @@ const getPreferredCodecs = (kind, preferredCodec, codecToRemove, codecPreference
3439
3439
  partiallyPreferred.push(codec);
3440
3440
  continue;
3441
3441
  }
3442
- // packetization-mode mode is optional; when not present it defaults to 0:
3443
- // https://datatracker.ietf.org/doc/html/rfc6184#section-6.2
3444
- if (sdpFmtpLine.includes('packetization-mode=0') ||
3445
- !sdpFmtpLine.includes('packetization-mode')) {
3442
+ if (sdpFmtpLine.includes('packetization-mode=1')) {
3446
3443
  preferred.unshift(codec);
3447
3444
  }
3448
3445
  else {
@@ -3479,8 +3476,9 @@ const getOptimalVideoCodec = (preferredCodec) => {
3479
3476
  const os = getOSInfo()?.name.toLowerCase();
3480
3477
  if (os === 'android')
3481
3478
  return preferredOr(preferredCodec, 'vp8');
3482
- if (os === 'ios' || os === 'ipados')
3483
- return 'h264';
3479
+ if (os === 'ios' || os === 'ipados') {
3480
+ return supportsH264Baseline() ? 'h264' : 'vp8';
3481
+ }
3484
3482
  return preferredOr(preferredCodec, 'h264');
3485
3483
  }
3486
3484
  if (isSafari())
@@ -3511,6 +3509,18 @@ const preferredOr = (codec, fallback) => {
3511
3509
  ? codec
3512
3510
  : fallback;
3513
3511
  };
3512
+ /**
3513
+ * Returns whether the platform supports the H264 baseline codec.
3514
+ */
3515
+ const supportsH264Baseline = () => {
3516
+ if (!('getCapabilities' in RTCRtpSender))
3517
+ return false;
3518
+ const capabilities = RTCRtpSender.getCapabilities('video');
3519
+ if (!capabilities)
3520
+ return false;
3521
+ return capabilities.codecs.some((c) => c.mimeType.toLowerCase() === 'video/h264' &&
3522
+ c.sdpFmtpLine?.includes('profile-level-id=42e01f'));
3523
+ };
3514
3524
  /**
3515
3525
  * Returns whether the codec is an SVC codec.
3516
3526
  *
@@ -5483,8 +5493,14 @@ const preserveCodec = (sdp, mid, codec) => {
5483
5493
  // find the payload id of the desired codec
5484
5494
  const payloads = new Set();
5485
5495
  for (const rtp of media.rtp) {
5486
- if (rtp.codec.toLowerCase() === codecName &&
5487
- media.fmtp.some((f) => f.payload === rtp.payload && equal(toSet(f.config), codecFmtp))) {
5496
+ if (rtp.codec.toLowerCase() !== codecName)
5497
+ continue;
5498
+ const match =
5499
+ // vp8 doesn't have any fmtp, we preserve it without any additional checks
5500
+ codecName === 'vp8'
5501
+ ? true
5502
+ : media.fmtp.some((f) => f.payload === rtp.payload && equal(toSet(f.config), codecFmtp));
5503
+ if (match) {
5488
5504
  payloads.add(rtp.payload);
5489
5505
  }
5490
5506
  }
@@ -5686,7 +5702,7 @@ class Publisher {
5686
5702
  // handle codec preferences
5687
5703
  if (!('setCodecPreferences' in transceiver))
5688
5704
  return;
5689
- const codecPreferences = this.getCodecPreferences(trackType, trackType === TrackType.VIDEO ? codecInUse : undefined);
5705
+ const codecPreferences = this.getCodecPreferences(trackType, trackType === TrackType.VIDEO ? codecInUse : undefined, 'receiver');
5690
5706
  if (!codecPreferences)
5691
5707
  return;
5692
5708
  try {
@@ -5847,12 +5863,12 @@ class Publisher {
5847
5863
  };
5848
5864
  this.getCodecPreferences = (trackType, preferredCodec, codecPreferencesSource) => {
5849
5865
  if (trackType === TrackType.VIDEO) {
5850
- return getPreferredCodecs('video', preferredCodec || 'vp8', codecPreferencesSource);
5866
+ return getPreferredCodecs('video', preferredCodec || 'vp8', undefined, codecPreferencesSource);
5851
5867
  }
5852
5868
  if (trackType === TrackType.AUDIO) {
5853
5869
  const defaultAudioCodec = this.isRedEnabled ? 'red' : 'opus';
5854
5870
  const codecToRemove = !this.isRedEnabled ? 'red' : undefined;
5855
- return getPreferredCodecs('audio', preferredCodec ?? defaultAudioCodec, codecToRemove);
5871
+ return getPreferredCodecs('audio', preferredCodec ?? defaultAudioCodec, codecToRemove, codecPreferencesSource);
5856
5872
  }
5857
5873
  };
5858
5874
  this.onIceCandidate = (e) => {
@@ -6077,7 +6093,8 @@ class Publisher {
6077
6093
  }
6078
6094
  removeUnpreferredCodecs(sdp, trackType) {
6079
6095
  const opts = this.publishOptsForTrack.get(trackType);
6080
- if (!opts || !opts.forceSingleCodec)
6096
+ const forceSingleCodec = !!opts?.forceSingleCodec || isReactNative() || isFirefox();
6097
+ if (!opts || !forceSingleCodec)
6081
6098
  return sdp;
6082
6099
  const codec = opts.forceCodec || getOptimalVideoCodec(opts.preferredCodec);
6083
6100
  const orderedCodecs = this.getCodecPreferences(trackType, codec, 'sender');
@@ -8327,7 +8344,7 @@ const getAudioStream = async (trackConstraints) => {
8327
8344
  const constraints = {
8328
8345
  audio: {
8329
8346
  ...audioDeviceConstraints.audio,
8330
- ...trackConstraints,
8347
+ ...normalizeContraints(trackConstraints),
8331
8348
  },
8332
8349
  };
8333
8350
  try {
@@ -8338,11 +8355,6 @@ const getAudioStream = async (trackConstraints) => {
8338
8355
  return await getStream(constraints);
8339
8356
  }
8340
8357
  catch (error) {
8341
- if (error instanceof OverconstrainedError && trackConstraints?.deviceId) {
8342
- const { deviceId, ...relaxedContraints } = trackConstraints;
8343
- getLogger(['devices'])('warn', 'Failed to get audio stream, will try again with relaxed contraints', { error, constraints, relaxedContraints });
8344
- return getAudioStream(relaxedContraints);
8345
- }
8346
8358
  getLogger(['devices'])('error', 'Failed to get audio stream', {
8347
8359
  error,
8348
8360
  constraints,
@@ -8362,7 +8374,7 @@ const getVideoStream = async (trackConstraints) => {
8362
8374
  const constraints = {
8363
8375
  video: {
8364
8376
  ...videoDeviceConstraints.video,
8365
- ...trackConstraints,
8377
+ ...normalizeContraints(trackConstraints),
8366
8378
  },
8367
8379
  };
8368
8380
  try {
@@ -8373,11 +8385,6 @@ const getVideoStream = async (trackConstraints) => {
8373
8385
  return await getStream(constraints);
8374
8386
  }
8375
8387
  catch (error) {
8376
- if (error instanceof OverconstrainedError && trackConstraints?.deviceId) {
8377
- const { deviceId, ...relaxedContraints } = trackConstraints;
8378
- getLogger(['devices'])('warn', 'Failed to get video stream, will try again with relaxed contraints', { error, constraints, relaxedContraints });
8379
- return getVideoStream(relaxedContraints);
8380
- }
8381
8388
  getLogger(['devices'])('error', 'Failed to get video stream', {
8382
8389
  error,
8383
8390
  constraints,
@@ -8385,6 +8392,16 @@ const getVideoStream = async (trackConstraints) => {
8385
8392
  throw error;
8386
8393
  }
8387
8394
  };
8395
+ function normalizeContraints(constraints) {
8396
+ if (constraints?.deviceId === 'default' ||
8397
+ (typeof constraints?.deviceId === 'object' &&
8398
+ 'exact' in constraints.deviceId &&
8399
+ constraints.deviceId.exact === 'default')) {
8400
+ const { deviceId, ...contraintsWithoutDeviceId } = constraints;
8401
+ return contraintsWithoutDeviceId;
8402
+ }
8403
+ return constraints;
8404
+ }
8388
8405
  /**
8389
8406
  * Prompts the user for a permission to share a screen.
8390
8407
  * If the user grants the permission, a screen sharing stream is returned. Throws otherwise.
@@ -8611,6 +8628,7 @@ class InputMediaDeviceManager {
8611
8628
  }
8612
8629
  catch (error) {
8613
8630
  this.state.setDevice(prevDeviceId);
8631
+ await this.applySettingsToStream();
8614
8632
  throw error;
8615
8633
  }
8616
8634
  }
@@ -12596,7 +12614,7 @@ class StreamClient {
12596
12614
  return await this.wsConnection.connect(this.defaultWSTimeout);
12597
12615
  };
12598
12616
  this.getUserAgent = () => {
12599
- const version = "1.11.7";
12617
+ const version = "1.11.9";
12600
12618
  return (this.userAgent ||
12601
12619
  `stream-video-javascript-client-${this.node ? 'node' : 'browser'}-${version}`);
12602
12620
  };