nathanbabcock / ffmpeg-sidecar

Wrap a standalone FFmpeg binary in an intuitive Iterator interface. 🏍
MIT License
284 stars 20 forks source link

Download fails due to sidecar path under restricted system directories #43

Closed clytras closed 2 months ago

clytras commented 2 months ago

In a case when the app is living inside a restricted directory, like C:\Program Files on Windows, the download_ffmpeg_package fails with the error Failed to download ffmpeg. I believe this happens because curl does not have elevated access to write inside program files, thus it fails with that error internally.

I think the best approach to such issues, is to allow changing the default sidecar directory location to an unprivileged path. Is there a way to change the default sidecard directory?

nathanbabcock commented 2 months ago

I'll have to think about a better way to handle this situation automatically, but the short answer is yes, you can customize the sidecar directory pretty easily. Instead of using the auto_download() function directly, you should copy and paste the few lines inside it and customize your desired paths:

  let download_url = ffmpeg_download_url()?;
  let destination = sidecar_dir()?;
  let archive_path = download_ffmpeg_package(download_url, &destination)?;
  unpack_ffmpeg(&archive_path, &destination)?;

You can also deconstruct the download_ffmpeg example to accomplish the same thing.

clytras commented 2 months ago

And how the rest of the ecosystem will know about that changed sidecar directory to go and look for the binaries?

I mean, the ffmpeg_path uses the sidecar_path which it uses the current_exe path and ffmpeg_path falls back to default ffmpeg, so, if I download the binaries to a sidecar path that is not in the system PATH, how it will know about that custom sidecarr path? Will it work then?

I'll try this out and see if it works.

nathanbabcock commented 2 months ago

You're right that the other methods will not automatically know to look in a nonstandard place, so you will need to use variants such as FfmpegCommand::new_with_path(), ffmpeg_version_with_path(), ffprobe_version_with_path(), etc.

Another option would be to add ffmpeg to the system path after downloading it using some third party crate. Rather than having the library do something like that automatically, I'd leave that up to each application on a case-by-case basis.

clytras commented 2 months ago

I didn't see such functions and methods exist! That will work perfectly, thank you 💪

bliongosari1 commented 2 months ago

Hi @nathanbabcock @clytras

I had the same issues with restricted system directories so I installed them manually using this

    let download_url = ffmpeg_download_url().unwrap_or("");
    let destination = ffmpeg_path_dir();
    let archive_path = download_ffmpeg_package(download_url, &destination);
    println!("archive_path: {:?}", archive_path);

    match archive_path {
        Ok(archive_path) => {
            println!("unpacking ffmpeg");
            let _ffmpeg = unpack_ffmpeg(&archive_path, &destination);
            println!("ffmpeg unpacked");
            let _version = ffmpeg_version_with_path(destination.join("ffmpeg"));
        }
        Err(_) => {
            println!("Error while downloading ffmpeg");
        }
    }

When I try to install ffmpeg using the functions here it fails when unpacking with this error message

tar: Error opening archive: Failed to open '/Users/username/Library/Application Support/app_data/ffmpeg/ffmpeg7arm.zip'

and when I check if its installed it will be false

  Command::new(ffmpeg_path_dir())
  .arg("-version")
  .create_no_window()
  .stderr(Stdio::null())
  .stdout(Stdio::null())
  .status()
  .map(|s| s.success())
  .unwrap_or_else(|_| false)

Any thoughts?