@stream-io/video-react-sdk 1.18.13 → 1.19.1
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 +24 -0
- package/dist/css/styles.css +10 -0
- package/dist/css/styles.css.map +1 -1
- package/dist/index.cjs.js +28 -9
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +29 -10
- package/dist/index.es.js.map +1 -1
- package/dist/src/translations/index.d.ts +1 -0
- package/package.json +5 -5
- package/src/components/BackgroundFilters/BackgroundFilters.tsx +16 -4
- package/src/core/components/ParticipantView/DefaultParticipantViewUI.tsx +14 -2
- package/src/core/components/Video/Video.tsx +6 -1
- package/src/translations/en.json +1 -0
|
@@ -83,6 +83,7 @@ export declare const translations: {
|
|
|
83
83
|
"{{ direction }} picture-in-picture": string;
|
|
84
84
|
"Dominant Speaker": string;
|
|
85
85
|
"Poor connection quality": string;
|
|
86
|
+
"Video paused due to insufficient bandwidth": string;
|
|
86
87
|
Participants: string;
|
|
87
88
|
Anonymous: string;
|
|
88
89
|
"No participants found": string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stream-io/video-react-sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.19.1",
|
|
4
4
|
"main": "./dist/index.cjs.js",
|
|
5
5
|
"module": "./dist/index.es.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -30,9 +30,9 @@
|
|
|
30
30
|
],
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@floating-ui/react": "^0.27.6",
|
|
33
|
-
"@stream-io/video-client": "1.
|
|
33
|
+
"@stream-io/video-client": "1.27.1",
|
|
34
34
|
"@stream-io/video-filters-web": "0.2.1",
|
|
35
|
-
"@stream-io/video-react-bindings": "1.7.
|
|
35
|
+
"@stream-io/video-react-bindings": "1.7.10",
|
|
36
36
|
"chart.js": "^4.4.4",
|
|
37
37
|
"clsx": "^2.0.0",
|
|
38
38
|
"react-chartjs-2": "^5.3.0"
|
|
@@ -45,8 +45,8 @@
|
|
|
45
45
|
"@rollup/plugin-json": "^6.1.0",
|
|
46
46
|
"@rollup/plugin-replace": "^6.0.2",
|
|
47
47
|
"@rollup/plugin-typescript": "^12.1.2",
|
|
48
|
-
"@stream-io/audio-filters-web": "^0.4.
|
|
49
|
-
"@stream-io/video-styling": "^1.
|
|
48
|
+
"@stream-io/audio-filters-web": "^0.4.3",
|
|
49
|
+
"@stream-io/video-styling": "^1.4.0",
|
|
50
50
|
"@types/react": "^19.1.3",
|
|
51
51
|
"@types/react-dom": "^19.1.3",
|
|
52
52
|
"react": "19.0.0",
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
import { flushSync } from 'react-dom';
|
|
11
11
|
import clsx from 'clsx';
|
|
12
12
|
import { useCall } from '@stream-io/video-react-bindings';
|
|
13
|
-
import { disposeOfMediaStream, getLogger } from '@stream-io/video-client';
|
|
13
|
+
import { Call, disposeOfMediaStream, getLogger } from '@stream-io/video-client';
|
|
14
14
|
import {
|
|
15
15
|
BackgroundBlurLevel,
|
|
16
16
|
BackgroundFilter,
|
|
@@ -228,7 +228,7 @@ export const BackgroundFiltersProvider = (
|
|
|
228
228
|
|
|
229
229
|
const BackgroundFilters = (props: { tfLite: TFLite }) => {
|
|
230
230
|
const call = useCall();
|
|
231
|
-
const { children, start } = useRenderer(props.tfLite);
|
|
231
|
+
const { children, start } = useRenderer(props.tfLite, call);
|
|
232
232
|
const { backgroundFilter, onError } = useBackgroundFilters();
|
|
233
233
|
const handleErrorRef = useRef<((error: any) => void) | undefined>(undefined);
|
|
234
234
|
handleErrorRef.current = onError;
|
|
@@ -246,7 +246,7 @@ const BackgroundFilters = (props: { tfLite: TFLite }) => {
|
|
|
246
246
|
return children;
|
|
247
247
|
};
|
|
248
248
|
|
|
249
|
-
const useRenderer = (tfLite: TFLite) => {
|
|
249
|
+
const useRenderer = (tfLite: TFLite, call: Call | undefined) => {
|
|
250
250
|
const { backgroundFilter, backgroundBlurLevel, backgroundImage } =
|
|
251
251
|
useBackgroundFilters();
|
|
252
252
|
const videoRef = useRef<HTMLVideoElement>(null);
|
|
@@ -297,6 +297,11 @@ const useRenderer = (tfLite: TFLite) => {
|
|
|
297
297
|
height: trackSettings.height ?? 0,
|
|
298
298
|
}),
|
|
299
299
|
);
|
|
300
|
+
call?.tracer.trace('backgroundFilters.enable', {
|
|
301
|
+
backgroundFilter,
|
|
302
|
+
backgroundBlurLevel,
|
|
303
|
+
backgroundImage,
|
|
304
|
+
});
|
|
300
305
|
renderer = createRenderer(
|
|
301
306
|
tfLite,
|
|
302
307
|
videoEl,
|
|
@@ -320,13 +325,20 @@ const useRenderer = (tfLite: TFLite) => {
|
|
|
320
325
|
return {
|
|
321
326
|
output,
|
|
322
327
|
stop: () => {
|
|
328
|
+
call?.tracer.trace('backgroundFilters.disable', null);
|
|
323
329
|
renderer?.dispose();
|
|
324
330
|
if (videoRef.current) videoRef.current.srcObject = null;
|
|
325
331
|
if (outputStream) disposeOfMediaStream(outputStream);
|
|
326
332
|
},
|
|
327
333
|
};
|
|
328
334
|
},
|
|
329
|
-
[
|
|
335
|
+
[
|
|
336
|
+
backgroundBlurLevel,
|
|
337
|
+
backgroundFilter,
|
|
338
|
+
backgroundImage,
|
|
339
|
+
call?.tracer,
|
|
340
|
+
tfLite,
|
|
341
|
+
],
|
|
330
342
|
);
|
|
331
343
|
|
|
332
344
|
const children = (
|
|
@@ -2,6 +2,7 @@ import { ComponentType, forwardRef } from 'react';
|
|
|
2
2
|
import { Placement } from '@floating-ui/react';
|
|
3
3
|
import {
|
|
4
4
|
hasAudio,
|
|
5
|
+
hasPausedTrack,
|
|
5
6
|
hasScreenShare,
|
|
6
7
|
hasVideo,
|
|
7
8
|
SfuModels,
|
|
@@ -50,7 +51,9 @@ export const DefaultScreenShareOverlay = () => {
|
|
|
50
51
|
const { t } = useI18n();
|
|
51
52
|
|
|
52
53
|
const stopScreenShare = () => {
|
|
53
|
-
call?.screenShare.disable()
|
|
54
|
+
call?.screenShare.disable().catch((err) => {
|
|
55
|
+
console.error('Failed to stop screen sharing:', err);
|
|
56
|
+
});
|
|
54
57
|
};
|
|
55
58
|
|
|
56
59
|
return (
|
|
@@ -61,6 +64,7 @@ export const DefaultScreenShareOverlay = () => {
|
|
|
61
64
|
</span>
|
|
62
65
|
<button
|
|
63
66
|
onClick={stopScreenShare}
|
|
67
|
+
type="button"
|
|
64
68
|
className="str-video__screen-share-overlay__button"
|
|
65
69
|
>
|
|
66
70
|
<Icon icon="close" /> {t('Stop Screen Sharing')}
|
|
@@ -111,7 +115,7 @@ export const DefaultParticipantViewUI = ({
|
|
|
111
115
|
export const ParticipantDetails = ({
|
|
112
116
|
indicatorsVisible = true,
|
|
113
117
|
}: Pick<DefaultParticipantViewUIProps, 'indicatorsVisible'>) => {
|
|
114
|
-
const { participant } = useParticipantViewContext();
|
|
118
|
+
const { participant, trackType } = useParticipantViewContext();
|
|
115
119
|
const {
|
|
116
120
|
isLocalParticipant,
|
|
117
121
|
connectionQuality,
|
|
@@ -130,6 +134,8 @@ export const ParticipantDetails = ({
|
|
|
130
134
|
const hasAudioTrack = hasAudio(participant);
|
|
131
135
|
const hasVideoTrack = hasVideo(participant);
|
|
132
136
|
const canUnpin = !!pin && pin.isLocalPin;
|
|
137
|
+
const isTrackPaused =
|
|
138
|
+
trackType !== 'none' ? hasPausedTrack(participant, trackType) : false;
|
|
133
139
|
|
|
134
140
|
return (
|
|
135
141
|
<>
|
|
@@ -143,6 +149,12 @@ export const ParticipantDetails = ({
|
|
|
143
149
|
{indicatorsVisible && !hasVideoTrack && (
|
|
144
150
|
<span className="str-video__participant-details__name--video-muted" />
|
|
145
151
|
)}
|
|
152
|
+
{indicatorsVisible && isTrackPaused && (
|
|
153
|
+
<span
|
|
154
|
+
title={t('Video paused due to insufficient bandwidth')}
|
|
155
|
+
className="str-video__participant-details__name--track-paused"
|
|
156
|
+
/>
|
|
157
|
+
)}
|
|
146
158
|
{indicatorsVisible && canUnpin && (
|
|
147
159
|
// TODO: remove this monstrosity once we have a proper design
|
|
148
160
|
<span
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
useState,
|
|
7
7
|
} from 'react';
|
|
8
8
|
import {
|
|
9
|
+
hasPausedTrack,
|
|
9
10
|
hasScreenShare,
|
|
10
11
|
hasVideo,
|
|
11
12
|
StreamVideoParticipant,
|
|
@@ -171,7 +172,11 @@ export const Video = ({
|
|
|
171
172
|
trackType === 'none' ||
|
|
172
173
|
viewportVisibilityState?.[trackType] === VisibilityState.INVISIBLE;
|
|
173
174
|
|
|
174
|
-
const hasNoVideoOrInvisible =
|
|
175
|
+
const hasNoVideoOrInvisible =
|
|
176
|
+
!enabled ||
|
|
177
|
+
!isPublishingTrack ||
|
|
178
|
+
isInvisible ||
|
|
179
|
+
hasPausedTrack(participant, trackType);
|
|
175
180
|
const mirrorVideo =
|
|
176
181
|
mirror === undefined
|
|
177
182
|
? isLocalParticipant && trackType === 'videoTrack'
|
package/src/translations/en.json
CHANGED
|
@@ -88,6 +88,7 @@
|
|
|
88
88
|
|
|
89
89
|
"Dominant Speaker": "Dominant Speaker",
|
|
90
90
|
"Poor connection quality": "Poor connection quality. Please check your internet connection.",
|
|
91
|
+
"Video paused due to insufficient bandwidth": "Video paused due to insufficient bandwidth",
|
|
91
92
|
|
|
92
93
|
"Participants": "Participants",
|
|
93
94
|
"Anonymous": ", and ({{ count }}) anonymous",
|