From 6359c9f50dd71cc3ba39f6ae3552460d532d0f25 Mon Sep 17 00:00:00 2001
From: Cogent Apps
Date: Mon, 20 Mar 2023 21:03:12 +0000
Subject: [PATCH] fallback to whisper when speechrecognition is not available
---
app/src/components/input.tsx | 25 +++++++++++++------
app/src/components/settings/user.tsx | 5 ++--
...types.d.ts => speech-recognition-types.ts} | 13 +++++++---
3 files changed, 29 insertions(+), 14 deletions(-)
rename app/src/{speech-recognition-types.d.ts => speech-recognition-types.ts} (92%)
diff --git a/app/src/components/input.tsx b/app/src/components/input.tsx
index e41dd775..1ac7dd7d 100644
--- a/app/src/components/input.tsx
+++ b/app/src/components/input.tsx
@@ -8,8 +8,8 @@ import { useAppContext } from '../context';
import { useAppDispatch, useAppSelector } from '../store';
import { selectMessage, setMessage } from '../store/message';
import { selectTemperature } from '../store/parameters';
-import { openSystemPromptPanel, openTemperaturePanel } from '../store/settings-ui';
-import { speechRecognition } from '../speech-recognition-types.d'
+import { openOpenAIApiKeyPanel, openSystemPromptPanel, openTemperaturePanel } from '../store/settings-ui';
+import { speechRecognition, supportsSpeechRecognition } from '../speech-recognition-types'
import MicRecorder from 'mic-recorder-to-mp3';
import { selectUseOpenAIWhisper, selectOpenAIApiKey } from '../store/api-keys';
import { Mp3Encoder } from 'lamejs';
@@ -109,7 +109,7 @@ export default function MessageInput(props: MessageInputProps) {
console.error('speech recognition error', e);
try {
- speechRecognition.stop();
+ speechRecognition?.stop();
} catch (e) {
}
@@ -122,14 +122,19 @@ export default function MessageInput(props: MessageInputProps) {
}, [recorder]);
const onSpeechStart = useCallback(() => {
+ if (!openAIApiKey) {
+ dispatch(openOpenAIApiKeyPanel());
+ return false;
+ }
+
try {
if (!recording) {
setRecording(true);
// if we are using whisper, the we will just record with the browser and send the api when done
- if (useOpenAIWhisper) {
+ if (useOpenAIWhisper || !supportsSpeechRecognition) {
recorder.start().catch(onSpeechError);
- } else {
+ } else if (speechRecognition) {
const initialMessage = message;
speechRecognition.continuous = true;
@@ -146,10 +151,12 @@ export default function MessageInput(props: MessageInputProps) {
};
speechRecognition.start();
+ } else {
+ onSpeechError(new Error('not supported'));
}
} else {
setRecording(false);
- if (useOpenAIWhisper) {
+ if (useOpenAIWhisper || !supportsSpeechRecognition) {
setTranscribing(true);
const mp3 = recorder.stop().getMp3();
@@ -185,14 +192,16 @@ export default function MessageInput(props: MessageInputProps) {
}
}).catch(onSpeechError);
- } else {
+ } else if (speechRecognition) {
speechRecognition.stop();
+ } else {
+ onSpeechError(new Error('not supported'));
}
}
} catch (e) {
onSpeechError(e);
}
- }, [recording, message, dispatch]);
+ }, [recording, message, dispatch, onSpeechError, openAIApiKey]);
const onKeyDown = useCallback((e: React.KeyboardEvent) => {
diff --git a/app/src/components/settings/user.tsx b/app/src/components/settings/user.tsx
index 6b6d1303..474e3be1 100644
--- a/app/src/components/settings/user.tsx
+++ b/app/src/components/settings/user.tsx
@@ -6,6 +6,7 @@ import { useAppDispatch, useAppSelector } from "../../store";
import { selectOpenAIApiKey, setOpenAIApiKeyFromEvent, selectUseOpenAIWhisper, setUseOpenAIWhisperFromEvent } from "../../store/api-keys";
import { selectSettingsOption } from "../../store/settings-ui";
import { FormattedMessage, useIntl } from "react-intl";
+import { supportsSpeechRecognition } from "../../speech-recognition-types";
export default function UserOptionsTab(props: any) {
const option = useAppSelector(selectSettingsOption);
@@ -31,11 +32,11 @@ export default function UserOptionsTab(props: any) {
-
+ />}
diff --git a/app/src/speech-recognition-types.d.ts b/app/src/speech-recognition-types.ts
similarity index 92%
rename from app/src/speech-recognition-types.d.ts
rename to app/src/speech-recognition-types.ts
index 8e205a5b..89eee651 100644
--- a/app/src/speech-recognition-types.d.ts
+++ b/app/src/speech-recognition-types.ts
@@ -122,12 +122,17 @@ declare global {
}
}
-let speechRecognition: SpeechRecognition
+let speechRecognition: SpeechRecognition | null = null;
if (window.SpeechRecognition) {
speechRecognition = new SpeechRecognition()
-} else {
- speechRecognition = new webkitSpeechRecognition()
+} else if ((window as any).webkitSpeechRecognition) {
+ speechRecognition = new (window as any).webkitSpeechRecognition() as SpeechRecognition;
}
-export { speechRecognition }
\ No newline at end of file
+const supportsSpeechRecognition = speechRecognition !== null;
+
+export {
+ speechRecognition,
+ supportsSpeechRecognition,
+}
\ No newline at end of file