@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 +19 -0
- package/dist/index.browser.es.js +50 -24
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +50 -24
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +50 -24
- package/dist/index.es.js.map +1 -1
- package/dist/src/sorting/participants.d.ts +5 -2
- package/package.json +20 -21
- package/src/Call.ts +1 -0
- package/src/devices/SpeakerManager.ts +9 -6
- package/src/devices/__tests__/SpeakerManager.test.ts +8 -5
- package/src/rtc/__tests__/layers.test.ts +99 -74
- package/src/sorting/__tests__/sorting.test.ts +106 -0
- package/src/sorting/participants.ts +30 -14
- package/src/sorting/presets.ts +14 -2
- package/src/store/__tests__/CallState.test.ts +7 -12
package/dist/index.es.js
CHANGED
|
@@ -4581,9 +4581,11 @@ const speaking = (a, b) => {
|
|
|
4581
4581
|
* @param b the second participant.
|
|
4582
4582
|
*/
|
|
4583
4583
|
const screenSharing = (a, b) => {
|
|
4584
|
-
|
|
4584
|
+
const hasA = hasScreenShare(a);
|
|
4585
|
+
const hasB = hasScreenShare(b);
|
|
4586
|
+
if (hasA && !hasB)
|
|
4585
4587
|
return -1;
|
|
4586
|
-
if (!
|
|
4588
|
+
if (!hasA && hasB)
|
|
4587
4589
|
return 1;
|
|
4588
4590
|
return 0;
|
|
4589
4591
|
};
|
|
@@ -4594,9 +4596,11 @@ const screenSharing = (a, b) => {
|
|
|
4594
4596
|
* @param b the second participant.
|
|
4595
4597
|
*/
|
|
4596
4598
|
const publishingVideo = (a, b) => {
|
|
4597
|
-
|
|
4599
|
+
const hasA = hasVideo(a);
|
|
4600
|
+
const hasB = hasVideo(b);
|
|
4601
|
+
if (hasA && !hasB)
|
|
4598
4602
|
return -1;
|
|
4599
|
-
if (!
|
|
4603
|
+
if (!hasA && hasB)
|
|
4600
4604
|
return 1;
|
|
4601
4605
|
return 0;
|
|
4602
4606
|
};
|
|
@@ -4607,9 +4611,11 @@ const publishingVideo = (a, b) => {
|
|
|
4607
4611
|
* @param b the second participant.
|
|
4608
4612
|
*/
|
|
4609
4613
|
const publishingAudio = (a, b) => {
|
|
4610
|
-
|
|
4614
|
+
const hasA = hasAudio(a);
|
|
4615
|
+
const hasB = hasAudio(b);
|
|
4616
|
+
if (hasA && !hasB)
|
|
4611
4617
|
return -1;
|
|
4612
|
-
if (!
|
|
4618
|
+
if (!hasA && hasB)
|
|
4613
4619
|
return 1;
|
|
4614
4620
|
return 0;
|
|
4615
4621
|
};
|
|
@@ -4640,14 +4646,22 @@ const pinned = (a, b) => {
|
|
|
4640
4646
|
* A comparator creator which will set up a comparator which prioritizes
|
|
4641
4647
|
* participants who are from a specific source (e.g., WebRTC, RTMP, WHIP...).
|
|
4642
4648
|
*
|
|
4643
|
-
*
|
|
4649
|
+
* The priority of a source is determined by the order of the sources passed in.
|
|
4650
|
+
* e.g. [SRT, RTMP, WHIP] will prioritize SRT sources first, then RTMP, then WHIP.
|
|
4651
|
+
*
|
|
4652
|
+
* @param sources the sources to prioritize.
|
|
4644
4653
|
*/
|
|
4645
|
-
const withParticipantSource = (
|
|
4646
|
-
|
|
4647
|
-
|
|
4648
|
-
|
|
4649
|
-
|
|
4650
|
-
|
|
4654
|
+
const withParticipantSource = (...sources) => {
|
|
4655
|
+
const priority = (i) => (i === -1 ? Number.MAX_SAFE_INTEGER : i);
|
|
4656
|
+
return (a, b) => {
|
|
4657
|
+
const priorityA = priority(sources.indexOf(a.source));
|
|
4658
|
+
const priorityB = priority(sources.indexOf(b.source));
|
|
4659
|
+
if (priorityA < priorityB)
|
|
4660
|
+
return -1;
|
|
4661
|
+
if (priorityA > priorityB)
|
|
4662
|
+
return 1;
|
|
4663
|
+
return 0;
|
|
4664
|
+
};
|
|
4651
4665
|
};
|
|
4652
4666
|
/**
|
|
4653
4667
|
* A comparator creator which will set up a comparator which prioritizes
|
|
@@ -4671,9 +4685,11 @@ const reactionType = (type) => {
|
|
|
4671
4685
|
* @param roles the roles to prioritize.
|
|
4672
4686
|
*/
|
|
4673
4687
|
const role = (...roles) => (a, b) => {
|
|
4674
|
-
|
|
4688
|
+
const hasA = hasAnyRole(a, roles);
|
|
4689
|
+
const hasB = hasAnyRole(b, roles);
|
|
4690
|
+
if (hasA && !hasB)
|
|
4675
4691
|
return -1;
|
|
4676
|
-
if (!
|
|
4692
|
+
if (!hasA && hasB)
|
|
4677
4693
|
return 1;
|
|
4678
4694
|
return 0;
|
|
4679
4695
|
};
|
|
@@ -4706,6 +4722,10 @@ const ifInvisibleOrUnknownBy = conditional((a, b) => a.viewportVisibilityState?.
|
|
|
4706
4722
|
a.viewportVisibilityState?.videoTrack === VisibilityState.UNKNOWN ||
|
|
4707
4723
|
b.viewportVisibilityState?.videoTrack === VisibilityState.INVISIBLE ||
|
|
4708
4724
|
b.viewportVisibilityState?.videoTrack === VisibilityState.UNKNOWN);
|
|
4725
|
+
/**
|
|
4726
|
+
* A comparator that prioritizes participants with video ingress sources.
|
|
4727
|
+
*/
|
|
4728
|
+
const withVideoIngressSource = withParticipantSource(ParticipantSource.RTMP, ParticipantSource.SRT, ParticipantSource.WHIP, ParticipantSource.RTSP);
|
|
4709
4729
|
/**
|
|
4710
4730
|
* The default sorting preset.
|
|
4711
4731
|
*/
|
|
@@ -4713,16 +4733,16 @@ const defaultSortPreset = combineComparators(screenSharing, pinned, ifInvisibleB
|
|
|
4713
4733
|
/**
|
|
4714
4734
|
* The sorting preset for speaker layout.
|
|
4715
4735
|
*/
|
|
4716
|
-
const speakerLayoutSortPreset = combineComparators(screenSharing, pinned, dominantSpeaker, ifInvisibleBy(combineComparators(speaking, reactionType('raised-hand'), publishingVideo, publishingAudio)));
|
|
4736
|
+
const speakerLayoutSortPreset = combineComparators(screenSharing, pinned, dominantSpeaker, ifInvisibleBy(combineComparators(speaking, reactionType('raised-hand'), withVideoIngressSource, publishingVideo, publishingAudio)));
|
|
4717
4737
|
/**
|
|
4718
4738
|
* The sorting preset for layouts that don't render all participants but
|
|
4719
4739
|
* instead, render them in pages.
|
|
4720
4740
|
*/
|
|
4721
|
-
const paginatedLayoutSortPreset = combineComparators(pinned, ifInvisibleOrUnknownBy(combineComparators(dominantSpeaker, speaking, reactionType('raised-hand'), publishingVideo, publishingAudio)));
|
|
4741
|
+
const paginatedLayoutSortPreset = combineComparators(pinned, ifInvisibleOrUnknownBy(combineComparators(dominantSpeaker, speaking, reactionType('raised-hand'), withVideoIngressSource, publishingVideo, publishingAudio)));
|
|
4722
4742
|
/**
|
|
4723
4743
|
* The sorting preset for livestreams and audio rooms.
|
|
4724
4744
|
*/
|
|
4725
|
-
const livestreamOrAudioRoomSortPreset = combineComparators(ifInvisibleBy(combineComparators(dominantSpeaker, speaking, reactionType('raised-hand'),
|
|
4745
|
+
const livestreamOrAudioRoomSortPreset = combineComparators(ifInvisibleBy(combineComparators(dominantSpeaker, speaking, reactionType('raised-hand'), withVideoIngressSource, publishingVideo, publishingAudio)), role('admin', 'host', 'speaker'));
|
|
4726
4746
|
|
|
4727
4747
|
/**
|
|
4728
4748
|
* Returns the default egress object - when no egress data is available.
|
|
@@ -5834,7 +5854,7 @@ const getSdkVersion = (sdk) => {
|
|
|
5834
5854
|
return sdk ? `${sdk.major}.${sdk.minor}.${sdk.patch}` : '0.0.0-development';
|
|
5835
5855
|
};
|
|
5836
5856
|
|
|
5837
|
-
const version = "1.
|
|
5857
|
+
const version = "1.34.0";
|
|
5838
5858
|
const [major, minor, patch] = version.split('.');
|
|
5839
5859
|
let sdkInfo = {
|
|
5840
5860
|
type: SdkType.PLAIN_JAVASCRIPT,
|
|
@@ -11624,13 +11644,18 @@ class SpeakerManager {
|
|
|
11624
11644
|
* @param volume a number between 0 and 1. Set it to `undefined` to use the default volume.
|
|
11625
11645
|
*/
|
|
11626
11646
|
setParticipantVolume(sessionId, volume) {
|
|
11627
|
-
if (isReactNative()) {
|
|
11628
|
-
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');
|
|
11629
|
-
}
|
|
11630
11647
|
if (volume && (volume < 0 || volume > 1)) {
|
|
11631
11648
|
throw new Error('Volume must be between 0 and 1, or undefined');
|
|
11632
11649
|
}
|
|
11633
|
-
this.call.state.updateParticipant(sessionId,
|
|
11650
|
+
this.call.state.updateParticipant(sessionId, (p) => {
|
|
11651
|
+
if (isReactNative() && p.audioStream) {
|
|
11652
|
+
for (const track of p.audioStream.getAudioTracks()) {
|
|
11653
|
+
// @ts-expect-error track._setVolume is present in react-native-webrtc
|
|
11654
|
+
track?._setVolume(volume);
|
|
11655
|
+
}
|
|
11656
|
+
}
|
|
11657
|
+
return { audioVolume: volume };
|
|
11658
|
+
});
|
|
11634
11659
|
}
|
|
11635
11660
|
}
|
|
11636
11661
|
|
|
@@ -12444,6 +12469,7 @@ class Call {
|
|
|
12444
12469
|
});
|
|
12445
12470
|
}
|
|
12446
12471
|
this.tracer.setEnabled(enableTracing);
|
|
12472
|
+
this.sfuStatsReporter?.flush();
|
|
12447
12473
|
this.sfuStatsReporter?.stop();
|
|
12448
12474
|
if (statsOptions?.reporting_interval_ms > 0) {
|
|
12449
12475
|
this.sfuStatsReporter = new SfuStatsReporter(sfuClient, {
|
|
@@ -14777,7 +14803,7 @@ class StreamClient {
|
|
|
14777
14803
|
this.getUserAgent = () => {
|
|
14778
14804
|
if (!this.cachedUserAgent) {
|
|
14779
14805
|
const { clientAppIdentifier = {} } = this.options;
|
|
14780
|
-
const { sdkName = 'js', sdkVersion = "1.
|
|
14806
|
+
const { sdkName = 'js', sdkVersion = "1.34.0", ...extras } = clientAppIdentifier;
|
|
14781
14807
|
this.cachedUserAgent = [
|
|
14782
14808
|
`stream-video-${sdkName}-v${sdkVersion}`,
|
|
14783
14809
|
...Object.entries(extras).map(([key, value]) => `${key}=${value}`),
|