ffmpeg_sidecar/
ffprobe.rs

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
//! Utilities related to the FFprobe binary.

use crate::command::BackgroundCommand;
use anyhow::Context;
use std::{env::current_exe, ffi::OsStr, path::PathBuf};
use std::{
  path::Path,
  process::{Command, Stdio},
};

/// Returns the path of the downloaded FFprobe executable, or falls back to
/// assuming its installed in the system path. Note that not all FFmpeg
/// distributions include FFprobe.
pub fn ffprobe_path() -> PathBuf {
  let default = Path::new("ffprobe").to_path_buf();
  match ffprobe_sidecar_path() {
    Ok(sidecar_path) => match sidecar_path.exists() {
      true => sidecar_path,
      false => default,
    },
    Err(_) => default,
  }
}

/// The (expected) path to an FFmpeg binary adjacent to the Rust binary.
///
/// The extension between platforms, with Windows using `.exe`, while Mac and
/// Linux have no extension.
pub fn ffprobe_sidecar_path() -> anyhow::Result<PathBuf> {
  let mut path = current_exe()?
    .parent()
    .context("Can't get parent of current_exe")?
    .join("ffprobe");
  if cfg!(windows) {
    path.set_extension("exe");
  }
  Ok(path)
}

/// Alias for `ffprobe -version`, parsing the version number and returning it.
pub fn ffprobe_version() -> anyhow::Result<String> {
  ffprobe_version_with_path(ffprobe_path())
}

/// Lower level variant of `ffprobe_version` that exposes a customized the path
/// to the ffmpeg binary.
pub fn ffprobe_version_with_path<S: AsRef<OsStr>>(path: S) -> anyhow::Result<String> {
  let output = Command::new(&path)
    .arg("-version")
    .create_no_window()
    .output()?;

  // note:version parsing is not implemented for ffprobe

  Ok(String::from_utf8(output.stdout)?)
}

/// Verify whether ffprobe is installed on the system. This will return true if
/// there is an ffprobe binary in the PATH, or in the same directory as the Rust
/// executable.
pub fn ffprobe_is_installed() -> bool {
  Command::new(ffprobe_path())
    .create_no_window()
    .arg("-version")
    .stderr(Stdio::null())
    .stdout(Stdio::null())
    .status()
    .map(|s| s.success())
    .unwrap_or_else(|_| false)
}