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