@stream-io/video-client 1.33.0 → 1.34.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/CHANGELOG.md CHANGED
@@ -2,6 +2,25 @@
2
2
 
3
3
  This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
4
4
 
5
+ ## [1.34.0](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.33.1...@stream-io/video-client-1.34.0) (2025-10-14)
6
+
7
+ - use fromPartial instead of suppressing ts-errors ([#1949](https://github.com/GetStream/stream-video-js/issues/1949)) ([95e5654](https://github.com/GetStream/stream-video-js/commit/95e5654e2bac5dc7c5126079795fca9951652290))
8
+
9
+ ### Features
10
+
11
+ - **deps:** React 19.1, React Native 0.81, NextJS 15.5, Expo 54 ([#1940](https://github.com/GetStream/stream-video-js/issues/1940)) ([30f8ce2](https://github.com/GetStream/stream-video-js/commit/30f8ce2b335189e1f77160236839bc6c6a02f634))
12
+ - move audio route manager inside SDK ([#1840](https://github.com/GetStream/stream-video-js/issues/1840)) ([847dd30](https://github.com/GetStream/stream-video-js/commit/847dd30d6240a0780fe3d58d681554bc392f6f51)), closes [#1829](https://github.com/GetStream/stream-video-js/issues/1829)
13
+
14
+ ### Bug Fixes
15
+
16
+ - flush rtc stats when reconnecting ([#1946](https://github.com/GetStream/stream-video-js/issues/1946)) ([fb1f6fc](https://github.com/GetStream/stream-video-js/commit/fb1f6fcb2837154a4fe746a6efe4f9a4830bca20))
17
+
18
+ ## [1.33.1](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.33.0...@stream-io/video-client-1.33.1) (2025-10-02)
19
+
20
+ ### Bug Fixes
21
+
22
+ - ensure ingress participants are prioritized ([#1943](https://github.com/GetStream/stream-video-js/issues/1943)) ([a51a119](https://github.com/GetStream/stream-video-js/commit/a51a119cfb9f13736395b4afb3d3947ef994a6d9))
23
+
5
24
  ## [1.33.0](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.32.0...@stream-io/video-client-1.33.0) (2025-09-30)
6
25
 
7
26
  ### Features
@@ -4580,9 +4580,11 @@ const speaking = (a, b) => {
4580
4580
  * @param b the second participant.
4581
4581
  */
4582
4582
  const screenSharing = (a, b) => {
4583
- if (hasScreenShare(a) && !hasScreenShare(b))
4583
+ const hasA = hasScreenShare(a);
4584
+ const hasB = hasScreenShare(b);
4585
+ if (hasA && !hasB)
4584
4586
  return -1;
4585
- if (!hasScreenShare(a) && hasScreenShare(b))
4587
+ if (!hasA && hasB)
4586
4588
  return 1;
4587
4589
  return 0;
4588
4590
  };
@@ -4593,9 +4595,11 @@ const screenSharing = (a, b) => {
4593
4595
  * @param b the second participant.
4594
4596
  */
4595
4597
  const publishingVideo = (a, b) => {
4596
- if (hasVideo(a) && !hasVideo(b))
4598
+ const hasA = hasVideo(a);
4599
+ const hasB = hasVideo(b);
4600
+ if (hasA && !hasB)
4597
4601
  return -1;
4598
- if (!hasVideo(a) && hasVideo(b))
4602
+ if (!hasA && hasB)
4599
4603
  return 1;
4600
4604
  return 0;
4601
4605
  };
@@ -4606,9 +4610,11 @@ const publishingVideo = (a, b) => {
4606
4610
  * @param b the second participant.
4607
4611
  */
4608
4612
  const publishingAudio = (a, b) => {
4609
- if (hasAudio(a) && !hasAudio(b))
4613
+ const hasA = hasAudio(a);
4614
+ const hasB = hasAudio(b);
4615
+ if (hasA && !hasB)
4610
4616
  return -1;
4611
- if (!hasAudio(a) && hasAudio(b))
4617
+ if (!hasA && hasB)
4612
4618
  return 1;
4613
4619
  return 0;
4614
4620
  };
@@ -4639,14 +4645,22 @@ const pinned = (a, b) => {
4639
4645
  * A comparator creator which will set up a comparator which prioritizes
4640
4646
  * participants who are from a specific source (e.g., WebRTC, RTMP, WHIP...).
4641
4647
  *
4642
- * @param source the source to prioritize.
4648
+ * The priority of a source is determined by the order of the sources passed in.
4649
+ * e.g. [SRT, RTMP, WHIP] will prioritize SRT sources first, then RTMP, then WHIP.
4650
+ *
4651
+ * @param sources the sources to prioritize.
4643
4652
  */
4644
- const withParticipantSource = (source) => (a, b) => {
4645
- if (a.source === source && b.source !== source)
4646
- return -1;
4647
- if (a.source !== source && b.source === source)
4648
- return 1;
4649
- return 0;
4653
+ const withParticipantSource = (...sources) => {
4654
+ const priority = (i) => (i === -1 ? Number.MAX_SAFE_INTEGER : i);
4655
+ return (a, b) => {
4656
+ const priorityA = priority(sources.indexOf(a.source));
4657
+ const priorityB = priority(sources.indexOf(b.source));
4658
+ if (priorityA < priorityB)
4659
+ return -1;
4660
+ if (priorityA > priorityB)
4661
+ return 1;
4662
+ return 0;
4663
+ };
4650
4664
  };
4651
4665
  /**
4652
4666
  * A comparator creator which will set up a comparator which prioritizes
@@ -4670,9 +4684,11 @@ const reactionType = (type) => {
4670
4684
  * @param roles the roles to prioritize.
4671
4685
  */
4672
4686
  const role = (...roles) => (a, b) => {
4673
- if (hasAnyRole(a, roles) && !hasAnyRole(b, roles))
4687
+ const hasA = hasAnyRole(a, roles);
4688
+ const hasB = hasAnyRole(b, roles);
4689
+ if (hasA && !hasB)
4674
4690
  return -1;
4675
- if (!hasAnyRole(a, roles) && hasAnyRole(b, roles))
4691
+ if (!hasA && hasB)
4676
4692
  return 1;
4677
4693
  return 0;
4678
4694
  };
@@ -4705,6 +4721,10 @@ const ifInvisibleOrUnknownBy = conditional((a, b) => a.viewportVisibilityState?.
4705
4721
  a.viewportVisibilityState?.videoTrack === VisibilityState.UNKNOWN ||
4706
4722
  b.viewportVisibilityState?.videoTrack === VisibilityState.INVISIBLE ||
4707
4723
  b.viewportVisibilityState?.videoTrack === VisibilityState.UNKNOWN);
4724
+ /**
4725
+ * A comparator that prioritizes participants with video ingress sources.
4726
+ */
4727
+ const withVideoIngressSource = withParticipantSource(ParticipantSource.RTMP, ParticipantSource.SRT, ParticipantSource.WHIP, ParticipantSource.RTSP);
4708
4728
  /**
4709
4729
  * The default sorting preset.
4710
4730
  */
@@ -4712,16 +4732,16 @@ const defaultSortPreset = combineComparators(screenSharing, pinned, ifInvisibleB
4712
4732
  /**
4713
4733
  * The sorting preset for speaker layout.
4714
4734
  */
4715
- const speakerLayoutSortPreset = combineComparators(screenSharing, pinned, dominantSpeaker, ifInvisibleBy(combineComparators(speaking, reactionType('raised-hand'), publishingVideo, publishingAudio)));
4735
+ const speakerLayoutSortPreset = combineComparators(screenSharing, pinned, dominantSpeaker, ifInvisibleBy(combineComparators(speaking, reactionType('raised-hand'), withVideoIngressSource, publishingVideo, publishingAudio)));
4716
4736
  /**
4717
4737
  * The sorting preset for layouts that don't render all participants but
4718
4738
  * instead, render them in pages.
4719
4739
  */
4720
- const paginatedLayoutSortPreset = combineComparators(pinned, ifInvisibleOrUnknownBy(combineComparators(dominantSpeaker, speaking, reactionType('raised-hand'), publishingVideo, publishingAudio)));
4740
+ const paginatedLayoutSortPreset = combineComparators(pinned, ifInvisibleOrUnknownBy(combineComparators(dominantSpeaker, speaking, reactionType('raised-hand'), withVideoIngressSource, publishingVideo, publishingAudio)));
4721
4741
  /**
4722
4742
  * The sorting preset for livestreams and audio rooms.
4723
4743
  */
4724
- const livestreamOrAudioRoomSortPreset = combineComparators(ifInvisibleBy(combineComparators(dominantSpeaker, speaking, reactionType('raised-hand'), withParticipantSource(ParticipantSource.RTMP), publishingVideo, publishingAudio)), role('admin', 'host', 'speaker'));
4744
+ const livestreamOrAudioRoomSortPreset = combineComparators(ifInvisibleBy(combineComparators(dominantSpeaker, speaking, reactionType('raised-hand'), withVideoIngressSource, publishingVideo, publishingAudio)), role('admin', 'host', 'speaker'));
4725
4745
 
4726
4746
  /**
4727
4747
  * Returns the default egress object - when no egress data is available.
@@ -5833,7 +5853,7 @@ const getSdkVersion = (sdk) => {
5833
5853
  return sdk ? `${sdk.major}.${sdk.minor}.${sdk.patch}` : '0.0.0-development';
5834
5854
  };
5835
5855
 
5836
- const version = "1.33.0";
5856
+ const version = "1.34.0";
5837
5857
  const [major, minor, patch] = version.split('.');
5838
5858
  let sdkInfo = {
5839
5859
  type: SdkType.PLAIN_JAVASCRIPT,
@@ -11623,13 +11643,18 @@ class SpeakerManager {
11623
11643
  * @param volume a number between 0 and 1. Set it to `undefined` to use the default volume.
11624
11644
  */
11625
11645
  setParticipantVolume(sessionId, volume) {
11626
- if (isReactNative()) {
11627
- throw new Error('This feature is not supported in React Native. Please visit https://getstream.io/video/docs/reactnative/core/camera-and-microphone/#speaker-management for more details');
11628
- }
11629
11646
  if (volume && (volume < 0 || volume > 1)) {
11630
11647
  throw new Error('Volume must be between 0 and 1, or undefined');
11631
11648
  }
11632
- this.call.state.updateParticipant(sessionId, { audioVolume: volume });
11649
+ this.call.state.updateParticipant(sessionId, (p) => {
11650
+ if (isReactNative() && p.audioStream) {
11651
+ for (const track of p.audioStream.getAudioTracks()) {
11652
+ // @ts-expect-error track._setVolume is present in react-native-webrtc
11653
+ track?._setVolume(volume);
11654
+ }
11655
+ }
11656
+ return { audioVolume: volume };
11657
+ });
11633
11658
  }
11634
11659
  }
11635
11660
 
@@ -12443,6 +12468,7 @@ class Call {
12443
12468
  });
12444
12469
  }
12445
12470
  this.tracer.setEnabled(enableTracing);
12471
+ this.sfuStatsReporter?.flush();
12446
12472
  this.sfuStatsReporter?.stop();
12447
12473
  if (statsOptions?.reporting_interval_ms > 0) {
12448
12474
  this.sfuStatsReporter = new SfuStatsReporter(sfuClient, {
@@ -14778,7 +14804,7 @@ class StreamClient {
14778
14804
  this.getUserAgent = () => {
14779
14805
  if (!this.cachedUserAgent) {
14780
14806
  const { clientAppIdentifier = {} } = this.options;
14781
- const { sdkName = 'js', sdkVersion = "1.33.0", ...extras } = clientAppIdentifier;
14807
+ const { sdkName = 'js', sdkVersion = "1.34.0", ...extras } = clientAppIdentifier;
14782
14808
  this.cachedUserAgent = [
14783
14809
  `stream-video-${sdkName}-v${sdkVersion}`,
14784
14810
  ...Object.entries(extras).map(([key, value]) => `${key}=${value}`),