download_ffmpeg/
download_ffmpeg.rs

1#[cfg(feature = "download_ffmpeg")]
2fn main() -> anyhow::Result<()> {
3  use ffmpeg_sidecar::{
4    command::ffmpeg_is_installed,
5    download::{check_latest_version, download_ffmpeg_package, ffmpeg_download_url, unpack_ffmpeg},
6    paths::sidecar_dir,
7    version::ffmpeg_version_with_path,
8  };
9  use std::env::current_exe;
10
11  if ffmpeg_is_installed() {
12    println!("FFmpeg is already installed! 🎉");
13    println!("For demo purposes, we'll re-download and unpack it anyway.");
14    println!("TIP: Use `auto_download()` to skip manual customization.");
15  }
16
17  // Short version without customization:
18  // ```rust
19  // ffmpeg_sidecar::download::auto_download().unwrap();
20  // ```
21
22  // Checking the version number before downloading is actually not necessary,
23  // but it's a good way to check that the download URL is correct.
24  match check_latest_version() {
25    Ok(version) => println!("Latest available version: {version}"),
26    Err(_) => println!("Skipping version check on this platform."),
27  }
28
29  // These defaults will automatically select the correct download URL for your
30  // platform.
31  let download_url = ffmpeg_download_url()?;
32  let cli_arg = std::env::args().nth(1);
33  let destination = match cli_arg {
34    Some(arg) => resolve_relative_path(current_exe()?.parent().unwrap().join(arg)),
35    None => sidecar_dir()?,
36  };
37
38  // The built-in download function uses `reqwest` to download the package.
39  // For more advanced use cases like async streaming or download progress
40  // updates, you could replace this with your own download function.
41  println!("Downloading from: {download_url:?}");
42  let archive_path = download_ffmpeg_package(download_url, &destination)?;
43  println!("Downloaded package: {archive_path:?}");
44
45  // Extraction uses `tar` on all platforms (available in Windows since version 1803)
46  println!("Extracting...");
47  unpack_ffmpeg(&archive_path, &destination)?;
48
49  // Use the freshly installed FFmpeg to check the version number
50  let version = ffmpeg_version_with_path(destination.join("ffmpeg"))?;
51  println!("FFmpeg version: {version}");
52
53  println!("Done! 🏁");
54  Ok(())
55}
56
57#[cfg(feature = "download_ffmpeg")]
58fn resolve_relative_path(path_buf: std::path::PathBuf) -> std::path::PathBuf {
59  use std::path::{Component, PathBuf};
60
61  let mut components: Vec<PathBuf> = vec![];
62  for component in path_buf.as_path().components() {
63    match component {
64      Component::Prefix(_) | Component::RootDir => components.push(component.as_os_str().into()),
65      Component::CurDir => (),
66      Component::ParentDir => {
67        if !components.is_empty() {
68          components.pop();
69        }
70      }
71      Component::Normal(component) => components.push(component.into()),
72    }
73  }
74  PathBuf::from_iter(components)
75}
76
77#[cfg(not(feature = "download_ffmpeg"))]
78fn main() {
79  eprintln!(r#"This example requires the "download_ffmpeg" feature to be enabled."#);
80  println!("The feature is included by default unless manually disabled.");
81  println!("Please run `cargo run --example download_ffmpeg`.");
82}