main: use spooled temp files where possible, instead of "mic.wav"

This commit is contained in:
2026-06-02 21:50:57 +02:00
parent 2957be7b04
commit 2e880ca552
3 changed files with 43 additions and 6 deletions
+35 -6
View File
@@ -10,11 +10,12 @@ use serde::{Deserialize, Serialize};
use ratatui::{Frame, layout::{Constraint, Direction, Layout}, widgets::{Block, BorderType, Clear, Gauge, List, ListDirection, ListItem, ListState, Paragraph, Wrap}};
use serde_json::Value;
use sqlite::OpenFlags;
use tempfile::SpooledData;
use throbber_widgets_tui::{Throbber, ThrobberState};
use crossterm::{event::{self, EventStream, KeyCode, KeyModifiers}};
use tokio::{sync::watch, time::Instant};
use tui_input::{Input, backend::crossterm::EventHandler};
use std::{io::Read, process::Command};
use std::{cell::RefCell, io::Read, process::Command, rc::Rc, sync::{Arc, Mutex}};
use futures::{StreamExt, future::FutureExt};
// TODO: We should have a separate 'state.json' file, which remembers jack connections, and the world time for the show to end. Then we only update the 'time remaining' field in the scene and only deal with relative durations inside the scene data
@@ -528,6 +529,25 @@ enum AudioRecordRequest {
Finish
}
struct RcFile<T>(Arc<Mutex<T>>);
impl<T: std::io::Write> std::io::Write for RcFile<T> {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.0.lock().unwrap().write(buf)
}
fn flush(&mut self) -> std::io::Result<()> {
self.0.lock().unwrap().flush()
}
}
impl<T: std::io::Seek> std::io::Seek for RcFile<T> {
fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result<u64> {
self.0.lock().unwrap().seek(pos)
}
}
#[tokio::main]
async fn main() {
color_eyre::install().unwrap();
@@ -582,7 +602,9 @@ async fn main() {
let mut meter = VuMeter::new(rate.into(), 1, None);
let spool_size = 16 * (rate as usize) * 10;// 10 seconds of audio
let mut writer = None;
let mut outfile = None;
let client: Client<OpenAIConfig> = Client::default();
@@ -592,16 +614,23 @@ async fn main() {
let audio_event = maybe_audio_event.unwrap();
match audio_event {
AudioRecordRequest::Start => {
// FIXME: We should switch this over to using spooled tempfiles instead of a named file in the current directory that can easily get clobbered
//const SPOOL_SIZE: usize = 16 * (rate as usize) * 10;// 10 seconds of audio
//let mut outfile = tempfile::spooled_tempfile(SPOOL_SIZE);
writer = Some(hound::WavWriter::create("mic.wav", spec).unwrap());
outfile = Some(Arc::new(Mutex::new(tempfile::spooled_tempfile(spool_size))));
writer = Some(hound::WavWriter::new(RcFile(outfile.as_ref().unwrap().clone()), spec).unwrap());
},
AudioRecordRequest::Finish => {
writer = None;
let final_audio = outfile.take().unwrap();
let bytes = match Arc::into_inner(final_audio).unwrap().into_inner().unwrap().into_inner() {
SpooledData::OnDisk(mut file) => {
let mut bytes = Vec::new();
file.read_to_end(&mut bytes).unwrap();
bytes.into()
},
SpooledData::InMemory(cursor) => cursor.into_inner().into(),
};
let response = client.audio().transcription().create(CreateTranscriptionRequest {
file: AudioInput { source: InputSource::Path { path: "mic.wav".into() } },
file: AudioInput { source: InputSource::Bytes { filename: "transcription.wav".into(), bytes } },
model: "gpt-4o-mini-transcribe".into(),
..Default::default()
}).await.unwrap();