v2.0.0
✨ 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
tou32
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
- Remove tar dependency and used platform specific dependencies for different formats by @VirtualPirate in #51
- feat!: Add audio and subtitle stream parsing by @PanCakeConnaisseur in #50
- feat: Add option alias for subtitle codec by @PanCakeConnaisseur in #54
- feat: create named pipes by @nathanbabcock in #53
- chore: remove deprecated curl functions by @nathanbabcock in #55
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