Files
voice-to-notes/src-tauri/src/commands/transcribe.rs

131 lines
3.6 KiB
Rust
Raw Normal View History

use serde_json::{json, Value};
use tauri::{AppHandle, Emitter};
use crate::sidecar::messages::IPCMessage;
use crate::sidecar::sidecar;
/// Start transcription of an audio file via the Python sidecar.
#[tauri::command]
pub fn transcribe_file(
file_path: String,
model: Option<String>,
device: Option<String>,
language: Option<String>,
) -> Result<Value, String> {
let manager = sidecar();
manager.ensure_running()?;
let request_id = uuid::Uuid::new_v4().to_string();
let msg = IPCMessage::new(
&request_id,
"transcribe.start",
json!({
"file": file_path,
"model": model.unwrap_or_else(|| "base".to_string()),
"device": device.unwrap_or_else(|| "cpu".to_string()),
"compute_type": "int8",
"language": language,
}),
);
let response = manager.send_and_receive(&msg)?;
if response.msg_type == "error" {
return Err(format!(
"Transcription error: {}",
response
.payload
.get("message")
.and_then(|v| v.as_str())
.unwrap_or("unknown")
));
}
Ok(response.payload)
}
/// Download and validate the diarization model via the Python sidecar.
#[tauri::command]
pub fn download_diarize_model(hf_token: String) -> Result<Value, String> {
let manager = sidecar();
manager.ensure_running()?;
let request_id = uuid::Uuid::new_v4().to_string();
let msg = IPCMessage::new(
&request_id,
"diarize.download",
json!({
"hf_token": hf_token,
}),
);
let response = manager.send_and_receive(&msg)?;
if response.msg_type == "error" {
return Ok(json!({
"ok": false,
"error": response.payload.get("message").and_then(|v| v.as_str()).unwrap_or("unknown"),
}));
}
Ok(json!({ "ok": true }))
}
/// Run the full transcription + diarization pipeline via the Python sidecar.
#[tauri::command]
pub fn run_pipeline(
app: AppHandle,
file_path: String,
model: Option<String>,
device: Option<String>,
language: Option<String>,
num_speakers: Option<u32>,
min_speakers: Option<u32>,
max_speakers: Option<u32>,
skip_diarization: Option<bool>,
hf_token: Option<String>,
) -> Result<Value, String> {
let manager = sidecar();
manager.ensure_running()?;
let request_id = uuid::Uuid::new_v4().to_string();
let msg = IPCMessage::new(
&request_id,
"pipeline.start",
json!({
"file": file_path,
"model": model.unwrap_or_else(|| "base".to_string()),
"device": device.unwrap_or_else(|| "cpu".to_string()),
"compute_type": "int8",
"language": language,
"num_speakers": num_speakers,
"min_speakers": min_speakers,
"max_speakers": max_speakers,
"skip_diarization": skip_diarization.unwrap_or(false),
"hf_token": hf_token,
}),
);
let response = manager.send_and_receive_with_progress(&msg, |msg| {
let event_name = match msg.msg_type.as_str() {
"pipeline.segment" => "pipeline-segment",
"pipeline.speaker_update" => "pipeline-speaker-update",
_ => "pipeline-progress",
};
let _ = app.emit(event_name, &msg.payload);
})?;
if response.msg_type == "error" {
return Err(format!(
"Pipeline error: {}",
response
.payload
.get("message")
.and_then(|v| v.as_str())
.unwrap_or("unknown")
));
}
Ok(response.payload)
}