feat: run crispasr sidecar transcription

This commit is contained in:
Evandro committed 2026-06-11 01:08:05 -03:00
1 parent 2aaad73652
commit 7b726af951
2 files changed
+49 -8

No files matched your search

+48 -7
View File
@@ -1,4 +1,5 @@
use std::path::PathBuf;
use std::process::Command;
use serde::{Deserialize, Serialize};
@@ -34,16 +35,46 @@ impl Transcriber for CrispAsrTranscriber {
return Err(AppError::ModelNotInstalled(input.options.model_id));
};
if self.config.sidecar_name.is_none() {
if !model_path.exists() {
return Err(AppError::InvalidModel(format!(
"modelo não encontrado em {}",
model_path.display()
)));
}
let Some(sidecar_name) = &self.config.sidecar_name else {
return Err(AppError::SidecarNotConfigured);
};
let threads = default_thread_count().to_string();
let output = Command::new(sidecar_name)
.arg("-m")
.arg(model_path)
.arg("-f")
.arg(&input.audio_path)
.arg("-t")
.arg(&threads)
.output()
.map_err(|error| AppError::Transcription(error.to_string()))?;
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr).trim().to_string();
return Err(AppError::Transcription(if stderr.is_empty() {
format!("sidecar encerrou com status {}", output.status)
} else {
stderr
}));
}
let text = String::from_utf8_lossy(&output.stdout).trim().to_string();
if text.is_empty() {
return Err(AppError::Transcription(
"sidecar não retornou texto transcrito".to_string(),
));
}
Ok(TranscriptionResult {
text: format!(
"Transcrição local pendente via CrispASR para {} usando {}.",
input.audio_path.display(),
model_path.display()
),
text,
backend: "crispasr".to_string(),
model_id: input.options.model_id,
detected_language: input.options.language,
@@ -51,6 +82,13 @@ impl Transcriber for CrispAsrTranscriber {
}
}
fn default_thread_count() -> usize {
std::thread::available_parallelism()
.map(|count| count.get())
.unwrap_or(2)
.clamp(1, 4)
}
#[cfg(test)]
mod tests {
use std::path::PathBuf;
@@ -75,6 +113,9 @@ mod tests {
})
.expect_err("modelo ausente deve falhar");
assert_eq!(err, AppError::ModelNotInstalled(DEFAULT_MODEL_ID.to_string()));
assert_eq!(
err,
AppError::ModelNotInstalled(DEFAULT_MODEL_ID.to_string())
);
}
}
+1 -1
View File
@@ -46,7 +46,7 @@ pub(crate) fn stop_recording_and_transcribe(
.clone();
let transcriber = CrispAsrTranscriber::new(CrispAsrConfig {
sidecar_name: None,
sidecar_name: Some("parakeet-main".to_string()),
model_path: Some(default_model_path(&state.model_dir)),
});