// ============================================================ // MicManager — 麦克风音频采集 // 职责:获取麦克风 MediaStream,供 VAD 和音频录制使用 // ============================================================ import { useCallback, useRef, useState } from "react"; import { useI18n } from "../../lib/i18n"; export function useMicrophone() { const { t } = useI18n(); const [stream, setStream] = useState(null); const [error, setError] = useState(null); const audioContextRef = useRef(null); const startMic = useCallback(async () => { try { const mediaStream = await navigator.mediaDevices.getUserMedia({ audio: { sampleRate: 16000, channelCount: 1, echoCancellation: true, noiseSuppression: true, }, video: false, }); setStream(mediaStream); setError(null); return mediaStream; } catch (err) { const message = err instanceof Error ? err.message : t("error.micAccess"); setError(message); console.error("[Mic] 获取麦克风失败:", err); return null; } }, []); const stopMic = useCallback(() => { stream?.getTracks().forEach((track) => track.stop()); setStream(null); audioContextRef.current?.close(); audioContextRef.current = null; }, [stream]); /** 获取或创建 AudioContext */ const getAudioContext = useCallback((): AudioContext => { if (!audioContextRef.current) { audioContextRef.current = new AudioContext({ sampleRate: 16000 }); } return audioContextRef.current; }, []); return { stream, error, startMic, stopMic, getAudioContext }; }