async_ffmpeg_sidecar/
paths.rs

1//! Utilities for locating FFmpeg binaries on the system
2
3use anyhow::Context;
4use std::{
5  env::current_exe,
6  path::{Path, PathBuf},
7};
8
9/// Returns the default path of the FFmpeg executable, to be used as the
10/// argument to `Command::new`. It should first attempt to locate an FFmpeg
11/// binary adjacent to the Rust executable. If that fails, it should invoke
12/// `ffmpeg` expecting it to be in the system path. If that fails, an
13/// informative error message should be printed (not when this function is
14/// called, but when the command is actually run).
15pub fn ffmpeg_path() -> PathBuf {
16  let default = Path::new("ffmpeg").to_path_buf();
17  match sidecar_path() {
18    Ok(sidecar_path) => match sidecar_path.exists() {
19      true => sidecar_path,
20      false => default,
21    },
22    Err(_) => default,
23  }
24}
25
26/// The (expected) path to an FFmpeg binary adjacent to the Rust binary.
27///
28/// The extension between platforms, with Windows using `.exe`, while Mac and
29/// Linux have no extension.
30pub fn sidecar_path() -> anyhow::Result<PathBuf> {
31  let mut path = current_exe()?
32    .parent()
33    .context("Can't get parent of current_exe")?
34    .join("ffmpeg_dir")
35    .join("ffmpeg");
36  if cfg!(windows) {
37    path.set_extension("exe");
38  }
39  Ok(path)
40}
41
42/// By default, downloads all temporary files to the same directory as the Rust executable.
43pub fn sidecar_dir() -> anyhow::Result<PathBuf> {
44  Ok(
45    sidecar_path()?
46      .parent()
47      .context("invalid sidecar path")?
48      .to_path_buf(),
49  )
50}