Skip to content

v2.0.0

Compare
Choose a tag to compare
@nathanbabcock nathanbabcock released this 01 Nov 22:29
· 22 commits to main since this release
2248e96

✨ Highlights

TL;DR: Minimal breaking changes, improvements under the hood, and some powerful new tools

Audio stream metadata parsing

One of the main purposes of ffmpeg-sidecar is to parse detailed metadata from log messages emitted by the FFmpeg CLI. Before now, metadata was only supported for video streams. In v2.0, that support is extended to audio streams as well. Information like sample_rate and channels are available both in the iterator events ParsedInputStream and ParsedOutputStream, as well as the FfmpegMetadata struct.

This is a small breaking change, since in v1.x the AVStream struct had fields that only correspond to video. In 2.x, this is replaced by a broader Stream struct which can be narrowed down into specific variants via methods like is_video(), video_data(), is_audio(), and audio_data(). Migrating to 2.x only requires adding one of those checks before using the video metadata. Code that didn't read video metadata or reference the AVStream struct directly will continue to work without any changes.

There's room here for future contributions to also augment the Subtitle and Other stream types with granular metadata as well.

Thank you to @PanCakeConnaisseur for this contribution! 🎉

Robust download handling

This is a feature that already landed in v1.2. Under the hood we've transitioned to using reqwest to manage downloads of FFmpeg binaries. In v2.0 we are removing the deprecated curl() and curl_to_file() methods. Unless you were importing and using these methods directly, no migration is needed!

For some background on this: ffmpeg-sidecar launched with a very lightweight download mechanism which relied on curl and tar binaries being available in the host environment. This resonated with the "sidecar" ethos — relying on industry-standard and widely available binaries rather than statically linking with source code dependencies to do the same thing. Since then, the auto-download feature has grown in popularity and may sometimes be used in environments where assumptions can't be made about the availability or behavior of curl, tar, and others. Maybe there is room for a curl-sidecar crate here...but for the purposes of this library, using reqwest for downloads gives a better guarantee of consistency across platforms, including CI environments.

The reqwest implementation is behind a crate feature named download_ffmpeg, which is enabled by default. If you prefer the sidecar curl approach or any other one, you can disable the feature and roll your own function for it.

Thank you to @VirtualPirate for this contribution! 🎉

Cross-platform named pipe support

One of the most powerful use cases for ffmpeg-sidecar is to stream data directly from FFmpeg's output into your Rust program for further processing. Then it can be used for various purposes like computer vision, image processing, or transcoding.

This approach is limited to a single output when using the most straightforward approach of outputting onto stdout from FFmpeg. It would be difficult to separate video and audio streams without spawning two separate instances of FFmepg (and potentially decoding the file twice). However, some downstream applications like Cap have extended this approach to support OS-level named pipes.

In v2.0, a new optional crate feature called named_pipes provides a cross-platform abstraction over named pipes for the purposes of interop with FFmpeg. Some of the nuances of named pipes can be difficult to work with, particularly when it comes to synchronization logic about connecting to a pipe, whether it blocks while waiting for output to begin, etc — and these behaviors vary between Windows and Unix. The NamedPipe struct provides a minimal wrapper over these details, and examples/named_pipes.rs has an end-to-end example that can be taken as a starting point.

This crate feature is opt-in and disabled by default, since it requires OS dependencies (either winapi or nix) for a fairly niche use-case. Another alternative to consider would be using local TCP sockets to support multiple output streams, which have a bit more consistent and predictable behavior with great performance. See examples/sockets.rs for an example of that approach.

Other/misc

  • Switched from usize to u32 for some metadata struct fields
  • Fixed a bug where the first progress message would be missed if it contained "bitrate=N/A"
  • Improved the output of print_command() debug method to split the command onto multiple lines for better readability

PRs

New Contributors

  • 📢 New contributors are welcome! For the most part this is a simple-to-understand and beginner-friendly codebase.
  • @PanCakeConnaisseur made their first contribution in #50

Full Changelog: v1.2.0...v2.0.0