From 2234962acc5209d96179c089422067362936174f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sat, 13 Aug 2022 18:16:24 +0200 Subject: [PATCH 1/2] Fix handling of streams with no audio tracks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/video-grid/VideoTileContainer.tsx | 2 +- src/video-grid/useMediaStream.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video-grid/VideoTileContainer.tsx b/src/video-grid/VideoTileContainer.tsx index d647903..1ca1a4c 100644 --- a/src/video-grid/VideoTileContainer.tsx +++ b/src/video-grid/VideoTileContainer.tsx @@ -72,7 +72,7 @@ export function VideoTileContainer({ audioOutputDevice, audioContext, audioDestination, - isLocal, + isLocal || audioMuted, localVolume ); const { diff --git a/src/video-grid/useMediaStream.ts b/src/video-grid/useMediaStream.ts index 86b0105..2af4ec2 100644 --- a/src/video-grid/useMediaStream.ts +++ b/src/video-grid/useMediaStream.ts @@ -213,7 +213,7 @@ export const useSpatialMediaStream = ( const sourceRef = useRef(); useEffect(() => { - if (spatialAudio && tileRef.current && !mute) { + if (spatialAudio && audioContext && tileRef.current && !mute) { if (!pannerNodeRef.current) { pannerNodeRef.current = new PannerNode(audioContext, { panningModel: "HRTF", From 317f27e5f98669304ff8dc78f576c3c210b0c7e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sat, 13 Aug 2022 18:44:11 +0200 Subject: [PATCH 2/2] Don't re-run hook on every mute MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/video-grid/VideoTileContainer.tsx | 2 +- src/video-grid/useMediaStream.ts | 33 ++++++++++++++++++++++++--- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/video-grid/VideoTileContainer.tsx b/src/video-grid/VideoTileContainer.tsx index 1ca1a4c..d647903 100644 --- a/src/video-grid/VideoTileContainer.tsx +++ b/src/video-grid/VideoTileContainer.tsx @@ -72,7 +72,7 @@ export function VideoTileContainer({ audioOutputDevice, audioContext, audioDestination, - isLocal || audioMuted, + isLocal, localVolume ); const { diff --git a/src/video-grid/useMediaStream.ts b/src/video-grid/useMediaStream.ts index 2af4ec2..236361f 100644 --- a/src/video-grid/useMediaStream.ts +++ b/src/video-grid/useMediaStream.ts @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { useRef, useEffect, RefObject } from "react"; +import { useRef, useEffect, RefObject, useState, useCallback } from "react"; import { parse as parseSdp, write as writeSdp } from "sdp-transform"; import { acquireContext, @@ -22,6 +22,7 @@ import { } from "matrix-js-sdk/src/webrtc/audioContext"; import { useSpatialAudio } from "../settings/useSetting"; +import { useEventTarget } from "../useEvents"; declare global { interface Window { @@ -30,6 +31,23 @@ declare global { } } +export const useMediaStreamTrackCount = ( + stream: MediaStream +): [number, number] => { + const [audioTrackCount, setAudioTrackCount] = useState(0); + const [videoTrackCount, setVideoTrackCount] = useState(0); + + const tracksChanged = useCallback(() => { + setAudioTrackCount(stream.getAudioTracks().length); + setVideoTrackCount(stream.getVideoTracks().length); + }, [stream]); + + useEventTarget(stream, "addtrack", tracksChanged); + useEventTarget(stream, "removetrack", tracksChanged); + + return [audioTrackCount, videoTrackCount]; +}; + export const useMediaStream = ( stream: MediaStream, audioOutputDevice: string, @@ -207,13 +225,14 @@ export const useSpatialMediaStream = ( spatialAudio || mute, localVolume ); + const [audioTrackCount] = useMediaStreamTrackCount(stream); const gainNodeRef = useRef(); const pannerNodeRef = useRef(); const sourceRef = useRef(); useEffect(() => { - if (spatialAudio && audioContext && tileRef.current && !mute) { + if (spatialAudio && tileRef.current && !mute && audioTrackCount > 0) { if (!pannerNodeRef.current) { pannerNodeRef.current = new PannerNode(audioContext, { panningModel: "HRTF", @@ -261,7 +280,15 @@ export const useSpatialMediaStream = ( pannerNode.disconnect(); }; } - }, [stream, spatialAudio, audioContext, audioDestination, mute, localVolume]); + }, [ + stream, + spatialAudio, + audioContext, + audioDestination, + mute, + localVolume, + audioTrackCount, + ]); return [tileRef, mediaRef]; };