auto stop on silence

This commit is contained in:
Arjun 2026-03-17 17:27:15 +05:30
parent 49c004b53e
commit 7513ec69ac
2 changed files with 19 additions and 1 deletions

View file

@ -3387,6 +3387,7 @@ function App() {
}
}
}, [meetingTranscription, handleVoiceNoteCreated])
handleToggleMeetingRef.current = handleToggleMeeting
const ensureWikiFile = useCallback(async (wikiPath: string) => {
const resolvedPath = toKnowledgePath(wikiPath)

View file

@ -18,6 +18,9 @@ const DEEPGRAM_LISTEN_URL = `wss://api.deepgram.com/v1/listen?${DEEPGRAM_PARAMS.
// RMS threshold: system audio above this = "active" (speakers playing)
const SYSTEM_AUDIO_GATE_THRESHOLD = 0.005;
// Auto-stop after 2 minutes of silence (no transcript from Deepgram)
const SILENCE_AUTO_STOP_MS = 2 * 60 * 1000;
// ---------------------------------------------------------------------------
// Headphone detection
// ---------------------------------------------------------------------------
@ -68,7 +71,7 @@ function formatTranscript(entries: TranscriptEntry[], date: string): string {
// ---------------------------------------------------------------------------
// Hook
// ---------------------------------------------------------------------------
export function useMeetingTranscription() {
export function useMeetingTranscription(onAutoStop?: () => void) {
const [state, setState] = useState<MeetingTranscriptionState>('idle');
const wsRef = useRef<WebSocket | null>(null);
const micStreamRef = useRef<MediaStream | null>(null);
@ -79,6 +82,9 @@ export function useMeetingTranscription() {
const interimRef = useRef<Map<number, { speaker: string; text: string }>>(new Map());
const notePathRef = useRef<string>('');
const writeTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
const silenceTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
const onAutoStopRef = useRef(onAutoStop);
onAutoStopRef.current = onAutoStop;
const dateRef = useRef<string>('');
const writeTranscriptToFile = useCallback(async () => {
@ -117,6 +123,10 @@ export function useMeetingTranscription() {
clearTimeout(writeTimerRef.current);
writeTimerRef.current = null;
}
if (silenceTimerRef.current) {
clearTimeout(silenceTimerRef.current);
silenceTimerRef.current = null;
}
if (processorRef.current) {
processorRef.current.disconnect();
processorRef.current = null;
@ -195,6 +205,13 @@ export function useMeetingTranscription() {
const transcript = data.channel.alternatives[0].transcript;
if (!transcript) return;
// Reset silence auto-stop timer on any transcript
if (silenceTimerRef.current) clearTimeout(silenceTimerRef.current);
silenceTimerRef.current = setTimeout(() => {
console.log('[meeting] 2 minutes of silence — auto-stopping');
onAutoStopRef.current?.();
}, SILENCE_AUTO_STOP_MS);
const channelIndex = data.channel_index?.[0] ?? 0;
const isMic = channelIndex === 0;