feat: Auto-save voice recordings for model training
- Add /api/recordings endpoint with full CRUD operations - Create voice_recordings SQLite table for metadata - Save audio files to server/recordings/ as .webm - Store transcription, duration, microphone name, file size - Auto-save on each Whisper recording completion
This commit is contained in:
@@ -71,6 +71,7 @@ const showMicSelector = ref(false)
|
||||
const lastAudioUrl = ref<string>('')
|
||||
const isPlayingAudio = ref(false)
|
||||
let audioElement: HTMLAudioElement | null = null
|
||||
let recordingStartTime = 0
|
||||
|
||||
function playLastAudio() {
|
||||
if (!lastAudioUrl.value) return
|
||||
@@ -98,6 +99,42 @@ function saveAudioForPlayback(blob: Blob) {
|
||||
URL.revokeObjectURL(lastAudioUrl.value)
|
||||
}
|
||||
lastAudioUrl.value = URL.createObjectURL(blob)
|
||||
|
||||
// Also save to backend for training data
|
||||
saveRecordingToBackend(blob)
|
||||
}
|
||||
|
||||
async function saveRecordingToBackend(blob: Blob) {
|
||||
try {
|
||||
const duration_ms = Date.now() - recordingStartTime
|
||||
const reader = new FileReader()
|
||||
|
||||
reader.onloadend = async () => {
|
||||
const base64 = (reader.result as string).split(',')[1]
|
||||
|
||||
const response = await fetch(`http://${window.location.hostname}:4100/api/recordings`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
audio: base64,
|
||||
transcription: transcript.value.trim(),
|
||||
microphone: currentMicName.value,
|
||||
duration_ms
|
||||
})
|
||||
})
|
||||
|
||||
const data = await response.json()
|
||||
if (data.success) {
|
||||
console.log(`[Voice] Recording saved: ${data.filename} (${(data.size / 1024).toFixed(1)} KB)`)
|
||||
} else {
|
||||
console.error('[Voice] Failed to save recording:', data.error)
|
||||
}
|
||||
}
|
||||
|
||||
reader.readAsDataURL(blob)
|
||||
} catch (e) {
|
||||
console.error('[Voice] Error saving recording:', e)
|
||||
}
|
||||
}
|
||||
|
||||
const currentMicName = computed(() => {
|
||||
@@ -438,6 +475,7 @@ async function startWhisperRecording() {
|
||||
// Start recording
|
||||
mediaRecorder.start(100) // Collect data every 100ms
|
||||
isRecording.value = true
|
||||
recordingStartTime = Date.now()
|
||||
|
||||
// Send chunks periodically for progressive transcription
|
||||
chunkInterval = window.setInterval(() => {
|
||||
|
||||
Reference in New Issue
Block a user