use std::time::Duration;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AudioSpec {
pub sample_rate: u32,
pub channels: u16,
pub encoding: String,
}
impl AudioSpec {
pub fn new(sample_rate: u32, encoding: impl Into<String>) -> Self {
Self { sample_rate, channels: 1, encoding: encoding.into() }
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Outgoing {
Text(String),
Binary(Vec<u8>),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum WsMessage<'a> {
Text(&'a str),
Binary(&'a [u8]),
}
#[derive(Debug, Clone)]
pub struct Handshake {
pub url: String,
pub headers: Vec<(String, String)>,
}
impl Handshake {
pub fn new(url: impl Into<String>) -> Self {
Self { url: url.into(), headers: Vec::new() }
}
pub fn header(mut self, name: impl Into<String>, value: impl Into<String>) -> Self {
self.headers.push((name.into(), value.into()));
self
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum SttEvent {
Partial {
text: String,
language: Option<String>,
},
Final {
text: String,
language: Option<String>,
audio_ms: Option<f64>,
},
EmptyFinal { audio_ms: Option<f64> },
SpeechStarted,
SpeechEnded,
Error(String),
Ignore,
}
pub trait SttProvider: Send + Sync + 'static {
fn name(&self) -> &'static str;
fn audio(&self) -> &AudioSpec;
fn handshake(&self) -> Handshake;
fn on_connected(&self) -> Vec<Outgoing> {
Vec::new()
}
fn encode_audio(&self, pcm_le: &[u8]) -> Outgoing;
fn finalize_msg(&self) -> Option<Outgoing> {
None
}
fn close_msg(&self) -> Option<Outgoing> {
None
}
fn keepalive(&self) -> Option<(Duration, Outgoing)> {
None
}
fn parse(&self, msg: WsMessage<'_>) -> SttEvent;
}