From 0330383e67df9edceb5dda3b4d2ac9b653884f9a Mon Sep 17 00:00:00 2001 From: Yasir761 Date: Sun, 5 Oct 2025 13:47:46 +0530 Subject: [PATCH 1/3] Fix audio/video sync: publish audio from camera when enabled and and made some changes in icon padding and text --- tauri/src/components/ui/call-center.tsx | 65 ++++++++++++++++--------- tauri/src/windows/camera/main.tsx | 17 ++++++- 2 files changed, 58 insertions(+), 24 deletions(-) diff --git a/tauri/src/components/ui/call-center.tsx b/tauri/src/components/ui/call-center.tsx index d97cc6e..d4edf3a 100644 --- a/tauri/src/components/ui/call-center.tsx +++ b/tauri/src/components/ui/call-center.tsx @@ -236,18 +236,18 @@ export function ConnectedActions() { )} - + {/* */} diable to solve the issue related to sync audio playback ); } @@ -343,7 +343,7 @@ function MicrophoneIcon({ setMicEnabled }: { setMicEnabled: (enabled: boolean) = [Colors.mic.text]: hasAudioEnabled, [Colors.deactivatedIcon]: !hasAudioEnabled, })} - className="hover:outline-solid hover:outline-1 hover:outline-slate-300 focus:ring-0 focus-visible:ring-0 hover:bg-slate-200 size-4 rounded-xs p-0 border-0 shadow-none hover:shadow-xs" + className=" p-0.5 text-xs rounded-sm hover:outline-solid hover:outline-1 hover:outline-slate-300 focus:ring-0 focus-visible:ring-0 hover:bg-slate-200 size-4 border-0 shadow-none hover:shadow-xs" /> @@ -509,7 +509,7 @@ function ScreensharingEventListener({ return
; } -function CameraIcon() { +function CameraIcon({ micEnabled }: { micEnabled: boolean }) { const { updateCallTokens, callTokens } = useStore(); const [retry, setRetry] = useState(0); const tracks = useTracks([Track.Source.Camera], {}); @@ -541,23 +541,42 @@ function CameraIcon() { const isDisabled = cameraDevices.length === 0; + // const handleCameraToggle = () => { + // clickedCameraRef.current = true; + // let newCameraEnabled = !cameraEnabled; + // updateCallTokens({ + // ...callTokens, + // hasCameraEnabled: newCameraEnabled, + // }); + // if (!newCameraEnabled) { + // const cameraTrack = localParticipant + // .getTrackPublications() + // .filter((track) => track.source === Track.Source.Camera)[0]; + // if (cameraTrack && cameraTrack.track && cameraTrack.track instanceof LocalTrack) { + // localParticipant.unpublishTrack(cameraTrack.track); + // } + // } + // }; + const handleCameraToggle = () => { - clickedCameraRef.current = true; - let newCameraEnabled = !cameraEnabled; - updateCallTokens({ - ...callTokens, - hasCameraEnabled: newCameraEnabled, - }); - if (!newCameraEnabled) { - const cameraTrack = localParticipant - .getTrackPublications() - .filter((track) => track.source === Track.Source.Camera)[0]; - if (cameraTrack && cameraTrack.track && cameraTrack.track instanceof LocalTrack) { - localParticipant.unpublishTrack(cameraTrack.track); - } + clickedCameraRef.current = true; + const newCameraEnabled = !cameraEnabled; + updateCallTokens({ ...callTokens, hasCameraEnabled: newCameraEnabled }); + + if (newCameraEnabled && micEnabled) { + // Publish a camera track with audio + localParticipant.setMicrophoneEnabled(true, { noiseSuppression: true, echoCancellation: true }); + } else if (!newCameraEnabled) { + // Unpublish camera track and audio + const cameraTrack = localParticipant + .getTrackPublications() + .find((track) => track.source === Track.Source.Camera); + if (cameraTrack && cameraTrack.track instanceof LocalTrack) { + localParticipant.unpublishTrack(cameraTrack.track); } - }; - + localParticipant.setMicrophoneEnabled(false); + } +}; const handleCameraChange = (value: string) => { console.debug("Selected camera: ", value); setActiveCameraDevice(value); @@ -604,7 +623,7 @@ function CameraIcon() { } size="unsized" disabled={isDisabled} - className={clsx("flex-1 min-w-0", { + className={clsx("flex-1 min-w-0 text-xs", { [Colors.deactivatedText]: !cameraEnabled, [`${Colors.camera.text} ${Colors.camera.ring}`]: cameraEnabled, })} @@ -623,7 +642,7 @@ function CameraIcon() { return ( device.deviceId !== "" && ( - + {device.label || `Camera ${device.label.slice(0, 8)}...`} @@ -716,7 +735,7 @@ function MediaDevicesSettings() { return (
- + (""); const [isExpanded, setIsExpanded] = useState(false); + // this is to resolve the issue of audio sync playback +const { localParticipant } = useLocalParticipant(); +const [micEnabled, setMicEnabled] = useState(false); +useEffect(() => { + if (!localParticipant) return; + + if (micEnabled) { + localParticipant.setMicrophoneEnabled(true, { + noiseSuppression: true, + echoCancellation: true, + }); + } else { + localParticipant.setMicrophoneEnabled(false); + } +}, [micEnabled]); useEffect(() => { // Set correct window size CameraWindowSize({ numOfTracks: 0, expansionFactor: isExpanded ? EXPANSION_FACTOR : 1 }); From 81ec8ad37805c3fff351a85e19d1e93b75fe0f97 Mon Sep 17 00:00:00 2001 From: Yasir761 Date: Mon, 6 Oct 2025 16:58:17 +0530 Subject: [PATCH 2/3] fix: conditionally render ListenToRemoteAudio based on camera window state, remove commented code --- tauri/src/components/ui/call-center.tsx | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/tauri/src/components/ui/call-center.tsx b/tauri/src/components/ui/call-center.tsx index d4edf3a..bc347cc 100644 --- a/tauri/src/components/ui/call-center.tsx +++ b/tauri/src/components/ui/call-center.tsx @@ -247,7 +247,8 @@ export function ConnectedActions() {
- {/* */} diable to solve the issue related to sync audio playback + {/* Render remote audio only if camera is NOT enabled */} + {!callTokens?.hasCameraEnabled && } diable to solve the issue related to sync audio playback ); } @@ -541,22 +542,7 @@ function CameraIcon({ micEnabled }: { micEnabled: boolean }) { const isDisabled = cameraDevices.length === 0; - // const handleCameraToggle = () => { - // clickedCameraRef.current = true; - // let newCameraEnabled = !cameraEnabled; - // updateCallTokens({ - // ...callTokens, - // hasCameraEnabled: newCameraEnabled, - // }); - // if (!newCameraEnabled) { - // const cameraTrack = localParticipant - // .getTrackPublications() - // .filter((track) => track.source === Track.Source.Camera)[0]; - // if (cameraTrack && cameraTrack.track && cameraTrack.track instanceof LocalTrack) { - // localParticipant.unpublishTrack(cameraTrack.track); - // } - // } - // }; + const handleCameraToggle = () => { clickedCameraRef.current = true; From 281cd0451d0a8cb2c42dd92981405e3a95c7a5ab Mon Sep 17 00:00:00 2001 From: Yasir761 Date: Tue, 7 Oct 2025 20:16:08 +0530 Subject: [PATCH 3/3] fix: track camera window open in callState --- tauri/src/components/ui/call-center.tsx | 12 +++++++++--- tauri/src/store/store.ts | 1 + tauri/src/windows/camera/main.tsx | 13 +------------ 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/tauri/src/components/ui/call-center.tsx b/tauri/src/components/ui/call-center.tsx index bc347cc..b8121f8 100644 --- a/tauri/src/components/ui/call-center.tsx +++ b/tauri/src/components/ui/call-center.tsx @@ -505,12 +505,13 @@ function ScreensharingEventListener({ updateRole(newRole); } + }, [tracks]); return
; } -function CameraIcon({ micEnabled }: { micEnabled: boolean }) { +function CameraIcon() { const { updateCallTokens, callTokens } = useStore(); const [retry, setRetry] = useState(0); const tracks = useTracks([Track.Source.Camera], {}); @@ -549,7 +550,7 @@ function CameraIcon({ micEnabled }: { micEnabled: boolean }) { const newCameraEnabled = !cameraEnabled; updateCallTokens({ ...callTokens, hasCameraEnabled: newCameraEnabled }); - if (newCameraEnabled && micEnabled) { + if (newCameraEnabled) { // Publish a camera track with audio localParticipant.setMicrophoneEnabled(true, { noiseSuppression: true, echoCancellation: true }); } else if (!newCameraEnabled) { @@ -577,9 +578,14 @@ function CameraIcon({ micEnabled }: { micEnabled: boolean }) { useEffect(() => { if (tracks.length > 0) { tauriUtils.ensureCameraWindowIsVisible(callTokens?.cameraToken || ""); + // Update store + updateCallTokens({ cameraWindowOpen: true }); + } else { // If there are 0 then close the window tauriUtils.closeCameraWindow(); + // Update store + updateCallTokens({ cameraWindowOpen: false }); } if (localParticipant) { @@ -721,7 +727,7 @@ function MediaDevicesSettings() { return (
- + (""); const [isExpanded, setIsExpanded] = useState(false); // this is to resolve the issue of audio sync playback -const { localParticipant } = useLocalParticipant(); +// const { localParticipant } = useLocalParticipant(); const [micEnabled, setMicEnabled] = useState(false); -useEffect(() => { - if (!localParticipant) return; - if (micEnabled) { - localParticipant.setMicrophoneEnabled(true, { - noiseSuppression: true, - echoCancellation: true, - }); - } else { - localParticipant.setMicrophoneEnabled(false); - } -}, [micEnabled]); useEffect(() => { // Set correct window size CameraWindowSize({ numOfTracks: 0, expansionFactor: isExpanded ? EXPANSION_FACTOR : 1 });