ffmpeg_sidecar/
ffprobe.rs

1//! Utilities related to the FFprobe binary.
2
3use crate::command::BackgroundCommand;
4use anyhow::Context;
5use std::{env::current_exe, ffi::OsStr, path::PathBuf};
6use std::{
7  path::Path,
8  process::{Command, Stdio},
9};
10
11/// Returns the path of the downloaded FFprobe executable, or falls back to
12/// assuming its installed in the system path. Note that not all FFmpeg
13/// distributions include FFprobe.
14pub fn ffprobe_path() -> PathBuf {
15  let default = Path::new("ffprobe").to_path_buf();
16  match ffprobe_sidecar_path() {
17    Ok(sidecar_path) => match sidecar_path.exists() {
18      true => sidecar_path,
19      false => default,
20    },
21    Err(_) => default,
22  }
23}
24
25/// The (expected) path to an FFmpeg binary adjacent to the Rust binary.
26///
27/// The extension between platforms, with Windows using `.exe`, while Mac and
28/// Linux have no extension.
29pub fn ffprobe_sidecar_path() -> anyhow::Result<PathBuf> {
30  let mut path = current_exe()?
31    .parent()
32    .context("Can't get parent of current_exe")?
33    .join("ffprobe");
34  if cfg!(windows) {
35    path.set_extension("exe");
36  }
37  Ok(path)
38}
39
40/// Alias for `ffprobe -version`, parsing the version number and returning it.
41pub fn ffprobe_version() -> anyhow::Result<String> {
42  ffprobe_version_with_path(ffprobe_path())
43}
44
45/// Lower level variant of `ffprobe_version` that exposes a customized the path
46/// to the ffmpeg binary.
47pub fn ffprobe_version_with_path<S: AsRef<OsStr>>(path: S) -> anyhow::Result<String> {
48  let output = Command::new(&path)
49    .arg("-version")
50    .create_no_window()
51    .output()?;
52
53  // note:version parsing is not implemented for ffprobe
54
55  Ok(String::from_utf8(output.stdout)?)
56}
57
58/// Verify whether ffprobe is installed on the system. This will return true if
59/// there is an ffprobe binary in the PATH, or in the same directory as the Rust
60/// executable.
61pub fn ffprobe_is_installed() -> bool {
62  Command::new(ffprobe_path())
63    .create_no_window()
64    .arg("-version")
65    .stderr(Stdio::null())
66    .stdout(Stdio::null())
67    .status()
68    .map(|s| s.success())
69    .unwrap_or_else(|_| false)
70}