From 8b533018ea22c22eba7ae9778f280a3a2611adc3 Mon Sep 17 00:00:00 2001 From: Daniel Abramov Date: Fri, 2 Jun 2023 21:34:59 +0200 Subject: [PATCH] Remove unused stuff from video-grid --- src/room/InCallView.tsx | 3 +- src/video-grid/TileDescriptor.tsx | 3 - src/video-grid/VideoTileContainer.tsx | 19 +- src/video-grid/useAudioOutputDevice.ts | 42 ----- src/video-grid/useCallFeed.ts | 126 ------------- src/video-grid/useMediaStream.ts | 247 ------------------------- 6 files changed, 2 insertions(+), 438 deletions(-) delete mode 100644 src/video-grid/useAudioOutputDevice.ts delete mode 100644 src/video-grid/useCallFeed.ts delete mode 100644 src/video-grid/useMediaStream.ts diff --git a/src/room/InCallView.tsx b/src/room/InCallView.tsx index 00af9ee..3e6a62c 100644 --- a/src/room/InCallView.tsx +++ b/src/room/InCallView.tsx @@ -240,7 +240,7 @@ export function InCallView({ // think should be in the call, even if we don't have a call feed for them yet) const tileDescriptors: TileDescriptor[] = []; for (const [member, participantMap] of participants) { - for (const [deviceId, { connectionState, presenter }] of participantMap) { + for (const [deviceId, { presenter }] of participantMap) { const id = `${member.userId}:${deviceId}`; const sfuParticipant = sfuParticipants.find((p) => p.identity === id); @@ -253,7 +253,6 @@ export function InCallView({ focused: hasScreenShare && !sfuParticipant?.isLocal, isLocal: member.userId == localUserId && deviceId == localDeviceId, presenter, - connectionState, sfuParticipant, }); } diff --git a/src/video-grid/TileDescriptor.tsx b/src/video-grid/TileDescriptor.tsx index 687b1e7..c5533ac 100644 --- a/src/video-grid/TileDescriptor.tsx +++ b/src/video-grid/TileDescriptor.tsx @@ -17,8 +17,6 @@ limitations under the License. import { RoomMember } from "matrix-js-sdk"; import { LocalParticipant, RemoteParticipant } from "livekit-client"; -import { ConnectionState } from "../room/useGroupCall"; - // Represents something that should get a tile on the layout, // ie. a user's video feed or a screen share feed. export interface TileDescriptor { @@ -27,6 +25,5 @@ export interface TileDescriptor { focused: boolean; presenter: boolean; isLocal?: boolean; - connectionState: ConnectionState; sfuParticipant?: LocalParticipant | RemoteParticipant; } diff --git a/src/video-grid/VideoTileContainer.tsx b/src/video-grid/VideoTileContainer.tsx index 57ce6c0..6704861 100644 --- a/src/video-grid/VideoTileContainer.tsx +++ b/src/video-grid/VideoTileContainer.tsx @@ -16,9 +16,7 @@ limitations under the License. import React from "react"; import { RoomMember } from "matrix-js-sdk/src/models/room-member"; -import { useTranslation } from "react-i18next"; -import { ConnectionState } from "../room/useGroupCall"; import { useRoomMemberName } from "./useRoomMemberName"; import { VideoTile } from "./VideoTile"; import { TileDescriptor } from "./TileDescriptor"; @@ -44,25 +42,10 @@ export function VideoTileContainer({ ...rest }: Props) { const { rawDisplayName } = useRoomMemberName(item.member); - const { t } = useTranslation(); - - let caption: string; - switch (item.connectionState) { - case ConnectionState.EstablishingCall: - caption = t("{{name}} (Connecting...)", { name }); - break; - case ConnectionState.WaitMedia: - // not strictly true, but probably easier to understand than, "Waiting for media" - caption = t("{{name}} (Waiting for video...)", { name }); - break; - case ConnectionState.Connected: - caption = rawDisplayName; - break; - } return ( <> - {!item.sfuParticipant && {caption}} + {!item.sfuParticipant && null} {item.sfuParticipant && ( , - audioOutputDevice: string | undefined -): void { - useEffect(() => { - if ( - mediaRef.current && - mediaRef.current !== undefined && - audioOutputDevice - ) { - if (mediaRef.current.setSinkId) { - console.log( - `useMediaStream setting output setSinkId ${audioOutputDevice}` - ); - // Chrome for Android doesn't support this - mediaRef.current.setSinkId(audioOutputDevice); - } else { - console.log("Can't set output - no setsinkid"); - } - } - }, [mediaRef, audioOutputDevice]); -} diff --git a/src/video-grid/useCallFeed.ts b/src/video-grid/useCallFeed.ts deleted file mode 100644 index 5304b82..0000000 --- a/src/video-grid/useCallFeed.ts +++ /dev/null @@ -1,126 +0,0 @@ -/* -Copyright 2022 New Vector Ltd - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import { useState, useEffect } from "react"; -import { CallFeed, CallFeedEvent } from "matrix-js-sdk/src/webrtc/callFeed"; -import { SDPStreamMetadataPurpose } from "matrix-js-sdk/src/webrtc/callEventTypes"; - -const DEBUG_INFO_INTERVAL = 1000; // ms - -export interface CallFeedDebugInfo { - width: number | undefined; - height: number | undefined; -} - -interface CallFeedState { - callFeed: CallFeed | undefined; - isLocal: boolean; - speaking: boolean; - videoMuted: boolean; - audioMuted: boolean; - localVolume: number; - hasAudio: boolean; - disposed: boolean | undefined; - stream: MediaStream | undefined; - purpose: SDPStreamMetadataPurpose | undefined; - debugInfo: CallFeedDebugInfo; -} - -function getDebugInfo(callFeed: CallFeed | undefined): CallFeedDebugInfo { - return { - width: callFeed?.stream?.getVideoTracks()?.[0]?.getSettings()?.width, - height: callFeed?.stream?.getVideoTracks()?.[0]?.getSettings()?.height, - }; -} - -function getCallFeedState(callFeed: CallFeed | undefined): CallFeedState { - return { - callFeed, - isLocal: callFeed ? callFeed.isLocal : false, - speaking: callFeed ? callFeed.isSpeaking() : false, - videoMuted: callFeed ? callFeed.isVideoMuted() : true, - audioMuted: callFeed ? callFeed.isAudioMuted() : true, - localVolume: callFeed ? callFeed.getLocalVolume() : 0, - hasAudio: - callFeed && callFeed.stream - ? callFeed.stream.getAudioTracks().length >= 1 - : false, - disposed: callFeed ? callFeed.disposed : undefined, - stream: callFeed ? callFeed.stream : undefined, - purpose: callFeed ? callFeed.purpose : undefined, - debugInfo: getDebugInfo(callFeed), - }; -} - -export function useCallFeed(callFeed: CallFeed | undefined): CallFeedState { - const [state, setState] = useState(() => - getCallFeedState(callFeed) - ); - - useEffect(() => { - function onSpeaking(speaking: boolean) { - setState((prevState) => ({ ...prevState, speaking })); - } - - function onMuteStateChanged(audioMuted: boolean, videoMuted: boolean) { - setState((prevState) => ({ ...prevState, audioMuted, videoMuted })); - } - - function onLocalVolumeChanged(localVolume: number) { - setState((prevState) => ({ ...prevState, localVolume })); - } - - function onUpdateCallFeed() { - setState(getCallFeedState(callFeed)); - } - - if (callFeed) { - callFeed.on(CallFeedEvent.Speaking, onSpeaking); - callFeed.on(CallFeedEvent.MuteStateChanged, onMuteStateChanged); - callFeed.on(CallFeedEvent.LocalVolumeChanged, onLocalVolumeChanged); - callFeed.on(CallFeedEvent.NewStream, onUpdateCallFeed); - callFeed.on(CallFeedEvent.Disposed, onUpdateCallFeed); - } - - onUpdateCallFeed(); - - const debugInfoInterval = setInterval(() => { - setState((prevState) => ({ - ...prevState, - debugInfo: getDebugInfo(callFeed), - })); - }, DEBUG_INFO_INTERVAL); - - return () => { - clearInterval(debugInfoInterval); - - if (callFeed) { - callFeed.removeListener(CallFeedEvent.Speaking, onSpeaking); - callFeed.removeListener( - CallFeedEvent.MuteStateChanged, - onMuteStateChanged - ); - callFeed.removeListener( - CallFeedEvent.LocalVolumeChanged, - onLocalVolumeChanged - ); - callFeed.removeListener(CallFeedEvent.NewStream, onUpdateCallFeed); - } - }; - }, [callFeed]); - - return state; -} diff --git a/src/video-grid/useMediaStream.ts b/src/video-grid/useMediaStream.ts deleted file mode 100644 index 259ede7..0000000 --- a/src/video-grid/useMediaStream.ts +++ /dev/null @@ -1,247 +0,0 @@ -/* -Copyright 2022 New Vector Ltd - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import { useRef, useEffect, RefObject, useState, useCallback } from "react"; -import { - acquireContext, - releaseContext, -} from "matrix-js-sdk/src/webrtc/audioContext"; -import { logger } from "matrix-js-sdk/src/logger"; - -import { useSpatialAudio } from "../settings/useSetting"; -import { useEventTarget } from "../useEvents"; -import { useAudioOutputDevice } from "./useAudioOutputDevice"; - -declare global { - interface Window { - // For detecting whether this browser is Chrome or not - chrome?: unknown; - } -} - -export const useMediaStreamTrackCount = ( - stream: MediaStream | null -): [number, number] => { - const latestAudioTrackCount = stream ? stream.getAudioTracks().length : 0; - const latestVideoTrackCount = stream ? stream.getVideoTracks().length : 0; - - const [audioTrackCount, setAudioTrackCount] = useState( - stream ? stream.getAudioTracks().length : 0 - ); - const [videoTrackCount, setVideoTrackCount] = useState( - stream ? stream.getVideoTracks().length : 0 - ); - - const tracksChanged = useCallback(() => { - setAudioTrackCount(stream ? stream.getAudioTracks().length : 0); - setVideoTrackCount(stream ? stream.getVideoTracks().length : 0); - }, [stream]); - - useEventTarget(stream, "addtrack", tracksChanged); - useEventTarget(stream, "removetrack", tracksChanged); - - if ( - latestAudioTrackCount !== audioTrackCount || - latestVideoTrackCount !== videoTrackCount - ) { - tracksChanged(); - } - - return [audioTrackCount, videoTrackCount]; -}; - -// Binds a media stream to a media output element, returning a ref for the -// media element that should then be passed to the media element to be used. -export const useMediaStream = ( - stream: MediaStream | null, - audioOutputDevice: string | null, - mute = false, - localVolume?: number -): RefObject => { - const mediaRef = useRef(); - - useAudioOutputDevice(mediaRef, audioOutputDevice); - - useEffect(() => { - console.log( - `useMediaStream update stream mediaRef.current ${!!mediaRef.current} stream ${ - stream && stream.id - } muted ${mute}` - ); - - if (mediaRef.current) { - const mediaEl = mediaRef.current; - - if (stream) { - mediaEl.muted = mute; - mediaEl.srcObject = stream; - mediaEl.play().catch((e) => { - if (e.name !== "AbortError") throw e; - }); - - // Unmuting the tab in Safari causes all video elements to be individually - // unmuted, so we need to reset the mute state here to prevent audio loops - const onVolumeChange = () => { - mediaEl.muted = mute; - }; - mediaEl.addEventListener("volumechange", onVolumeChange); - return () => - mediaEl.removeEventListener("volumechange", onVolumeChange); - } else { - mediaRef.current.srcObject = null; - } - } - }, [stream, mute]); - - useEffect(() => { - if (!mediaRef.current) return; - if (localVolume === null || localVolume === undefined) return; - - mediaRef.current.volume = localVolume; - }, [localVolume]); - - useEffect(() => { - const mediaEl = mediaRef.current; - - return () => { - if (mediaEl) { - // Ensure we set srcObject to null before unmounting to prevent memory leak - // https://webrtchacks.com/srcobject-intervention/ - mediaEl.srcObject = null; - } - }; - }, []); - - return mediaRef; -}; - -// Provides a properly refcounted instance of the shared audio context, -// along with the context's destination audio node and a ref to be used -// for the