@bryan-gc/transcribe-cli 1.0.6 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/App.d.ts +1 -1
- package/dist/components/App.d.ts.map +1 -1
- package/dist/components/App.js +7 -201
- package/dist/components/App.js.map +1 -1
- package/dist/components/AutoRecordApp.d.ts.map +1 -1
- package/dist/components/AutoRecordApp.js +9 -127
- package/dist/components/AutoRecordApp.js.map +1 -1
- package/dist/components/Header.d.ts +14 -0
- package/dist/components/Header.d.ts.map +1 -0
- package/dist/components/Header.js +8 -0
- package/dist/components/Header.js.map +1 -0
- package/dist/components/MicTest.d.ts.map +1 -1
- package/dist/components/MicTest.js +7 -89
- package/dist/components/MicTest.js.map +1 -1
- package/dist/hooks/useAutoRecord.d.ts +18 -0
- package/dist/hooks/useAutoRecord.d.ts.map +1 -0
- package/dist/hooks/useAutoRecord.js +110 -0
- package/dist/hooks/useAutoRecord.js.map +1 -0
- package/dist/hooks/useMicTest.d.ts +18 -0
- package/dist/hooks/useMicTest.d.ts.map +1 -0
- package/dist/hooks/useMicTest.js +105 -0
- package/dist/hooks/useMicTest.js.map +1 -0
- package/dist/hooks/useTranscriberApp.d.ts +36 -0
- package/dist/hooks/useTranscriberApp.d.ts.map +1 -0
- package/dist/hooks/useTranscriberApp.js +202 -0
- package/dist/hooks/useTranscriberApp.js.map +1 -0
- package/dist/utils/fileUtils.d.ts +22 -0
- package/dist/utils/fileUtils.d.ts.map +1 -0
- package/dist/utils/fileUtils.js +51 -0
- package/dist/utils/fileUtils.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,93 +1,11 @@
|
|
|
1
1
|
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useState, useRef, useEffect, useCallback } from 'react';
|
|
3
2
|
import { Box, Text, useInput } from 'ink';
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import { AudioRecorder } from '../audio/recorder.js';
|
|
7
|
-
import { playAudio, stopPlayback } from '../audio/audioPlayer.js';
|
|
8
|
-
import { RECORDING_TICK_MS, ActionHotkey, TestStatus, getPaths } from '../constants.js';
|
|
9
|
-
const AUTO_STOP_SECS = 5;
|
|
3
|
+
import { useMicTest } from '../hooks/useMicTest.js';
|
|
4
|
+
import { ActionHotkey, TestStatus } from '../constants.js';
|
|
10
5
|
export function MicTest({ mic, basePath, onConfirm, onCancel }) {
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const [errorText, setErrorText] = useState('');
|
|
15
|
-
const testFilePath = getPaths(basePath).TEST_FILE;
|
|
16
|
-
const recorderRef = useRef(new AudioRecorder());
|
|
17
|
-
const timerRef = useRef(null);
|
|
18
|
-
const stoppingRef = useRef(false);
|
|
19
|
-
useEffect(() => {
|
|
20
|
-
const recorderInstance = recorderRef.current;
|
|
21
|
-
return () => {
|
|
22
|
-
clearTimer();
|
|
23
|
-
stoppingRef.current = true;
|
|
24
|
-
recorderInstance.stop().catch(() => { });
|
|
25
|
-
stopPlayback();
|
|
26
|
-
};
|
|
27
|
-
}, []);
|
|
28
|
-
function clearTimer() {
|
|
29
|
-
if (timerRef.current) {
|
|
30
|
-
clearInterval(timerRef.current);
|
|
31
|
-
timerRef.current = null;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
function startRecording() {
|
|
35
|
-
if (status === TestStatus.RECORDING)
|
|
36
|
-
return;
|
|
37
|
-
try {
|
|
38
|
-
const tmpDir = path.dirname(testFilePath);
|
|
39
|
-
if (!fs.existsSync(tmpDir))
|
|
40
|
-
fs.mkdirSync(tmpDir, { recursive: true });
|
|
41
|
-
recorderRef.current.setDevice(mic.id);
|
|
42
|
-
recorderRef.current.start(testFilePath);
|
|
43
|
-
setStatus(TestStatus.RECORDING);
|
|
44
|
-
setElapsed(0);
|
|
45
|
-
setErrorText('');
|
|
46
|
-
timerRef.current = setInterval(() => {
|
|
47
|
-
setElapsed((prev) => {
|
|
48
|
-
const next = prev + 1;
|
|
49
|
-
if (next >= AUTO_STOP_SECS)
|
|
50
|
-
stopRecording();
|
|
51
|
-
return next;
|
|
52
|
-
});
|
|
53
|
-
}, RECORDING_TICK_MS);
|
|
54
|
-
}
|
|
55
|
-
catch (e) {
|
|
56
|
-
setErrorText(`Recording error: ${e instanceof Error ? e.message : String(e)}`);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
const stopRecording = useCallback(async () => {
|
|
60
|
-
if (stoppingRef.current)
|
|
61
|
-
return;
|
|
62
|
-
stoppingRef.current = true;
|
|
63
|
-
clearTimer();
|
|
64
|
-
setStatus(TestStatus.SAVING);
|
|
65
|
-
await recorderRef.current.stop();
|
|
66
|
-
stoppingRef.current = false;
|
|
67
|
-
setStatus(TestStatus.RECORDED);
|
|
68
|
-
setHasRecording(true);
|
|
69
|
-
}, []);
|
|
70
|
-
async function handlePlayback() {
|
|
71
|
-
if (!hasRecording || !fs.existsSync(testFilePath)) {
|
|
72
|
-
setErrorText('No test recording found. Record first.');
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
setStatus(TestStatus.PLAYING);
|
|
76
|
-
setErrorText('');
|
|
77
|
-
try {
|
|
78
|
-
await playAudio(testFilePath);
|
|
79
|
-
}
|
|
80
|
-
catch (e) {
|
|
81
|
-
setErrorText(`Playback error: ${e instanceof Error ? e.message : String(e)}`);
|
|
82
|
-
}
|
|
83
|
-
finally {
|
|
84
|
-
setStatus(TestStatus.RECORDED);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
function handleStopPlayback() {
|
|
88
|
-
stopPlayback();
|
|
89
|
-
setStatus(TestStatus.RECORDED);
|
|
90
|
-
}
|
|
6
|
+
const { state, actions } = useMicTest(mic, basePath);
|
|
7
|
+
const { status, hasRecording, elapsed, errorText, AUTO_STOP_SECS } = state;
|
|
8
|
+
const { startRecording, stopRecording, handlePlayback, handleStopPlayback } = actions;
|
|
91
9
|
useInput((input, key) => {
|
|
92
10
|
const k = input.toLowerCase();
|
|
93
11
|
if (key.escape || k === ActionHotkey.CANCEL_C) {
|
|
@@ -133,7 +51,7 @@ export function MicTest({ mic, basePath, onConfirm, onCancel }) {
|
|
|
133
51
|
}
|
|
134
52
|
};
|
|
135
53
|
// ─── Action list ──────────────────────────────────────────────────────────
|
|
136
|
-
const
|
|
54
|
+
const actionList = () => {
|
|
137
55
|
switch (status) {
|
|
138
56
|
case TestStatus.RECORDING:
|
|
139
57
|
return _jsxs(Text, { color: "yellow", children: ["[", ActionHotkey.STOP, "] Stop recording early"] });
|
|
@@ -145,6 +63,6 @@ export function MicTest({ mic, basePath, onConfirm, onCancel }) {
|
|
|
145
63
|
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: "cyan", children: ["[", ActionHotkey.RECORD, "]", ' ', status === TestStatus.RECORDED ? 'Record Again' : 'Record Test', ' ', _jsxs(Text, { dimColor: true, children: ["(auto-stops at ", AUTO_STOP_SECS, "s)"] })] }), hasRecording && _jsxs(Text, { color: "cyan", children: ["[", ActionHotkey.PLAYBACK, "] Play Back"] }), _jsxs(Text, { color: "green", children: ["[", ActionHotkey.CONFIRM, "] Confirm \u2014 use this microphone"] }), _jsxs(Text, { color: "red", children: ["[", ActionHotkey.CANCEL_C, "] Cancel \u2014 choose a different mic"] })] }));
|
|
146
64
|
}
|
|
147
65
|
};
|
|
148
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: '=== Microphone Test ===' }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Text, { children: ["Microphone: ", _jsx(Text, { color: "magenta", children: mic.label })] }), _jsxs(Text, { children: ["Device ID: ", _jsx(Text, { dimColor: true, children: mic.id })] })] }), _jsx(Box, { marginTop: 1, marginBottom: 1, children: statusLine() }),
|
|
66
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: '=== Microphone Test ===' }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Text, { children: ["Microphone: ", _jsx(Text, { color: "magenta", children: mic.label })] }), _jsxs(Text, { children: ["Device ID: ", _jsx(Text, { dimColor: true, children: mic.id })] })] }), _jsx(Box, { marginTop: 1, marginBottom: 1, children: statusLine() }), actionList(), errorText !== '' && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "red", children: ["\u26A0\uFE0F ", errorText] }) })), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: ["Esc/[", ActionHotkey.CANCEL_C, "] cancel \u00B7 [", ActionHotkey.CONFIRM, "]/Enter confirm"] }) })] }));
|
|
149
67
|
}
|
|
150
68
|
//# sourceMappingURL=MicTest.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MicTest.js","sourceRoot":"","sources":["../../src/components/MicTest.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"MicTest.js","sourceRoot":"","sources":["../../src/components/MicTest.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { AppConfig } from '../config/configManager.js';
|
|
2
|
+
export declare function useAutoRecord(appConfig: AppConfig, exit: () => void): {
|
|
3
|
+
state: {
|
|
4
|
+
statusText: string;
|
|
5
|
+
isRecording: boolean;
|
|
6
|
+
isTranscribing: boolean;
|
|
7
|
+
transcriptionResult: string;
|
|
8
|
+
activeLanguage: import("../constants.js").LanguageCode;
|
|
9
|
+
activeMic: import("../audio/micDevices.js").MicDevice;
|
|
10
|
+
activeGlossary: string;
|
|
11
|
+
currentTextPath: string;
|
|
12
|
+
};
|
|
13
|
+
actions: {
|
|
14
|
+
handleStopAndTranscribe: () => Promise<void>;
|
|
15
|
+
forceStop: () => void;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=useAutoRecord.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAutoRecord.d.ts","sourceRoot":"","sources":["../../src/hooks/useAutoRecord.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAK5D,wBAAgB,aAAa,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,IAAI;;;;;;;;;;;;;;;EA8HnE"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { useState, useEffect, useRef } from 'react';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import { AudioRecorder } from '../audio/recorder.js';
|
|
4
|
+
import { WhisperTranscriber } from '../transcriber/WhisperTranscriber.js';
|
|
5
|
+
import { extractTextFromSrt } from '../utils/srtParser.js';
|
|
6
|
+
import { copyTextToClipboard } from '../utils/clipboard.js';
|
|
7
|
+
import { listMicDevices } from '../audio/micDevices.js';
|
|
8
|
+
import { getTimestampPaths, readGlossaryContent, getInitialGlossary } from '../utils/fileUtils.js';
|
|
9
|
+
import { Encoding, LANGUAGE_NAMES, TranscriptionFormat } from '../constants.js';
|
|
10
|
+
export function useAutoRecord(appConfig, exit) {
|
|
11
|
+
const [statusText, setStatusText] = useState('Initializing recording...');
|
|
12
|
+
const [isRecording, setIsRecording] = useState(false);
|
|
13
|
+
const [isTranscribing, setIsTranscribing] = useState(false);
|
|
14
|
+
const [transcriptionResult, setTranscriptionResult] = useState('');
|
|
15
|
+
const [currentAudioPath, setCurrentAudioPath] = useState('');
|
|
16
|
+
const [currentSrtPath, setCurrentSrtPath] = useState('');
|
|
17
|
+
const [currentTextPath, setCurrentTextPath] = useState('');
|
|
18
|
+
const recorderRef = useRef(null);
|
|
19
|
+
const transcriberRef = useRef(null);
|
|
20
|
+
const activeLanguage = appConfig.selectedLanguage;
|
|
21
|
+
const activeMicId = appConfig.selectedMicrophone;
|
|
22
|
+
const mics = listMicDevices();
|
|
23
|
+
const activeMic = mics.find((m) => m.id === activeMicId) ?? {
|
|
24
|
+
id: activeMicId,
|
|
25
|
+
label: activeMicId,
|
|
26
|
+
};
|
|
27
|
+
const activeGlossary = getInitialGlossary(appConfig.basePath);
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
const recorder = new AudioRecorder();
|
|
30
|
+
recorderRef.current = recorder;
|
|
31
|
+
transcriberRef.current = new WhisperTranscriber(appConfig.apiKey);
|
|
32
|
+
try {
|
|
33
|
+
recorder.setDevice(activeMic.id);
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// Ignore if device fails, recorder will try default
|
|
37
|
+
}
|
|
38
|
+
const p = getTimestampPaths(appConfig.basePath);
|
|
39
|
+
setCurrentAudioPath(p.audioPath);
|
|
40
|
+
setCurrentSrtPath(p.srtPath);
|
|
41
|
+
setCurrentTextPath(p.textPath);
|
|
42
|
+
recorder.start(p.audioPath);
|
|
43
|
+
setIsRecording(true);
|
|
44
|
+
setStatusText('🔴 Recording... Press [Enter] to stop and transcribe.');
|
|
45
|
+
return () => {
|
|
46
|
+
if (recorderRef.current) {
|
|
47
|
+
recorderRef.current.stop().catch(() => { });
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
}, [appConfig, activeMic.id]);
|
|
51
|
+
const handleStopAndTranscribe = async () => {
|
|
52
|
+
if (!recorderRef.current || !transcriberRef.current || !isRecording || isTranscribing) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
setIsRecording(false);
|
|
57
|
+
setIsTranscribing(true);
|
|
58
|
+
setStatusText('⏹️ Stopped recording. Saving file...');
|
|
59
|
+
await recorderRef.current.stop();
|
|
60
|
+
recorderRef.current = null;
|
|
61
|
+
if (!fs.existsSync(currentAudioPath)) {
|
|
62
|
+
setStatusText('❌ Error: Audio file was not generated.');
|
|
63
|
+
setTimeout(exit, 2000);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const glossaryPrompt = readGlossaryContent(appConfig.basePath, activeGlossary);
|
|
67
|
+
setStatusText(`⏳ Transcribing (${LANGUAGE_NAMES[activeLanguage]}${glossaryPrompt ? ' + glossary' : ''})...`);
|
|
68
|
+
const srtContent = await transcriberRef.current.transcribe(currentAudioPath, activeLanguage, TranscriptionFormat.SRT, glossaryPrompt, (msg) => setStatusText(`⏳ Transcribing: ${msg}`));
|
|
69
|
+
setStatusText('⏳ Formatting text and saving files...');
|
|
70
|
+
fs.writeFileSync(currentSrtPath, srtContent, Encoding.UTF8);
|
|
71
|
+
const cleanText = extractTextFromSrt(srtContent);
|
|
72
|
+
fs.writeFileSync(currentTextPath, cleanText, Encoding.UTF8);
|
|
73
|
+
setTranscriptionResult(cleanText);
|
|
74
|
+
if (appConfig.autoCopy) {
|
|
75
|
+
copyTextToClipboard(cleanText);
|
|
76
|
+
setStatusText('✅ Transcription done — copied to clipboard.');
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
setStatusText('✅ Transcription completed and saved.');
|
|
80
|
+
}
|
|
81
|
+
setTimeout(exit, 500);
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
setStatusText(`❌ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
85
|
+
setIsTranscribing(false);
|
|
86
|
+
setTimeout(exit, 3000);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
const forceStop = () => {
|
|
90
|
+
if (recorderRef.current)
|
|
91
|
+
recorderRef.current.stop().catch(() => { });
|
|
92
|
+
};
|
|
93
|
+
return {
|
|
94
|
+
state: {
|
|
95
|
+
statusText,
|
|
96
|
+
isRecording,
|
|
97
|
+
isTranscribing,
|
|
98
|
+
transcriptionResult,
|
|
99
|
+
activeLanguage,
|
|
100
|
+
activeMic,
|
|
101
|
+
activeGlossary,
|
|
102
|
+
currentTextPath,
|
|
103
|
+
},
|
|
104
|
+
actions: {
|
|
105
|
+
handleStopAndTranscribe,
|
|
106
|
+
forceStop,
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=useAutoRecord.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAutoRecord.js","sourceRoot":"","sources":["../../src/hooks/useAutoRecord.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { MicDevice } from '../audio/micDevices.js';
|
|
2
|
+
import { TestStatus } from '../constants.js';
|
|
3
|
+
export declare function useMicTest(mic: MicDevice, basePath: string): {
|
|
4
|
+
state: {
|
|
5
|
+
status: TestStatus;
|
|
6
|
+
hasRecording: boolean;
|
|
7
|
+
elapsed: number;
|
|
8
|
+
errorText: string;
|
|
9
|
+
AUTO_STOP_SECS: number;
|
|
10
|
+
};
|
|
11
|
+
actions: {
|
|
12
|
+
startRecording: () => void;
|
|
13
|
+
stopRecording: () => Promise<void>;
|
|
14
|
+
handlePlayback: () => Promise<void>;
|
|
15
|
+
handleStopPlayback: () => void;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=useMicTest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useMicTest.d.ts","sourceRoot":"","sources":["../../src/hooks/useMicTest.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAqB,UAAU,EAAY,MAAM,iBAAiB,CAAC;AAE1E,wBAAgB,UAAU,CAAC,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM;;;;;;;;;8BA6B9B,IAAI;;8BAmCE,OAAO,CAAC,IAAI,CAAC;kCAgBf,IAAI;;EAoBpC"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { useState, useRef, useEffect, useCallback } from 'react';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { AudioRecorder } from '../audio/recorder.js';
|
|
5
|
+
import { playAudio, stopPlayback } from '../audio/audioPlayer.js';
|
|
6
|
+
import { RECORDING_TICK_MS, TestStatus, getPaths } from '../constants.js';
|
|
7
|
+
export function useMicTest(mic, basePath) {
|
|
8
|
+
const AUTO_STOP_SECS = 5;
|
|
9
|
+
const [status, setStatus] = useState(TestStatus.IDLE);
|
|
10
|
+
const [hasRecording, setHasRecording] = useState(false);
|
|
11
|
+
const [elapsed, setElapsed] = useState(0);
|
|
12
|
+
const [errorText, setErrorText] = useState('');
|
|
13
|
+
const testFilePath = getPaths(basePath).TEST_FILE;
|
|
14
|
+
const recorderRef = useRef(new AudioRecorder());
|
|
15
|
+
const timerRef = useRef(null);
|
|
16
|
+
const stoppingRef = useRef(false);
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
const recorderInstance = recorderRef.current;
|
|
19
|
+
return () => {
|
|
20
|
+
clearTimer();
|
|
21
|
+
stoppingRef.current = true;
|
|
22
|
+
recorderInstance.stop().catch(() => { });
|
|
23
|
+
stopPlayback();
|
|
24
|
+
};
|
|
25
|
+
}, []);
|
|
26
|
+
function clearTimer() {
|
|
27
|
+
if (timerRef.current) {
|
|
28
|
+
clearInterval(timerRef.current);
|
|
29
|
+
timerRef.current = null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function startRecording() {
|
|
33
|
+
if (status === TestStatus.RECORDING)
|
|
34
|
+
return;
|
|
35
|
+
try {
|
|
36
|
+
const tmpDir = path.dirname(testFilePath);
|
|
37
|
+
if (!fs.existsSync(tmpDir))
|
|
38
|
+
fs.mkdirSync(tmpDir, { recursive: true });
|
|
39
|
+
recorderRef.current.setDevice(mic.id);
|
|
40
|
+
recorderRef.current.start(testFilePath);
|
|
41
|
+
setStatus(TestStatus.RECORDING);
|
|
42
|
+
setElapsed(0);
|
|
43
|
+
setErrorText('');
|
|
44
|
+
timerRef.current = setInterval(() => {
|
|
45
|
+
setElapsed((prev) => {
|
|
46
|
+
const next = prev + 1;
|
|
47
|
+
if (next >= AUTO_STOP_SECS)
|
|
48
|
+
stopRecording();
|
|
49
|
+
return next;
|
|
50
|
+
});
|
|
51
|
+
}, RECORDING_TICK_MS);
|
|
52
|
+
}
|
|
53
|
+
catch (e) {
|
|
54
|
+
setErrorText(`Recording error: ${e instanceof Error ? e.message : String(e)}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const stopRecording = useCallback(async () => {
|
|
58
|
+
if (stoppingRef.current)
|
|
59
|
+
return;
|
|
60
|
+
stoppingRef.current = true;
|
|
61
|
+
clearTimer();
|
|
62
|
+
setStatus(TestStatus.SAVING);
|
|
63
|
+
await recorderRef.current.stop();
|
|
64
|
+
stoppingRef.current = false;
|
|
65
|
+
setStatus(TestStatus.RECORDED);
|
|
66
|
+
setHasRecording(true);
|
|
67
|
+
}, []);
|
|
68
|
+
async function handlePlayback() {
|
|
69
|
+
if (!hasRecording || !fs.existsSync(testFilePath)) {
|
|
70
|
+
setErrorText('No test recording found. Record first.');
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
setStatus(TestStatus.PLAYING);
|
|
74
|
+
setErrorText('');
|
|
75
|
+
try {
|
|
76
|
+
await playAudio(testFilePath);
|
|
77
|
+
}
|
|
78
|
+
catch (e) {
|
|
79
|
+
setErrorText(`Playback error: ${e instanceof Error ? e.message : String(e)}`);
|
|
80
|
+
}
|
|
81
|
+
finally {
|
|
82
|
+
setStatus(TestStatus.RECORDED);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function handleStopPlayback() {
|
|
86
|
+
stopPlayback();
|
|
87
|
+
setStatus(TestStatus.RECORDED);
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
state: {
|
|
91
|
+
status,
|
|
92
|
+
hasRecording,
|
|
93
|
+
elapsed,
|
|
94
|
+
errorText,
|
|
95
|
+
AUTO_STOP_SECS,
|
|
96
|
+
},
|
|
97
|
+
actions: {
|
|
98
|
+
startRecording,
|
|
99
|
+
stopRecording,
|
|
100
|
+
handlePlayback,
|
|
101
|
+
handleStopPlayback,
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=useMicTest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useMicTest.js","sourceRoot":"","sources":["../../src/hooks/useMicTest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { AudioRecorder } from '../audio/recorder.js';
|
|
2
|
+
import { type MicDevice } from '../audio/micDevices.js';
|
|
3
|
+
import { type AppConfig } from '../config/configManager.js';
|
|
4
|
+
import { LanguageCode, ViewMode, MenuAction } from '../constants.js';
|
|
5
|
+
export declare function useTranscriberApp(appConfig: AppConfig, exit: () => void): {
|
|
6
|
+
state: {
|
|
7
|
+
viewMode: ViewMode;
|
|
8
|
+
selectedIndex: number;
|
|
9
|
+
statusText: string;
|
|
10
|
+
isRecording: boolean;
|
|
11
|
+
isPaused: boolean;
|
|
12
|
+
isTranscribing: boolean;
|
|
13
|
+
transcriptionResult: string;
|
|
14
|
+
clipboardEnabled: boolean;
|
|
15
|
+
currentTextPath: string;
|
|
16
|
+
activeLanguage: LanguageCode;
|
|
17
|
+
activeGlossary: string;
|
|
18
|
+
activeMic: MicDevice;
|
|
19
|
+
pendingMic: MicDevice;
|
|
20
|
+
micDevices: MicDevice[];
|
|
21
|
+
glossaryFiles: string[];
|
|
22
|
+
recorder: AudioRecorder;
|
|
23
|
+
};
|
|
24
|
+
actions: {
|
|
25
|
+
setViewMode: import("react").Dispatch<import("react").SetStateAction<ViewMode>>;
|
|
26
|
+
setSelectedIndex: import("react").Dispatch<import("react").SetStateAction<number>>;
|
|
27
|
+
setStatusText: import("react").Dispatch<import("react").SetStateAction<string>>;
|
|
28
|
+
setActiveLanguage: import("react").Dispatch<import("react").SetStateAction<LanguageCode>>;
|
|
29
|
+
setActiveGlossary: import("react").Dispatch<import("react").SetStateAction<string>>;
|
|
30
|
+
setActiveMic: import("react").Dispatch<import("react").SetStateAction<MicDevice>>;
|
|
31
|
+
setPendingMic: import("react").Dispatch<import("react").SetStateAction<MicDevice>>;
|
|
32
|
+
handleAction: (actionId: MenuAction) => Promise<void>;
|
|
33
|
+
saveConfig: (updates: Partial<AppConfig>) => void;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=useTranscriberApp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTranscriberApp.d.ts","sourceRoot":"","sources":["../../src/hooks/useTranscriberApp.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAkB,KAAK,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAIxE,OAAO,EAAE,KAAK,SAAS,EAAiB,MAAM,4BAA4B,CAAC;AAE3E,OAAO,EAIL,YAAY,EAIZ,QAAQ,EACR,UAAU,EACX,MAAM,iBAAiB,CAAC;AAEzB,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;iCAqDnD,UAAU;8BApBjB,OAAO,CAAC,SAAS,CAAC;;EA4L/B"}
|