|
Β |
nathanbabcock / ffmpeg-sidecar Goto Github PK
View Code? Open in Web Editor NEWWrap a standalone FFmpeg binary in an intuitive Iterator interface. π
License: MIT License
Wrap a standalone FFmpeg binary in an intuitive Iterator interface. π
License: MIT License
|
Β |
Seems like latest version still has check for x86_64 targets.
ffmpeg-sidecar/src/download.rs
Lines 19 to 23 in c4dff09
Also, add a convenience method collect_metadata()
that consumes the iterator until all metadata has been obtained, returning a single struct with all the parsed metadata.
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.
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.
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
On Windows 10, I get several command popup windows when running commands such as ffmpeg_version
, check_latest_version
, and download_ffmpeg_package
.
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()
uses sidecar_path()
which hardcodes .join('ffmepg')
.
Seems like it needs ffmpeg_sidecar_path()
and ffprobe_sidecar_path()
.
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
ffmpeg_sidecar::download::auto_download()
Would there be any way to know the download progress here to show to the users as a percentage?
Would be quite useful, as currently there is requirement for ffmpeg to be in either the path or right next to the rust binary
Hello,
I'm passing a filter_complex
argument, which seems to get translated into -filtergraph
when the ffmpeg CLI is invoked:
Line 469 in ee2e4c0
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?
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?
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.",
))
}
}
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?
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.
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.
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
Current version of the crate uses anyhow::Result
instead of ffmpeg_sidecar::error::Result
, so example fails to compile.
The /examples/
one is correct, though.
hey i'm curious what is the difference with rust-ffmpeg:
https://github.com/zmwangx/rust-ffmpeg
? I'm using rust-ffmpeg atm in https://github.com/louis030195/screen-pipe but might be open to change because of the download feature etc. quite pain to package ffmpeg for deployment
what do you think are pros and cons?
Will fix ASAP...
When running the auto-download for ffmpeg on an M1 mac it fails because its not compatible with non x86 architectures. Is there a way to add it?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.