use std::fmt;
use std::str::FromStr;
use crate::error::Result;
use crate::types::{AudioBuffer, ImageBuffer, OcrOutput, TimedSegment, Transcript, VideoFrame};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum Task {
Asr,
Tts,
Ocr,
Vlm,
}
impl fmt::Display for Task {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
Task::Asr => "asr",
Task::Tts => "tts",
Task::Ocr => "ocr",
Task::Vlm => "vlm",
})
}
}
impl FromStr for Task {
type Err = String;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
match s.to_ascii_lowercase().as_str() {
"asr" => Ok(Task::Asr),
"tts" => Ok(Task::Tts),
"ocr" => Ok(Task::Ocr),
"vlm" => Ok(Task::Vlm),
other => Err(format!("unknown task `{other}` (expected asr, tts, ocr, or vlm)")),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EngineStatus {
Stub,
Experimental,
Stable,
}
impl fmt::Display for EngineStatus {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
EngineStatus::Stub => "stub",
EngineStatus::Experimental => "experimental",
EngineStatus::Stable => "stable",
})
}
}
#[derive(Debug, Clone)]
pub struct EngineInfo {
pub name: String,
pub task: Task,
pub status: EngineStatus,
pub description: String,
}
#[derive(Debug, Clone, Default)]
pub struct AsrOptions {
pub language: Option<String>,
pub word_timestamps: bool,
pub diarize: bool,
pub translate: bool,
}
#[derive(Debug, Clone)]
pub struct TtsOptions {
pub voice: Option<String>,
pub speed: f32,
}
impl Default for TtsOptions {
fn default() -> Self {
TtsOptions { voice: None, speed: 1.0 }
}
}
#[derive(Debug, Clone, Default)]
pub struct OcrOptions {
pub languages: Vec<String>,
}
#[derive(Debug, Clone, Default)]
pub struct VlmOptions {
pub prompt: Option<String>,
pub max_new_tokens: Option<usize>,
}
pub trait AsrEngine: Send + Sync {
fn info(&self) -> EngineInfo;
fn transcribe(&self, audio: &AudioBuffer, opts: &AsrOptions) -> Result<Transcript>;
}
pub trait TtsEngine: Send + Sync {
fn info(&self) -> EngineInfo;
fn synthesize(&self, text: &str, opts: &TtsOptions) -> Result<AudioBuffer>;
}
pub trait OcrEngine: Send + Sync {
fn info(&self) -> EngineInfo;
fn recognize(&self, image: &ImageBuffer, opts: &OcrOptions) -> Result<OcrOutput>;
}
pub trait VlmEngine: Send + Sync {
fn info(&self) -> EngineInfo;
fn describe_image(&self, image: &ImageBuffer, opts: &VlmOptions) -> Result<String>;
fn describe_video(
&self,
frames: &[VideoFrame],
opts: &VlmOptions,
) -> Result<Vec<TimedSegment<String>>>;
}