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