@stream-io/video-react-sdk 1.3.6 → 1.4.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 +13 -0
- package/dist/index.cjs.js +35 -96
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +37 -95
- package/dist/index.es.js.map +1 -1
- package/dist/latency-chart-Bj5OSYzg.es.js +57 -0
- package/dist/latency-chart-Bj5OSYzg.es.js.map +1 -0
- package/dist/latency-chart-CpL1M_s0.cjs.js +59 -0
- package/dist/latency-chart-CpL1M_s0.cjs.js.map +1 -0
- package/dist/src/components/CallStats/CallStats.d.ts +5 -15
- package/dist/src/components/CallStats/CallStatsLatencyChart.d.ts +2 -1
- package/dist/src/components/CallStats/index.d.ts +0 -1
- package/package.json +12 -9
- package/src/components/CallStats/CallStats.tsx +47 -48
- package/src/components/CallStats/CallStatsLatencyChart.tsx +30 -41
- package/src/components/CallStats/index.ts +0 -1
package/dist/index.es.js
CHANGED
|
@@ -3,13 +3,11 @@ export * from '@stream-io/video-client';
|
|
|
3
3
|
import { useCall, useCallStateHooks, useI18n, Restricted, useConnectedUser, StreamCallProvider, StreamVideoProvider, useStreamVideoClient } from '@stream-io/video-react-bindings';
|
|
4
4
|
export * from '@stream-io/video-react-bindings';
|
|
5
5
|
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
6
|
-
import { useState, useEffect, Fragment as Fragment$1, createContext, useContext, useCallback, useRef, useMemo, forwardRef, isValidElement, useLayoutEffect } from 'react';
|
|
6
|
+
import { useState, useEffect, Fragment as Fragment$1, createContext, useContext, useCallback, useRef, useMemo, forwardRef, isValidElement, lazy, Suspense, useLayoutEffect } from 'react';
|
|
7
7
|
import clsx from 'clsx';
|
|
8
8
|
import { flushSync } from 'react-dom';
|
|
9
9
|
import { isPlatformSupported, loadTFLite, createRenderer } from '@stream-io/video-filters-web';
|
|
10
10
|
import { useFloating, offset, shift, flip, size, autoUpdate, FloatingOverlay, FloatingPortal, arrow, FloatingArrow, useListItem, useListNavigation, useTypeahead, useClick, useDismiss, useRole, useInteractions, FloatingFocusManager, FloatingList, useHover } from '@floating-ui/react';
|
|
11
|
-
import { Chart, CategoryScale, LinearScale, LineElement, PointElement } from 'chart.js';
|
|
12
|
-
import { Line } from 'react-chartjs-2';
|
|
13
11
|
|
|
14
12
|
const Audio = ({ participant, trackType = 'audioTrack', ...rest }) => {
|
|
15
13
|
const call = useCall();
|
|
@@ -1202,89 +1200,15 @@ const CancelCallButton = ({ disabled, caption, onClick, onLeave, }) => {
|
|
|
1202
1200
|
|
|
1203
1201
|
const CallControls = ({ onLeave }) => (jsxs("div", { className: "str-video__call-controls", children: [jsx(SpeakingWhileMutedNotification, { children: jsx(ToggleAudioPublishingButton, {}) }), jsx(ToggleVideoPublishingButton, {}), jsx(ReactionsButton, {}), jsx(ScreenShareButton, {}), jsx(RecordCallButton, {}), jsx(CancelCallButton, { onLeave: onLeave })] }));
|
|
1204
1202
|
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
return `${date.getHours()}:${date.getMinutes()}`;
|
|
1213
|
-
}),
|
|
1214
|
-
datasets: [
|
|
1215
|
-
{
|
|
1216
|
-
data: values.map((point) => {
|
|
1217
|
-
const { y } = point;
|
|
1218
|
-
max = Math.max(max, y);
|
|
1219
|
-
return point;
|
|
1220
|
-
}),
|
|
1221
|
-
borderColor: '#00e2a1',
|
|
1222
|
-
backgroundColor: '#00e2a1',
|
|
1223
|
-
},
|
|
1224
|
-
],
|
|
1225
|
-
};
|
|
1226
|
-
const options = useMemo(() => {
|
|
1227
|
-
return {
|
|
1228
|
-
maintainAspectRatio: false,
|
|
1229
|
-
animation: {
|
|
1230
|
-
duration: 0,
|
|
1231
|
-
},
|
|
1232
|
-
elements: {
|
|
1233
|
-
line: {
|
|
1234
|
-
borderWidth: 1,
|
|
1235
|
-
},
|
|
1236
|
-
point: {
|
|
1237
|
-
radius: 2,
|
|
1238
|
-
},
|
|
1239
|
-
},
|
|
1240
|
-
scales: {
|
|
1241
|
-
y: {
|
|
1242
|
-
position: 'right',
|
|
1243
|
-
stacked: true,
|
|
1244
|
-
min: 0,
|
|
1245
|
-
max: Math.max(180, Math.ceil((max + 10) / 10) * 10),
|
|
1246
|
-
grid: {
|
|
1247
|
-
display: true,
|
|
1248
|
-
color: '#979ca0',
|
|
1249
|
-
},
|
|
1250
|
-
ticks: {
|
|
1251
|
-
stepSize: 30,
|
|
1252
|
-
},
|
|
1253
|
-
},
|
|
1254
|
-
x: {
|
|
1255
|
-
grid: {
|
|
1256
|
-
display: false,
|
|
1257
|
-
},
|
|
1258
|
-
ticks: {
|
|
1259
|
-
display: false,
|
|
1260
|
-
},
|
|
1261
|
-
},
|
|
1262
|
-
},
|
|
1263
|
-
};
|
|
1264
|
-
}, [max]);
|
|
1265
|
-
return (jsx("div", { className: "str-video__call-stats-line-chart-container", children: jsx(Line, { options: options, data: data, className: "str-video__call-stats__latencychart" }) }));
|
|
1266
|
-
};
|
|
1267
|
-
|
|
1268
|
-
var Statuses;
|
|
1269
|
-
(function (Statuses) {
|
|
1270
|
-
Statuses["GOOD"] = "Good";
|
|
1271
|
-
Statuses["OK"] = "Ok";
|
|
1272
|
-
Statuses["BAD"] = "Bad";
|
|
1273
|
-
})(Statuses || (Statuses = {}));
|
|
1274
|
-
const statsStatus = ({ value, lowBound, highBound, }) => {
|
|
1275
|
-
if (value <= lowBound) {
|
|
1276
|
-
return Statuses.GOOD;
|
|
1277
|
-
}
|
|
1278
|
-
if (value >= lowBound && value <= highBound) {
|
|
1279
|
-
return Statuses.OK;
|
|
1280
|
-
}
|
|
1281
|
-
if (value >= highBound) {
|
|
1282
|
-
return Statuses.BAD;
|
|
1283
|
-
}
|
|
1284
|
-
return Statuses.GOOD;
|
|
1285
|
-
};
|
|
1203
|
+
const CallStatsLatencyChart = lazy(() => import('./latency-chart-Bj5OSYzg.es.js'));
|
|
1204
|
+
var Status;
|
|
1205
|
+
(function (Status) {
|
|
1206
|
+
Status["GOOD"] = "Good";
|
|
1207
|
+
Status["OK"] = "Ok";
|
|
1208
|
+
Status["BAD"] = "Bad";
|
|
1209
|
+
})(Status || (Status = {}));
|
|
1286
1210
|
const CallStats = (props) => {
|
|
1287
|
-
const { latencyLowBound = 75, latencyHighBound = 400 } = props;
|
|
1211
|
+
const { latencyLowBound = 75, latencyHighBound = 400, showCodecInfo = false, LatencyChartSuspenseFallback = null, } = props;
|
|
1288
1212
|
const [latencyBuffer, setLatencyBuffer] = useState(() => {
|
|
1289
1213
|
const now = Date.now();
|
|
1290
1214
|
return Array.from({ length: 20 }, (_, i) => ({ x: now + i, y: 0 }));
|
|
@@ -1324,13 +1248,13 @@ const CallStats = (props) => {
|
|
|
1324
1248
|
highBound: latencyHighBound,
|
|
1325
1249
|
value: callStatsReport?.publisherStats.averageRoundTripTimeInMs || 0,
|
|
1326
1250
|
};
|
|
1327
|
-
return (jsx("div", { className: "str-video__call-stats", children: callStatsReport && (jsxs(Fragment, { children: [jsxs("div", { className: "str-video__call-stats__header", children: [jsxs("h3", { className: "str-video__call-stats__heading", children: [jsx(Icon, { className: "str-video__call-stats__icon", icon: "call-latency" }), t('Call Latency')] }), jsx("p", { className: "str-video__call-stats__description", children: t('Very high latency values may reduce call quality, cause lag, and make the call less enjoyable.') })] }), jsx("div", { className: "str-video__call-stats__latencychart", children: jsx(CallStatsLatencyChart, { values: latencyBuffer }) }), jsxs("div", { className: "str-video__call-stats__header", children: [jsxs("h3", { className: "str-video__call-stats__heading", children: [jsx(Icon, { className: "str-video__call-stats__icon", icon: "network-quality" }), t('Call performance')] }), jsx("p", { className: "str-video__call-stats__description", children: t('Review the key data points below to assess call performance') })] }), jsxs("div", { className: "str-video__call-stats__card-container", children: [jsx(StatCard, { label: t('Region'), value: callStatsReport.datacenter }), jsx(StatCard, { label: t('Latency'), value: `${callStatsReport.publisherStats.averageRoundTripTimeInMs} ms.`, comparison: latencyComparison }), jsx(StatCard, { label: t('Receive jitter'), value: `${callStatsReport.subscriberStats.averageJitterInMs} ms.`, comparison: {
|
|
1251
|
+
return (jsx("div", { className: "str-video__call-stats", children: callStatsReport && (jsxs(Fragment, { children: [jsxs("div", { className: "str-video__call-stats__header", children: [jsxs("h3", { className: "str-video__call-stats__heading", children: [jsx(Icon, { className: "str-video__call-stats__icon", icon: "call-latency" }), t('Call Latency')] }), jsx("p", { className: "str-video__call-stats__description", children: t('Very high latency values may reduce call quality, cause lag, and make the call less enjoyable.') })] }), jsx("div", { className: "str-video__call-stats__latencychart", children: jsx(Suspense, { fallback: LatencyChartSuspenseFallback, children: jsx(CallStatsLatencyChart, { values: latencyBuffer }) }) }), jsxs("div", { className: "str-video__call-stats__header", children: [jsxs("h3", { className: "str-video__call-stats__heading", children: [jsx(Icon, { className: "str-video__call-stats__icon", icon: "network-quality" }), t('Call performance')] }), jsx("p", { className: "str-video__call-stats__description", children: t('Review the key data points below to assess call performance') })] }), jsxs("div", { className: "str-video__call-stats__card-container", children: [jsx(StatCard, { label: t('Region'), value: callStatsReport.datacenter }), jsx(StatCard, { label: t('Latency'), value: `${callStatsReport.publisherStats.averageRoundTripTimeInMs} ms.`, comparison: latencyComparison }), jsx(StatCard, { label: t('Receive jitter'), value: `${callStatsReport.subscriberStats.averageJitterInMs} ms.`, comparison: {
|
|
1328
1252
|
...latencyComparison,
|
|
1329
1253
|
value: callStatsReport.subscriberStats.averageJitterInMs,
|
|
1330
1254
|
} }), jsx(StatCard, { label: t('Publish jitter'), value: `${callStatsReport.publisherStats.averageJitterInMs} ms.`, comparison: {
|
|
1331
1255
|
...latencyComparison,
|
|
1332
1256
|
value: callStatsReport.publisherStats.averageJitterInMs,
|
|
1333
|
-
} }), jsx(StatCard, { label: t('Publish resolution')
|
|
1257
|
+
} }), jsx(StatCard, { label: `${t('Publish resolution')}${showCodecInfo ? formatCodec(callStatsReport) : ''}`, value: toFrameSize(callStatsReport.publisherStats) }), jsx(StatCard, { label: t('Publish quality drop reason'), value: callStatsReport.publisherStats.qualityLimitationReasons }), jsx(StatCard, { label: t('Receiving resolution'), value: toFrameSize(callStatsReport.subscriberStats) }), jsx(StatCard, { label: t('Receive quality drop reason'), value: callStatsReport.subscriberStats.qualityLimitationReasons }), jsx(StatCard, { label: t('Publish bitrate'), value: publishBitrate }), jsx(StatCard, { label: t('Receiving bitrate'), value: subscribeBitrate })] })] })) }));
|
|
1334
1258
|
};
|
|
1335
1259
|
const StatCardExplanation = (props) => {
|
|
1336
1260
|
const { description } = props;
|
|
@@ -1343,18 +1267,29 @@ const StatCardExplanation = (props) => {
|
|
|
1343
1267
|
const { getReferenceProps, getFloatingProps } = useInteractions([hover]);
|
|
1344
1268
|
return (jsxs(Fragment, { children: [jsx("div", { className: "str-video__call-explanation", ref: refs.setReference, ...getReferenceProps(), children: jsx(Icon, { className: "str-video__call-explanation__icon", icon: "info" }) }), isOpen && (jsx("div", { className: "str-video__call-explanation__description", ref: refs.setFloating, style: floatingStyles, ...getFloatingProps(), children: description }))] }));
|
|
1345
1269
|
};
|
|
1346
|
-
const StatsTag = (
|
|
1270
|
+
const StatsTag = (props) => {
|
|
1271
|
+
const { children, status } = props;
|
|
1347
1272
|
return (jsx("div", { className: clsx('str-video__call-stats__tag', {
|
|
1348
|
-
'str-video__call-stats__tag--good': status ===
|
|
1349
|
-
'str-video__call-stats__tag--ok': status ===
|
|
1350
|
-
'str-video__call-stats__tag--bad': status ===
|
|
1273
|
+
'str-video__call-stats__tag--good': status === Status.GOOD,
|
|
1274
|
+
'str-video__call-stats__tag--ok': status === Status.OK,
|
|
1275
|
+
'str-video__call-stats__tag--bad': status === Status.BAD,
|
|
1351
1276
|
}), children: jsx("div", { className: "str-video__call-stats__tag__text", children: children }) }));
|
|
1352
1277
|
};
|
|
1353
1278
|
const StatCard = (props) => {
|
|
1354
1279
|
const { label, value, description, comparison } = props;
|
|
1355
1280
|
const { t } = useI18n();
|
|
1356
|
-
const status = comparison ?
|
|
1357
|
-
return (jsxs("div", { className: "str-video__call-stats__card", children: [jsxs("div", { className: "str-video__call-stats__card-content", children: [jsxs("div", { className: "str-video__call-stats__card-label", children: [label, description && jsx(StatCardExplanation, { description: description })] }), jsx("div", { className: "str-video__call-stats__card-value", children: value })] }),
|
|
1281
|
+
const status = comparison ? toStatus(comparison) : undefined;
|
|
1282
|
+
return (jsxs("div", { className: "str-video__call-stats__card", children: [jsxs("div", { className: "str-video__call-stats__card-content", children: [jsxs("div", { className: "str-video__call-stats__card-label", children: [label, description && jsx(StatCardExplanation, { description: description })] }), jsx("div", { className: "str-video__call-stats__card-value", children: value })] }), status && jsx(StatsTag, { status: status, children: t(status) })] }));
|
|
1283
|
+
};
|
|
1284
|
+
const toStatus = (config) => {
|
|
1285
|
+
const { value, lowBound, highBound } = config;
|
|
1286
|
+
if (value <= lowBound)
|
|
1287
|
+
return Status.GOOD;
|
|
1288
|
+
if (value >= lowBound && value <= highBound)
|
|
1289
|
+
return Status.OK;
|
|
1290
|
+
if (value >= highBound)
|
|
1291
|
+
return Status.BAD;
|
|
1292
|
+
return Status.GOOD;
|
|
1358
1293
|
};
|
|
1359
1294
|
const toFrameSize = (stats) => {
|
|
1360
1295
|
const { highestFrameWidth: w, highestFrameHeight: h, highestFramesPerSecond: fps, } = stats;
|
|
@@ -1367,6 +1302,13 @@ const toFrameSize = (stats) => {
|
|
|
1367
1302
|
}
|
|
1368
1303
|
return size;
|
|
1369
1304
|
};
|
|
1305
|
+
const formatCodec = (callStatsReport) => {
|
|
1306
|
+
const { codec } = callStatsReport.publisherStats;
|
|
1307
|
+
if (!codec)
|
|
1308
|
+
return '';
|
|
1309
|
+
const [, name] = codec.split('/');
|
|
1310
|
+
return name ? ` (${name})` : '';
|
|
1311
|
+
};
|
|
1370
1312
|
const calculatePublishBitrate = (previousCallStatsReport, callStatsReport) => {
|
|
1371
1313
|
const { publisherStats: { totalBytesSent: previousTotalBytesSent, timestamp: previousTimestamp, }, } = previousCallStatsReport;
|
|
1372
1314
|
const { publisherStats: { totalBytesSent, timestamp }, } = callStatsReport;
|
|
@@ -2605,7 +2547,7 @@ const LivestreamPlayer = (props) => {
|
|
|
2605
2547
|
return (jsx(StreamCall, { call: call, children: jsx(LivestreamLayout, { ...layoutProps }) }));
|
|
2606
2548
|
};
|
|
2607
2549
|
|
|
2608
|
-
const [major, minor, patch] = ("1.
|
|
2550
|
+
const [major, minor, patch] = ("1.4.0").split('.');
|
|
2609
2551
|
setSdkInfo({
|
|
2610
2552
|
type: SfuModels.SdkType.REACT,
|
|
2611
2553
|
major,
|
|
@@ -2613,5 +2555,5 @@ setSdkInfo({
|
|
|
2613
2555
|
patch,
|
|
2614
2556
|
});
|
|
2615
2557
|
|
|
2616
|
-
export { AcceptCallButton, Audio, Avatar, AvatarFallback, BackgroundFiltersProvider, BaseVideo, CallControls, CallParticipantListing, CallParticipantListingItem, CallParticipantsList, CallPreview, CallRecordingList, CallRecordingListHeader, CallRecordingListItem, CallStats, CallStatsButton,
|
|
2558
|
+
export { AcceptCallButton, Audio, Avatar, AvatarFallback, BackgroundFiltersProvider, BaseVideo, CallControls, CallParticipantListing, CallParticipantListingItem, CallParticipantsList, CallPreview, CallRecordingList, CallRecordingListHeader, CallRecordingListItem, CallStats, CallStatsButton, CancelCallButton, CancelCallConfirmButton, CompositeButton, DefaultParticipantViewUI, DefaultReactionsMenu, DefaultScreenShareOverlay, DefaultVideoPlaceholder, DeviceSelector, DeviceSelectorAudioInput, DeviceSelectorAudioOutput, DeviceSelectorVideo, DeviceSettings, DropDownSelect, DropDownSelectOption, EmptyCallRecordingListing, GenericMenu, GenericMenuButtonItem, Icon, IconButton, LivestreamLayout, LivestreamPlayer, LoadingCallRecordingListing, LoadingIndicator, MenuToggle, MenuVisualType, NoiseCancellationProvider, Notification, PaginatedGridLayout, ParticipantActionsContextMenu, ParticipantDetails, ParticipantView, ParticipantViewContext, ParticipantsAudio, PermissionNotification, PermissionRequestList, PermissionRequests, ReactionsButton, RecordCallButton, RecordCallConfirmationButton, RecordingInProgressNotification, RingingCall, RingingCallControls, ScreenShareButton, SearchInput, SearchResults, SpeakerLayout, SpeakingWhileMutedNotification, SpeechIndicator, StatCard, StreamCall, StreamTheme, StreamVideo, TextButton, ToggleAudioOutputButton, ToggleAudioPreviewButton, ToggleAudioPublishingButton, ToggleVideoPreviewButton, ToggleVideoPublishingButton, Tooltip, Video$1 as Video, VideoPreview, WithTooltip, defaultReactions, translations, useBackgroundFilters, useHorizontalScrollPosition, useMenuContext, useNoiseCancellation, useParticipantViewContext, usePersistedDevicePreferences, useRequestPermission, useTrackElementVisibility, useVerticalScrollPosition };
|
|
2617
2559
|
//# sourceMappingURL=index.es.js.map
|