swarm-stt: only files that start like an audio container reach ffmpeg
This commit is contained in:
parent
f8e1d0fbbd
commit
33e63091d5
1 changed files with 97 additions and 7 deletions
|
|
@ -36,6 +36,12 @@ pub struct Whisper {
|
|||
#[async_trait]
|
||||
impl Engine for Whisper {
|
||||
async fn transcribe(&self, audio: &[u8]) -> Result<String, String> {
|
||||
if !crate::sniff::is_audio(audio) {
|
||||
return Err(
|
||||
"the file does not look like audio (Ogg, WAV, FLAC, MP3, AMR, MP4/M4A, WebM)"
|
||||
.to_owned(),
|
||||
);
|
||||
}
|
||||
let dir = tempfile_in(&self.scratch)
|
||||
.await
|
||||
.map_err(|e| format!("making a scratch directory: {e}"))?;
|
||||
|
|
@ -157,8 +163,8 @@ mod tests {
|
|||
async fn audio_goes_through_ffmpeg_then_whisper_and_the_text_is_trimmed() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let engine = whisper(dir.path(), FFMPEG_OK, WHISPER_ECHO);
|
||||
let text = engine.transcribe(b" hello there \n").await.unwrap();
|
||||
assert_eq!(text, "hello there");
|
||||
let text = engine.transcribe(b"OggS hello there \n").await.unwrap();
|
||||
assert_eq!(text, "OggS hello there");
|
||||
assert_eq!(
|
||||
std::fs::read_dir(dir.path().join("scratch"))
|
||||
.unwrap()
|
||||
|
|
@ -173,7 +179,7 @@ mod tests {
|
|||
let dir = tempfile::tempdir().unwrap();
|
||||
let mut engine = whisper(dir.path(), "sleep 60", WHISPER_ECHO);
|
||||
engine.timeout = std::time::Duration::from_millis(200);
|
||||
let err = engine.transcribe(b"x").await.unwrap_err();
|
||||
let err = engine.transcribe(b"OggSx").await.unwrap_err();
|
||||
assert!(err.contains("timed out"), "{err}");
|
||||
assert_eq!(
|
||||
std::fs::read_dir(dir.path().join("scratch"))
|
||||
|
|
@ -192,7 +198,7 @@ mod tests {
|
|||
record.display()
|
||||
);
|
||||
let engine = whisper(dir.path(), &ffmpeg, WHISPER_ECHO);
|
||||
engine.transcribe(b"x").await.unwrap();
|
||||
engine.transcribe(b"OggSx").await.unwrap();
|
||||
let args = std::fs::read_to_string(record).unwrap();
|
||||
assert!(
|
||||
args.contains("-protocol_whitelist pipe -i pipe:0"),
|
||||
|
|
@ -200,11 +206,25 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn a_file_that_is_not_audio_never_reaches_ffmpeg() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let record = dir.path().join("ran");
|
||||
let ffmpeg = format!("touch {}", record.display());
|
||||
let engine = whisper(dir.path(), &ffmpeg, WHISPER_ECHO);
|
||||
let err = engine
|
||||
.transcribe(b"#EXTM3U\nfile:///etc/passwd")
|
||||
.await
|
||||
.unwrap_err();
|
||||
assert!(err.contains("does not look like audio"), "{err}");
|
||||
assert!(!record.exists(), "ffmpeg was started");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn an_ffmpeg_failure_is_reported_with_its_stderr() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let engine = whisper(dir.path(), "echo 'bad data' >&2; exit 1", WHISPER_ECHO);
|
||||
let err = engine.transcribe(b"x").await.unwrap_err();
|
||||
let err = engine.transcribe(b"OggSx").await.unwrap_err();
|
||||
assert!(
|
||||
err.contains("could not decode") && err.contains("bad data"),
|
||||
"{err}"
|
||||
|
|
@ -215,7 +235,7 @@ mod tests {
|
|||
async fn a_whisper_failure_is_reported_with_its_stderr() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let engine = whisper(dir.path(), FFMPEG_OK, "echo 'no model' >&2; exit 2");
|
||||
let err = engine.transcribe(b"x").await.unwrap_err();
|
||||
let err = engine.transcribe(b"OggSx").await.unwrap_err();
|
||||
assert!(
|
||||
err.contains("whisper-cli failed") && err.contains("no model"),
|
||||
"{err}"
|
||||
|
|
|
|||
Loading…
Reference in a new issue