Code Monkey home page Code Monkey logo

ffmpeg-sidecar's Introduction

ffmpeg-sidecar's People

Contributors

avsaase avatar bvc3at avatar emirror-de avatar nathanbabcock avatar odilf avatar samrat avatar sobieg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

ffmpeg-sidecar's Issues

Broken with ffmpeg 7.0

I have been successfully using this crate for a few months on a personal project, but when I tried to update to ffmpeg to the new 7.0 release today, I ran into some issues.

In particular, it seems FfmpegEvent::Progress no longer parses correctly, causing that event to never be processed.

Adding metadata to videos

First off, thanks for the fantastic work on this crate, it's very useful and easy to use.

I'm currently using this crate to stitch together images to create a video using the image2 muxer, like so:

let pbar = ProgressBar::new(num_frames);

let cmd = format!(
    "-framerate {fps} -f image2 -i {pattern} -y -vcodec libx264 -crf 22 -pix_fmt yuv420p {outfile}"
);

let mut ffmpeg_runner = FfmpegCommand::new().args(cmd.split(' ')).spawn().unwrap();
ffmpeg_runner
    .iter()
    .unwrap()
    .filter_progress()
    .for_each(|progress| pbar.set_position(progress.frame as u64));
pbar.finish_and_clear();

However, I'd like to add metadata to the resulting video. According to the ffmpeg docs I can do so by adding an argument like "-metadata title='some cool title'" right before the output file. If I do this in the above example the code silently fails. I'm not entirely sure what's going on but my guess is that splitting the command on spaces causes issues.

Any suggestions for this? Is there a way to better report any errors that ffmpeg might be silently throwing? In fact, I've noticed that if the command starts with ffmpeg it also fails silently.

Prompt to overwrite file hangs infinitely waiting for stdin

If the -y or -n is not set and the user attempts to overwrite an image, the CLI will prompt the user for input:

File 'test.webp' already exists. Overwrite? [y/N]

However this will be invisible when used from within ffmpeg-sidecar, and nothing will be parsed in the logs since there's no newline at the end of the stderr buffer while it's prompting the user for input.

I think the solution is to start the CLI with -nostdin by default, if not otherwise specified β€” but need to double-check that this isn't a breaking change for packages which rely on sending a quit command (q) over stdin to gracefully end the ffmpeg process.

The workaround is to use -y, -n, -nostdin, or just avoid overwriting without those flags set.

Found by @jtof-dev

[Windows] Commands create popup cmd windows on each call

On Windows 10, I get several command popup windows when running commands such as ffmpeg_version, check_latest_version, and download_ffmpeg_package.

cmd popup window

I see that for the FfmpegCommand there is a create_no_window method that I think it does that, it flags the command process to create no windows or keep them hidden.

Could we do the same for all other commands like curl, curl_to_file etc.?

ffprobe_path returns ffmpeg path

ffprobe_path() uses sidecar_path() which hardcodes .join('ffmepg').

Seems like it needs ffmpeg_sidecar_path() and ffprobe_sidecar_path().

How to bundle as binary instead of running on runtime?

Is there a way to install this library as a binary instead of downloading on runtime?

Only functions I can see is
ffmpeg_sidecar::download::auto_download().unwrap();

So users download it as part of the bundle instead of download the application, then calling this which downloads the ffmpeg again?

Not really a bug, appreciate the help

Error: Unrecognized option 'filtergraph'

Hello,

I'm passing a filter_complex argument, which seems to get translated into -filtergraph when the ffmpeg CLI is invoked:

self.arg("-filtergraph");

However, for version 6.0, this flag doesn't seem to exist. I also couldn't find any docs for older versions pointing to this flag.

Was this a typo?

Issue running on MacOS

I suspect there is an issue with parsing the ffmpeg output on MacOS. When running the examples, execution gets blocked at creating the FfmpegIterator. I did a little digging and it turns out only one event is received from the thread that parses the ffmpeg output and then it hangs:

[src/iter.rs:35] &event = ParsedVersion(
    FfmpegVersion {
        version: "N-109875-geabc304d12-tessus",
        raw_log_message: "[info] ffmpeg version N-109875-geabc304d12-tessus  https://evermeet.cx/ffmpeg/  Copyright (c) 2000-2023 the FFmpeg developers\n[info]   built with Apple clang version 11.0.0 (clang-1100.0.33.17)\n[info]   configuration: --cc=/usr/bin/clang --prefix=/opt/ffmpeg --extra-version=tessus --enable-avisynth --enable-fontconfig --enable-gpl --enable-libaom --enable-libass --enable-libbluray --enable-libdav1d --enable-libfreetype --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libmysofa --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-libopenjpeg --enable-libopus --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvmaf --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libzimg --enable-libzmq --enable-libzvbi --enable-version3 --pkg-config-flags=--static --disable-ffplay\n[info]   libavutil      58.  1.100 / 58.  1.100\n[info]   libavcodec     60.  2.100 / 60.  2.100\n[info]   libavformat    60.  2.100 / 60.  2.100\n[info]   libavdevice    60.  0.100 / 60.  0.100\n[info]   libavfilter     9.  2.100 /  9.  2.100\n[info]   libswscale      7.  0.100 /  7.  0.100\n[info]   libswresample   4.  9.100 /  4.  9.100\n[info]   libpostproc    57.  0.100 / 57.  0.100\n[info] Input #0, lavfi, from 'testsrc=duration=10':\n[info]   Duration: N/A, start: 0.000000, bitrate: N/A\n[info]   Stream #0:0: Video: wrapped_avframe, rgb24, 320x240 [SAR 1:1 DAR 4:3], 25 fps, 25 tbr, 25 tbn\n[info] Stream mapping:\n[info]   Stream #0:0 -> #0:0 (wrapped_avframe (native) -> rawvideo (native))\n[info] Press [q] to stop, [?] for help\n[info] Output #0, rawvideo, to 'pipe:':\n[info]   Metadata:\n[info]     encoder         : Lavf60.2.100\n[info]   Stream #0:0: Video: rawvideo (RGB[24] / 0x18424752), rgb24(progressive), 320x240 [SAR 1:1 DAR 4:3], q=2-31, 46080 kb/s, 25 fps, 25 tbn\n[info]     Metadata:\n[info]       encoder         : Lavc60.2.100 rawvideo\n[info] frame=    0 fps=0.0 q=0.0 size=       0kB time=-577014:32:22.77 bitrate=  -0.0kbits/s speed=N/A",
    },
)

Compared to the debug output on Windows it looks it parses the complete output as a ParsedVersion. Maybe something to do with line endings?

consider downloading ffmpeg and ffprobe from https://github.com/eugeneware/ffmpeg-static

Use https://github.com/eugeneware/ffmpeg-static as it contains both ffmpeg and ffprobe and supports lot of different OS and architectures.

Currently it uses multiple domains. Having all from github.com would be great.

/// URL for the latest published FFmpeg release. The correct URL for the target
/// platform is baked in at compile time.
pub fn ffmpeg_download_url() -> Result<&'static str> {
  if cfg!(all(target_os = "windows", target_arch = "x86_64")) {
    Ok("https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip")
  } else if cfg!(all(target_os = "linux", target_arch = "x86_64")) {
    Ok("https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz")
  } else if cfg!(all(target_os = "macos", target_arch = "x86_64")) {
    Ok("https://evermeet.cx/ffmpeg/getrelease")
  } else if cfg!(all(target_os = "macos", target_arch = "aarch64")) {
    Ok("https://www.osxexperts.net/ffmpeg6arm.zip") // Mac M1
  } else {
    Err(Error::msg(
      "Unsupported platform; you can provide your own URL instead and call download_ffmpeg_package directly.",
    ))
  }
}

Download fails due to sidecar path under restricted system directories

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?

Consider adding `anyhow` as a dependency

I have been using this crate for a project and it is fantastic! However, there is one problem: it doesn't play nicely with anyhow. This is mainly because the error doesn't implement Send and Sync. While looking through the code I realized that there is an error module that does things very similarly to anyhow. In fact, it would be very easy to change all errors and results to the anyhow equivalents. That would also bring along all other benefits of anyhow such as the size of struct being only a usize, better ergonomics, etc.

I understand that this project has a "no dependency" rule. I don't know if that's a hard rule for you, but I would consider changing it. Currently it seems that the error module is just a worse version of anyhow, so why not add actual anyhow as a dependency? The only concrete reason I can think of for not using it as a dependency is because of compile time concerns, but it's usually faster because crates can be compiled in parallel and compilations shared between subdependencies. Rust has little of the disadvantages that some other languages have with deps. Re-inventing the wheel in this way is very rarely a good idea.

I understand that sometimes open source contributors get a lot of often unreasonable demands, so I want to reiterate that I really appreciate your work! This is just a thing I think is good to consider to make the crate even better 😁

I would be more than glad to do the migration to anyhow myself if I get the approval.

Would it be possible to include the frame timestamp in `OutputVideoFrame`?

First, I want to thank you for making this crate. ffmpeg is a powerful tool but it can be a major pain to work with, especially via the rust bindings available in many crates. Dealing with the CLI is slightly better but still far from ergonomic. This crate makes it so much better!

I was wondering if ffmpeg emits the frame timestamp when outputting rawvideo, and if so if this data can be captured and included in OutputVideoFrame. I'm using your library to overlay images on top off the video frames and for aligning the images and the video frame it be a lot easier if I had access to each frame's timestamp. The Progress(FfmpegProgress) event does not get emitted for every decoded frame so it's not usable for this purpose.

add support for ffprobe

Seems like this downloads ffmpeg and ffprobe and correctly places both the files after extraction. But there are no equivalent functions for ffprobe. Would it be possible to add these?

  • ffprobe_version()
  • ffprobe_path()
  • FfprobeCommand

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.