codev / desktop /src /hooks /useCameraDevices.ts
chenbhao's picture
feat: Doubao-style video call with scenario selection, screen share & fullscreen camera
3aea50a
Raw
History Blame
1.73 kB
import { useState, useCallback } from 'react'
export function useCameraDevices() {
const [devices, setDevices] = useState<MediaDeviceInfo[]>([])
const [activeDeviceId, setActiveDeviceId] = useState<string | null>(null)
const enumerateCameras = useCallback(async () => {
try {
const allDevices = await navigator.mediaDevices.enumerateDevices()
const videoInputs = allDevices.filter((d) => d.kind === 'videoinput')
setDevices(videoInputs)
return videoInputs
} catch {
return []
}
}, [])
const switchCamera = useCallback(
async (deviceId: string): Promise<MediaStream | null> => {
try {
const stream = await navigator.mediaDevices.getUserMedia({
video: {
deviceId: { exact: deviceId },
width: { ideal: 640 },
height: { ideal: 480 },
},
audio: false,
})
setActiveDeviceId(deviceId)
return stream
} catch (err) {
console.error('Failed to switch camera:', err)
return null
}
},
[],
)
const getStreamForFacingMode = useCallback(
async (facingMode: 'user' | 'environment'): Promise<MediaStream | null> => {
try {
const stream = await navigator.mediaDevices.getUserMedia({
video: {
facingMode,
width: { ideal: 640 },
height: { ideal: 480 },
},
audio: false,
})
return stream
} catch (err) {
console.error('Failed to get camera with facing mode:', err)
return null
}
},
[],
)
return {
devices,
activeDeviceId,
enumerateCameras,
switchCamera,
getStreamForFacingMode,
}
}