diff --git a/bigbluebutton-html5/imports/ui/components/connection-status/component.jsx b/bigbluebutton-html5/imports/ui/components/connection-status/component.jsx
index 9e9be29fbe..7f89298201 100755
--- a/bigbluebutton-html5/imports/ui/components/connection-status/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/connection-status/component.jsx
@@ -3,7 +3,6 @@ import { useMutation } from '@apollo/client';
import { UPDATE_CONNECTION_ALIVE_AT } from './mutations';
import { getStatus, handleAudioStatsEvent, startMonitoringNetwork } from '/imports/ui/components/connection-status/service';
import connectionStatus from '../../core/graphql/singletons/connectionStatus';
-import { useGetStats } from '../video-provider/hooks';
import getBaseUrl from '/imports/ui/core/utils/getBaseUrl';
@@ -14,8 +13,6 @@ const ConnectionStatus = () => {
const [updateConnectionAliveAtM] = useMutation(UPDATE_CONNECTION_ALIVE_AT);
- const getVideoStreamsStats = useGetStats();
-
const handleUpdateConnectionAliveAt = () => {
const startTime = performance.now();
fetch(
@@ -66,7 +63,7 @@ const ConnectionStatus = () => {
if (STATS_ENABLED) {
window.addEventListener('audiostats', handleAudioStatsEvent);
- startMonitoringNetwork(getVideoStreamsStats);
+ startMonitoringNetwork();
}
return () => {
diff --git a/bigbluebutton-html5/imports/ui/components/connection-status/modal/container.jsx b/bigbluebutton-html5/imports/ui/components/connection-status/modal/container.jsx
index 954d1b0d56..d6f0a08b28 100644
--- a/bigbluebutton-html5/imports/ui/components/connection-status/modal/container.jsx
+++ b/bigbluebutton-html5/imports/ui/components/connection-status/modal/container.jsx
@@ -3,7 +3,6 @@ import { CONNECTION_STATUS_REPORT_SUBSCRIPTION } from '../queries';
import Service from '../service';
import Component from './component';
import useCurrentUser from '/imports/ui/core/hooks/useCurrentUser';
-import { useGetStats } from '../../video-provider/hooks';
import useDeduplicatedSubscription from '/imports/ui/core/hooks/useDeduplicatedSubscription';
import { useReactiveVar } from '@apollo/client';
import connectionStatus from '/imports/ui/core/graphql/singletons/connectionStatus';
@@ -16,14 +15,11 @@ const ConnectionStatusContainer = (props) => {
const newtworkData = useReactiveVar(connectionStatus.getNetworkDataVar());
- const getVideoStreamsStats = useGetStats();
-
return (
);
diff --git a/bigbluebutton-html5/imports/ui/components/connection-status/service.js b/bigbluebutton-html5/imports/ui/components/connection-status/service.js
index ceaf3517b5..0b7cd89c88 100644
--- a/bigbluebutton-html5/imports/ui/components/connection-status/service.js
+++ b/bigbluebutton-html5/imports/ui/components/connection-status/service.js
@@ -5,6 +5,7 @@ import Session from '/imports/ui/services/storage/in-memory';
import { notify } from '/imports/ui/services/notification';
import AudioService from '/imports/ui/components/audio/service';
import ScreenshareService from '/imports/ui/components/screenshare/service';
+import VideoService from '/imports/ui/components/video-provider/service';
import connectionStatus from '../../core/graphql/singletons/connectionStatus';
const intlMessages = defineMessages({
@@ -210,8 +211,8 @@ const getAudioData = async () => {
* @returns An Object containing video data for all video peers and screenshare
* peer
*/
-const getVideoData = async (getVideoStreamsStats) => {
- const camerasData = await getVideoStreamsStats() || {};
+const getVideoData = async () => {
+ const camerasData = await VideoService.getStats() || {};
const screenshareData = await ScreenshareService.getStats() || {};
@@ -226,10 +227,10 @@ const getVideoData = async (getVideoStreamsStats) => {
* For audio, this will get information about the mic/listen-only stream.
* @returns An Object containing all this data.
*/
-const getNetworkData = async (getVideoStreamsStats) => {
+const getNetworkData = async () => {
const audio = await getAudioData();
- const video = await getVideoData(getVideoStreamsStats);
+ const video = await getVideoData();
const user = {
time: new Date(),
@@ -401,11 +402,11 @@ export function getStatus(levels, value) {
* Start monitoring the network data.
* @return {Promise} A Promise that resolves when process started.
*/
-export async function startMonitoringNetwork(getVideoStreamsStats) {
- let previousData = await getNetworkData(getVideoStreamsStats);
+export async function startMonitoringNetwork() {
+ let previousData = await getNetworkData();
setInterval(async () => {
- const data = await getNetworkData(getVideoStreamsStats);
+ const data = await getNetworkData();
const {
outbound: audioCurrentUploadRate,
diff --git a/bigbluebutton-html5/imports/ui/components/video-provider/container.tsx b/bigbluebutton-html5/imports/ui/components/video-provider/container.tsx
index ffae9e6ece..9a879fe4c4 100755
--- a/bigbluebutton-html5/imports/ui/components/video-provider/container.tsx
+++ b/bigbluebutton-html5/imports/ui/components/video-provider/container.tsx
@@ -20,7 +20,6 @@ import VideoService from './service';
import { Output } from '/imports/ui/components/layout/layoutTypes';
import { VideoItem } from './types';
import { debounce } from '/imports/utils/debounce';
-import WebRtcPeer from '/imports/ui/services/webrtc-base/peer';
import useSettings from '/imports/ui/services/settings/hooks/useSettings';
import { SETTINGS } from '/imports/ui/services/settings/enums';
import { useStorageKey } from '/imports/ui/services/storage/hooks';
@@ -64,7 +63,7 @@ const VideoProviderContainer: React.FC = (props) =>
VideoService.applyCameraProfile,
CAMERA_QUALITY_THR_DEBOUNCE,
{ leading: false, trailing: true },
- );
+ ) as typeof VideoService.applyCameraProfile;
const { data: currentMeeting } = useMeeting((m) => ({
usersPolicies: m.usersPolicies,
@@ -89,6 +88,7 @@ const VideoProviderContainer: React.FC = (props) =>
totalNumberOfStreams,
totalNumberOfOtherStreams,
} = useVideoStreams();
+ VideoService.updateActivePeers(streams);
let usersVideo: VideoItem[] = streams;
@@ -167,7 +167,7 @@ const VideoProviderContainer: React.FC = (props) =>
exitVideo={exitVideo}
lockUser={lockUser}
stopVideo={stopVideo}
- applyCameraProfile={applyCameraProfile as (peer: WebRtcPeer, profileId: string) => void}
+ applyCameraProfile={applyCameraProfile}
myRole={myRole}
/>
);
diff --git a/bigbluebutton-html5/imports/ui/components/video-provider/hooks/index.ts b/bigbluebutton-html5/imports/ui/components/video-provider/hooks/index.ts
index 841124e31b..0069503194 100644
--- a/bigbluebutton-html5/imports/ui/components/video-provider/hooks/index.ts
+++ b/bigbluebutton-html5/imports/ui/components/video-provider/hooks/index.ts
@@ -52,11 +52,6 @@ import ConnectionStatus from '/imports/ui/core/graphql/singletons/connectionStat
import { VIDEO_TYPES } from '/imports/ui/components/video-provider/enums';
import createUseSubscription from '/imports/ui/core/hooks/createUseSubscription';
-const FILTER_VIDEO_STATS = [
- 'outbound-rtp',
- 'inbound-rtp',
-];
-
const useVideoStreamsSubscription = createUseSubscription(
VIDEO_STREAMS_SUBSCRIPTION,
{},
@@ -532,53 +527,6 @@ export const useStopVideo = () => {
}, [cameraBroadcastStop]);
};
-export const useActivePeers = () => {
- const videoData = useVideoStreams();
-
- if (!videoData) return null;
-
- const { streams: activeVideoStreams } = videoData;
-
- if (!activeVideoStreams) return null;
-
- const activePeers: Record = {};
-
- activeVideoStreams.forEach((stream) => {
- if (videoService.getWebRtcPeersRef()[stream.stream]) {
- activePeers[stream.stream] = videoService.getWebRtcPeersRef()[stream.stream].peerConnection;
- }
- });
-
- return activePeers;
-};
-
-export const useGetStats = () => {
- const peers = useActivePeers();
-
- return useCallback(async () => {
- if (!peers) return null;
-
- const stats: Record = {};
-
- await Promise.all(
- Object.keys(peers).map(async (peerId) => {
- const peerStats = await peers[peerId].getStats();
-
- const videoStats: Record = {};
-
- peerStats.forEach((stat) => {
- if (FILTER_VIDEO_STATS.includes(stat.type)) {
- videoStats[stat.type] = stat;
- }
- });
- stats[peerId] = videoStats;
- }),
- );
-
- return stats;
- }, [peers]);
-};
-
export const useShouldRenderPaginationToggle = () => {
const myPageSize = useMyPageSize();
const {
diff --git a/bigbluebutton-html5/imports/ui/components/video-provider/service.ts b/bigbluebutton-html5/imports/ui/components/video-provider/service.ts
index b629cd114f..fa6b9fe38e 100755
--- a/bigbluebutton-html5/imports/ui/components/video-provider/service.ts
+++ b/bigbluebutton-html5/imports/ui/components/video-provider/service.ts
@@ -18,11 +18,16 @@ import WebRtcPeer from '/imports/ui/services/webrtc-base/peer';
import { Constraints2 } from '/imports/ui/Types/meetingClientSettings';
import MediaStreamUtils from '/imports/utils/media-stream-utils';
import Session from '/imports/ui/services/storage/in-memory';
-import type { Stream } from './types';
+import type { Stream, StreamItem } from './types';
import { VIDEO_TYPES } from './enums';
const TOKEN = '_';
+const FILTER_VIDEO_STATS = [
+ 'outbound-rtp',
+ 'inbound-rtp',
+];
+
class VideoService {
public isMobile: boolean;
@@ -40,6 +45,8 @@ class VideoService {
private deviceId: string | null = null;
+ private activePeers: Record;
+
private readonly clientSessionUUID: string;
constructor() {
@@ -60,6 +67,7 @@ class VideoService {
}
this.webRtcPeersRef = {};
+ this.activePeers = {};
}
static fetchNumberOfDevices(devices: MediaDeviceInfo[]) {
@@ -474,6 +482,39 @@ class VideoService {
getPrefix() {
return `${Auth.userID}${TOKEN}${this.clientSessionUUID}`;
}
+
+ updateActivePeers(streams: StreamItem[]) {
+ const activePeers: Record = {};
+
+ streams.forEach((vs) => {
+ if (this.webRtcPeersRef[vs.stream]) {
+ activePeers[vs.stream] = this.webRtcPeersRef[vs.stream].peerConnection;
+ }
+ });
+
+ this.activePeers = activePeers;
+ }
+
+ async getStats() {
+ const stats: Record = {};
+
+ await Promise.all(
+ Object.keys(this.activePeers).map(async (peerId) => {
+ const peerStats = await this.activePeers[peerId].getStats();
+
+ const videoStats: Record = {};
+
+ peerStats.forEach((stat) => {
+ if (FILTER_VIDEO_STATS.includes(stat.type)) {
+ videoStats[stat.type] = stat;
+ }
+ });
+ stats[peerId] = videoStats;
+ }),
+ );
+
+ return stats;
+ }
}
const videoService = new VideoService();
@@ -516,4 +557,6 @@ export default {
getRoleViewer: VideoService.getRoleViewer,
getPrefix: videoService.getPrefix.bind(videoService),
isPinEnabled: VideoService.isPinEnabled,
+ updateActivePeers: (streams: StreamItem[]) => videoService.updateActivePeers(streams),
+ getStats: () => videoService.getStats(),
};