From 8e80118bdf45d0e2ac4d6b6c20d12feb0530fb28 Mon Sep 17 00:00:00 2001 From: wendesongomes Date: Fri, 31 May 2024 21:14:45 -0300 Subject: [PATCH 1/2] fix: Fixed problem where Firefox user's webcam did not work --- apps/web/hooks/useUserMedia.ts | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/apps/web/hooks/useUserMedia.ts b/apps/web/hooks/useUserMedia.ts index 9d31130..2214010 100644 --- a/apps/web/hooks/useUserMedia.ts +++ b/apps/web/hooks/useUserMedia.ts @@ -16,20 +16,25 @@ export const useUserMedia = () => { const [accessGranted, setAccessGranted] = useState(false); const checkPermission = useCallback(async () => { - const videoPermission = await navigator.permissions.query({ name: 'camera' }); - const audioPermission = await navigator.permissions.query({ name: 'microphone' }); - - const permission = { - video: videoPermission.state === 'granted', - audio: audioPermission.state === 'granted' - } - - if(permission.video && permission.audio){ - setAccessGranted(true) + try { + await navigator.mediaDevices.getUserMedia({ + video: true, + audio: true, + }); + setAccessGranted(true); + return { + video: true, + audio: true, + }; + } catch (error) { + console.error("Error checking permission:", error); + setAccessGranted(false); + return { + video: false, + audio: false, + }; } - - return permission - }, [setAccessGranted]) + }, [setAccessGranted]); const stopStreaming = useCallback(async (_stream?: MediaStream) => { From 9e446d1c680a288d24aa27df5ea50ac3029727a3 Mon Sep 17 00:00:00 2001 From: Bruno Rodrigues Date: Sun, 2 Jun 2024 11:18:56 +0100 Subject: [PATCH 2/2] chore(web): remove unucessary console.log --- apps/web/hooks/useUserMedia.ts | 226 +++++++++++++++++---------------- 1 file changed, 117 insertions(+), 109 deletions(-) diff --git a/apps/web/hooks/useUserMedia.ts b/apps/web/hooks/useUserMedia.ts index 2214010..9b7291c 100644 --- a/apps/web/hooks/useUserMedia.ts +++ b/apps/web/hooks/useUserMedia.ts @@ -1,171 +1,172 @@ -import { useCallback, useEffect, useMemo, useState } from "react"; -import { usePreferencesStore } from "./usePreferencesStore"; +import { useCallback, useEffect, useMemo, useState } from "react" +import { usePreferencesStore } from "./usePreferencesStore" type MediaConstraints = { - audio?: string; - video?: string; -}; + audio?: string + video?: string +} export const useUserMedia = () => { - const preferences = usePreferencesStore(); - const [stream, setStream] = useState(null); - const [activeStream, setActiveStream] = useState(null); - const [devices, setDevices] = useState([]); - const [ready, setReady] = useState(false); + const preferences = usePreferencesStore() + const [stream, setStream] = useState(null) + const [activeStream, setActiveStream] = useState(null) + const [devices, setDevices] = useState([]) + const [ready, setReady] = useState(false) - const [accessGranted, setAccessGranted] = useState(false); + const [accessGranted, setAccessGranted] = useState(false) const checkPermission = useCallback(async () => { try { await navigator.mediaDevices.getUserMedia({ video: true, audio: true, - }); - setAccessGranted(true); + }) + setAccessGranted(true) return { video: true, audio: true, - }; + } } catch (error) { - console.error("Error checking permission:", error); - setAccessGranted(false); + console.error("Error checking permission:", error) + setAccessGranted(false) return { video: false, audio: false, - }; + } } - }, [setAccessGranted]); - + }, [setAccessGranted]) const stopStreaming = useCallback(async (_stream?: MediaStream) => { if (_stream) { - _stream?.getTracks().forEach((track) => track.stop()); + _stream?.getTracks().forEach((track) => track.stop()) } - }, []); + }, []) - const requestPermission = useCallback( - async () => { - const _stream = await navigator.mediaDevices.getUserMedia({ - video: true, - audio: true - }); + const requestPermission = useCallback(async () => { + const _stream = await navigator.mediaDevices.getUserMedia({ + video: true, + audio: true, + }) - stopStreaming(_stream) - checkPermission() - }, - [stopStreaming, checkPermission], - ); + stopStreaming(_stream) + checkPermission() + }, [stopStreaming, checkPermission]) const updateUserMedia = useCallback( async (constraints: MediaConstraints) => { const _stream = await navigator.mediaDevices.getUserMedia({ - video: constraints.video ? { deviceId: { exact: constraints.video } } : false, - audio: constraints.video ? { deviceId: { exact: constraints.audio } } : false, - }); + video: constraints.video + ? { deviceId: { exact: constraints.video } } + : false, + audio: constraints.video + ? { deviceId: { exact: constraints.audio } } + : false, + }) - _stream.getVideoTracks().forEach(track => { + _stream.getVideoTracks().forEach((track) => { track.enabled = !preferences.videoOff }) - _stream.getAudioTracks().forEach(track => { + _stream.getAudioTracks().forEach((track) => { track.enabled = !preferences.muted }) - setActiveStream(_stream); - setReady(true); + setActiveStream(_stream) + setReady(true) return _stream }, - [preferences.muted, preferences.videoOff], - ); + [preferences.muted, preferences.videoOff] + ) const getDevices = useCallback(async () => { - const devices = await navigator.mediaDevices.enumerateDevices(); - setDevices(devices || []); + const devices = await navigator.mediaDevices.enumerateDevices() + setDevices(devices || []) return devices - }, [setDevices]); + }, [setDevices]) const toggleMute = useCallback(async () => { - console.log({muted: preferences.muted}) - activeStream?.getAudioTracks().forEach(track => { - track.enabled = preferences.muted + activeStream?.getAudioTracks().forEach((track) => { + track.enabled = preferences.muted }) preferences.toggleMute() }, [preferences, activeStream]) const toggleVideo = useCallback(async () => { - activeStream?.getVideoTracks().forEach(track => { - track.enabled = preferences.videoOff + activeStream?.getVideoTracks().forEach((track) => { + track.enabled = preferences.videoOff }) preferences.toggleVideoOff() }, [preferences, activeStream]) - const switchInput = useCallback(async (deviceId: string, type: 'audio' | 'video') => { - let newStream: MediaStream; - const oldVideoTrack = activeStream?.getVideoTracks()[0]!; - const oldAudioTrack = activeStream?.getAudioTracks()[0]!; - - if(type === 'audio') { - newStream = await navigator.mediaDevices.getUserMedia({ - audio: { deviceId: { exact: deviceId } }, - video: { deviceId: { exact: preferences.video } }, - }); - preferences.set(deviceId, 'audio') - } else { - newStream = await navigator.mediaDevices.getUserMedia({ - audio: { deviceId: { exact: preferences.audio } }, - video: { deviceId: { exact: deviceId }}, - }); - preferences.set(deviceId, 'video') - } - - if(!newStream) return + const switchInput = useCallback( + async (deviceId: string, type: "audio" | "video") => { + let newStream: MediaStream + const oldVideoTrack = activeStream?.getVideoTracks()[0]! + const oldAudioTrack = activeStream?.getAudioTracks()[0]! + + if (type === "audio") { + newStream = await navigator.mediaDevices.getUserMedia({ + audio: { deviceId: { exact: deviceId } }, + video: { deviceId: { exact: preferences.video } }, + }) + preferences.set(deviceId, "audio") + } else { + newStream = await navigator.mediaDevices.getUserMedia({ + audio: { deviceId: { exact: preferences.audio } }, + video: { deviceId: { exact: deviceId } }, + }) + preferences.set(deviceId, "video") + } - const newVideoTrack = newStream.getVideoTracks()[0]!; - const newAudioTrack = newStream.getAudioTracks()[0]!; + if (!newStream) return - newVideoTrack.enabled = !preferences.videoOff - newAudioTrack.enabled = !preferences.muted + const newVideoTrack = newStream.getVideoTracks()[0]! + const newAudioTrack = newStream.getAudioTracks()[0]! - stopStreaming(activeStream!) - setActiveStream(newStream) + newVideoTrack.enabled = !preferences.videoOff + newAudioTrack.enabled = !preferences.muted - return { - oldVideoTrack, - newVideoTrack, - oldAudioTrack, - newAudioTrack, - newStream, - }; - }, [activeStream, preferences, stopStreaming]); + stopStreaming(activeStream!) + setActiveStream(newStream) + return { + oldVideoTrack, + newVideoTrack, + oldAudioTrack, + newAudioTrack, + newStream, + } + }, + [activeStream, preferences, stopStreaming] + ) const stopAllStreaming = useCallback(async () => { - stream?.getTracks().forEach((track) => track.stop()); - }, [stream]); + stream?.getTracks().forEach((track) => track.stop()) + }, [stream]) useEffect(() => { - if(accessGranted) { - getDevices(); + if (accessGranted) { + getDevices() } - }, [getDevices, accessGranted]); + }, [getDevices, accessGranted]) const audioDevices = useMemo(() => { return devices.filter( - (device) => device.kind === "audioinput" && !!device.deviceId, - ); - }, [devices]); + (device) => device.kind === "audioinput" && !!device.deviceId + ) + }, [devices]) const videoDevices = useMemo(() => { return devices.filter( - (device) => device.kind === "videoinput" && !!device.deviceId, + (device) => device.kind === "videoinput" && !!device.deviceId ) - }, [devices]); + }, [devices]) useEffect(() => { const init = async () => { const permission = await checkPermission() - if(!permission.audio || !permission.video) { + if (!permission.audio || !permission.video) { requestPermission() } } @@ -173,7 +174,6 @@ export const useUserMedia = () => { init() }, [checkPermission, getDevices, requestPermission]) - useEffect(() => { const init = async () => { const _devices = await getDevices() @@ -181,24 +181,25 @@ export const useUserMedia = () => { let audio = preferences.audio let video = preferences.video - if(!_devices || !devices.length) { + if (!_devices || !devices.length) { return } - if(!audio && !video) { - audio = _devices.find(device => device.kind === 'audioinput')?.deviceId - video = _devices.find(device => device.kind === 'videoinput')?.deviceId + if (!audio && !video) { + audio = _devices.find((device) => device.kind === "audioinput") + ?.deviceId + video = _devices.find((device) => device.kind === "videoinput") + ?.deviceId } - if(video) { - preferences.set(video, 'video') + if (video) { + preferences.set(video, "video") } - if(audio) { - preferences.set(audio, 'audio') + if (audio) { + preferences.set(audio, "audio") } - const _stream = await updateUserMedia({ audio, video, @@ -207,11 +208,18 @@ export const useUserMedia = () => { setStream(_stream) } - - if(accessGranted && !stream) { + if (accessGranted && !stream) { init() } - }, [preferences.audio, preferences.video, updateUserMedia, accessGranted, stream, getDevices, devices.length]) + }, [ + preferences.audio, + preferences.video, + updateUserMedia, + accessGranted, + stream, + getDevices, + devices.length, + ]) return { stream, @@ -230,5 +238,5 @@ export const useUserMedia = () => { muted: preferences.muted, videoOff: preferences.videoOff, checkPermission, - }; -}; + } +}