-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathasync_transcribe.rs
More file actions
83 lines (70 loc) · 2.72 KB
/
async_transcribe.rs
File metadata and controls
83 lines (70 loc) · 2.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
//! Async transcription example
//!
//! Shows async batch transcription using tokio. For real-time streaming,
//! use WhisperStreamPcm which already has its own reader thread.
//!
//! Requires: `cargo run --example async_transcribe --features async`
#[cfg(feature = "async")]
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
use whisper_cpp_plus::WhisperContext;
let model_path = find_model("ggml-tiny.en.bin")
.ok_or("Model not found. Run: cargo xtask test-setup")?;
println!("Loading model from {:?}...", model_path);
let ctx = WhisperContext::new(&model_path)?;
// Load audio
let audio = load_audio()?;
println!("Loaded {} samples ({:.1}s)", audio.len(), audio.len() as f64 / 16000.0);
// Async transcription — runs in blocking threadpool
println!("\nTranscribing asynchronously...");
let text = ctx.transcribe_async(audio).await?;
println!("Result: {}", text);
Ok(())
}
#[cfg(not(feature = "async"))]
fn main() {
eprintln!("This example requires the `async` feature:");
eprintln!(" cargo run --example async_transcribe --features async");
}
#[cfg(feature = "async")]
fn find_model(name: &str) -> Option<std::path::PathBuf> {
use std::path::Path;
for env_var in ["WHISPER_TEST_MODEL_DIR", "WHISPER_MODEL_PATH"] {
if let Ok(dir) = std::env::var(env_var) {
let path = std::path::Path::new(&dir).join(name);
if path.exists() { return Some(path); }
}
}
let paths = [
format!("tests/models/{}", name),
format!("whisper-cpp-plus/tests/models/{}", name),
format!("../whisper-cpp-plus-sys/whisper.cpp/models/{}", name),
format!("whisper-cpp-plus-sys/whisper.cpp/models/{}", name),
];
paths.iter().find(|p| Path::new(p).exists()).map(std::path::PathBuf::from)
}
#[cfg(feature = "async")]
fn load_audio() -> Result<Vec<f32>, Box<dyn std::error::Error>> {
use std::path::Path;
let path = std::env::var("WHISPER_TEST_AUDIO_DIR")
.ok()
.map(|d| format!("{}/jfk.wav", d))
.filter(|p| Path::new(p).exists())
.or_else(|| {
let paths = [
"../whisper-cpp-plus-sys/whisper.cpp/samples/jfk.wav",
"whisper-cpp-plus-sys/whisper.cpp/samples/jfk.wav",
];
paths.iter().find(|p| Path::new(*p).exists()).map(|s| s.to_string())
})
.ok_or("No audio file found")?;
println!("Loading audio from {}...", path);
let mut reader = hound::WavReader::open(&path)?;
let spec = reader.spec();
let samples: Vec<f32> = reader
.samples::<i16>()
.step_by(spec.channels as usize)
.map(|s| s.unwrap() as f32 / 32768.0)
.collect();
Ok(samples)
}