async_ffmpeg_sidecar/
version.rs

1use crate::command::BackgroundCommand;
2use crate::event::FfmpegEvent;
3use crate::log_parser::FfmpegLogParser;
4use crate::paths::ffmpeg_path;
5use anyhow::Context;
6use std::ffi::OsStr;
7use std::process::Stdio;
8use tokio::io::BufReader;
9use tokio::process::Command;
10
11/// Alias for `ffmmpeg -version`, parsing the version number and returning it.
12pub async fn ffmpeg_version() -> anyhow::Result<String> {
13  ffmpeg_version_with_path(ffmpeg_path()).await
14}
15
16/// Lower level variant of `ffmpeg_version`  that exposes a customized path
17/// to the ffmepg binary
18pub async fn ffmpeg_version_with_path<P: AsRef<OsStr>>(path: P) -> anyhow::Result<String> {
19  let mut cmd = Command::new(&path)
20    .create_no_window()
21    .arg("-version")
22    .stdout(Stdio::piped())
23    .spawn()?;
24
25  let stdout = cmd.stdout.take().context("no stdout channel")?;
26  let reader = BufReader::new(stdout);
27  let mut parser = FfmpegLogParser::new(reader);
28
29  let mut version: Option<String> = None;
30  while let Ok(event) = parser.parse_next_event().await {
31    match event {
32      FfmpegEvent::ParsedVersion(v) => version = Some(v.version),
33      FfmpegEvent::LogEOF => break,
34      _ => {}
35    }
36  }
37
38  let exit_status = cmd.wait().await?;
39  if !exit_status.success() {
40    anyhow::bail!("ffmpeg -version exited with non-zero status");
41  }
42
43  version.context("failed to parse ffmpeg version")
44}