mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-06-27 20:29:44 +02:00
auto stop on silence
This commit is contained in:
parent
57d7cb0746
commit
b00b6ddd71
2 changed files with 19 additions and 1 deletions
|
|
@ -3387,6 +3387,7 @@ function App() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [meetingTranscription, handleVoiceNoteCreated])
|
}, [meetingTranscription, handleVoiceNoteCreated])
|
||||||
|
handleToggleMeetingRef.current = handleToggleMeeting
|
||||||
|
|
||||||
const ensureWikiFile = useCallback(async (wikiPath: string) => {
|
const ensureWikiFile = useCallback(async (wikiPath: string) => {
|
||||||
const resolvedPath = toKnowledgePath(wikiPath)
|
const resolvedPath = toKnowledgePath(wikiPath)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
// RMS threshold: system audio above this = "active" (speakers playing)
|
||||||
const SYSTEM_AUDIO_GATE_THRESHOLD = 0.005;
|
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
|
// Headphone detection
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
@ -68,7 +71,7 @@ function formatTranscript(entries: TranscriptEntry[], date: string): string {
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Hook
|
// Hook
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
export function useMeetingTranscription() {
|
export function useMeetingTranscription(onAutoStop?: () => void) {
|
||||||
const [state, setState] = useState<MeetingTranscriptionState>('idle');
|
const [state, setState] = useState<MeetingTranscriptionState>('idle');
|
||||||
const wsRef = useRef<WebSocket | null>(null);
|
const wsRef = useRef<WebSocket | null>(null);
|
||||||
const micStreamRef = useRef<MediaStream | 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 interimRef = useRef<Map<number, { speaker: string; text: string }>>(new Map());
|
||||||
const notePathRef = useRef<string>('');
|
const notePathRef = useRef<string>('');
|
||||||
const writeTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
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 dateRef = useRef<string>('');
|
||||||
|
|
||||||
const writeTranscriptToFile = useCallback(async () => {
|
const writeTranscriptToFile = useCallback(async () => {
|
||||||
|
|
@ -117,6 +123,10 @@ export function useMeetingTranscription() {
|
||||||
clearTimeout(writeTimerRef.current);
|
clearTimeout(writeTimerRef.current);
|
||||||
writeTimerRef.current = null;
|
writeTimerRef.current = null;
|
||||||
}
|
}
|
||||||
|
if (silenceTimerRef.current) {
|
||||||
|
clearTimeout(silenceTimerRef.current);
|
||||||
|
silenceTimerRef.current = null;
|
||||||
|
}
|
||||||
if (processorRef.current) {
|
if (processorRef.current) {
|
||||||
processorRef.current.disconnect();
|
processorRef.current.disconnect();
|
||||||
processorRef.current = null;
|
processorRef.current = null;
|
||||||
|
|
@ -195,6 +205,13 @@ export function useMeetingTranscription() {
|
||||||
const transcript = data.channel.alternatives[0].transcript;
|
const transcript = data.channel.alternatives[0].transcript;
|
||||||
if (!transcript) return;
|
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 channelIndex = data.channel_index?.[0] ?? 0;
|
||||||
const isMic = channelIndex === 0;
|
const isMic = channelIndex === 0;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue