返回 presentation-ai
useMediaDevices.ts
根目录 / src / hooks / presentation / useMediaDevices.ts
1 "use client";
2
3 import { useEffect, useState } from "react";
4
5 export interface MediaDevice {
6 deviceId: string;
7 label: string;
8 kind: MediaDeviceKind;
9 }
10
11 export function useMediaDevices() {
12 const [videoDevices, setVideoDevices] = useState<MediaDevice[]>([]);
13 const [audioDevices, setAudioDevices] = useState<MediaDevice[]>([]);
14 const [isLoading, setIsLoading] = useState(true);
15 const [error, setError] = useState<string | null>(null);
16
17 const refreshDevices = async () => {
18 try {
19 setIsLoading(true);
20 setError(null);
21 // Request permissions first to get device labels
22 try {
23 await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
24 } catch (err) {
25 console.warn("Could not get permissions for device enumeration:", err);
26 }
27
28 const devices = await navigator.mediaDevices.enumerateDevices();
29
30 const video = devices
31 .filter((device) => device.kind === "videoinput")
32 .map((device) => ({
33 deviceId: device.deviceId,
34 label: device.label || `Camera ${device.deviceId.slice(0, 8)}`,
35 kind: device.kind,
36 }));
37
38 const audio = devices
39 .filter((device) => device.kind === "audioinput")
40 .map((device) => ({
41 deviceId: device.deviceId,
42 label: device.label || `Microphone ${device.deviceId.slice(0, 8)}`,
43 kind: device.kind,
44 }));
45
46 console.log("Found video devices:", video);
47 console.log("Found audio devices:", audio);
48 setVideoDevices(video);
49 setAudioDevices(audio);
50 } catch (err) {
51 console.error("Error enumerating devices:", err);
52 setError("Failed to load devices");
53 } finally {
54 setIsLoading(false);
55 }
56 };
57
58 useEffect(() => {
59 refreshDevices();
60
61 // Listen for device changes
62 const handleDeviceChange = () => {
63 refreshDevices();
64 };
65
66 navigator.mediaDevices.addEventListener("devicechange", handleDeviceChange);
67
68 return () => {
69 navigator.mediaDevices.removeEventListener(
70 "devicechange",
71 handleDeviceChange,
72 );
73 };
74 }, []);
75
76 return {
77 videoDevices,
78 audioDevices,
79 isLoading,
80 error,
81 refreshDevices,
82 };
83 }
84
84 lines TYPESCRIPT