Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
avioflow (Rust)
Rust bindings for AvioFlow, a high-performance audio library built on FFmpeg.
The crate wraps the same C++ core as the Python, Node.js, Java and WebAssembly
bindings, reached through the C ABI the core exports
(avioflow/include/avioflow-c-api.h). FFmpeg is linked statically,
so there is nothing to install or locate at runtime.
Install
[]
= "0.7"
Building the crate compiles the native core, so the host needs a C++17 compiler and CMake 3.20 or newer. The first build downloads a prebuilt FFmpeg package and takes a few minutes; later builds are cached.
Conventions
- Sample layout is always planar float:
samples[channel][sample], with every channel the same length. A ragged input is rejected rather than truncated. - Fallible calls return
Result<T, Error>. [Error::kind] classifies the failure and [Error::message] carries the text from the native layer. - Handles are
Sendbut notSync. Move a decoder, encoder or resampler between threads freely; sharing one across threads needs external synchronization. - Options use builders. Unset fields keep the source format rather than applying a default.
Decoding
AudioDecoder
| Method | Purpose |
|---|---|
new(&StreamOptions) -> Result<Self> |
Create a decoder. |
load_file(&str) -> Result<Metadata> |
Open a file path, URL or device. |
load_buffer(&[u8]) -> Result<Metadata> |
Open complete file bytes in memory. |
feed(&[u8]) -> Result<()> |
Push encoded bytes for streaming decode. |
flush() -> Result<()> |
Mark streaming input complete. |
get_samples() -> Result<Vec<Vec<f32>>> |
Decode everything remaining. |
get_samples_range(f64, Option<f64>) -> Result<Vec<Vec<f32>>> |
Decode [start, stop) in seconds. |
get_frame() -> Result<Option<Frame<'_>>> |
Decode one frame without copying. |
is_finished() -> Result<bool> |
Whether the stream is exhausted. |
metadata() -> Result<Metadata> |
Current stream metadata. |
StreamOptions
| Builder | Effect when unset |
|---|---|
output_sample_rate(i32) |
Preserves the source rate. |
output_num_channels(i32) |
Preserves the source channel count. |
input_sample_rate(i32) |
Required for raw PCM streaming. |
input_channels(i32) |
Required for raw PCM streaming. |
input_format(&str) |
Required to use feed. |
Offline decoding
use ;
#
load_file reports the source stream. The resampler is not configured until
the first frame is decoded, so when output_sample_rate is set, the new rate
appears in metadata() after decoding rather than in the value load_file
returns.
Time-range decoding
# use ;
#
Each call seeks independently, so one decoder can serve many ranges. Range
decoding requires offline mode; in stream mode only (0.0, None) is valid.
Frame-by-frame, zero-copy
# use ;
#
Frame borrows the decoder, so the compiler prevents holding a frame across the
next decode call that would invalidate its buffers.
Streaming decode
use ;
#
For raw PCM input, also set input_sample_rate and input_channels.
Resampling
Two entry points: [resample] for a buffer held in full, [AudioResampler] for
audio arriving in chunks.
One-shot
use resample;
#
Chunked
use ;
#
flush() is not optional. The resampler holds back the last few milliseconds to
keep filter continuity, and skipping the flush discards them. Filter state
carries across process calls, so chunked output matches a one-shot conversion
sample for sample — calling resample per chunk instead would introduce a
discontinuity at every boundary.
output_num_channels() returns 0 until the first process call reveals the
input channel count. The channel count must not change between calls.
Encoding
One-shot
use ;
#
Reusable encoder
use ;
#
WriteOptions
| Builder | Common values |
|---|---|
codec_name(&str) |
"pcm_s16le", "flac", "aac", "libmp3lame", "libopus" |
container_format(&str) |
"wav", "flac", "mp4", "ogg", "adts" |
sample_format(&str) |
"s16", "s32", "flt", "fltp" |
sample_rate(i32) |
8000, 16000, 44100, 48000 |
num_channels(i32) |
1, 2 |
bit_rate(i64) |
128000, 192000, 320000 |
overwrite(bool) |
Defaults to true |
Unset fields are inferred from the container and the input samples.
Info and diagnostics
#
Metadata without a full decode:
# use ;
#
Metadata also carries num_samples, num_channels, bit_rate and
sample_format. Note codec is the FFmpeg decoder name, so an MP3 file
reports "mp3float" while container reports "mp3".
Error handling
use ;
#
Error implements std::error::Error, so it works with ? and Box<dyn Error>.
Building from a repository checkout
build.rs configures the repository root with static linkage. To pass extra CMake arguments — for example to reuse an already
downloaded FFmpeg package:
AVIOFLOW_CMAKE_ARGS="-DFETCHCONTENT_SOURCE_DIR_FFMPEG_BIN=/path/to/ffmpeg"
The crate version is derived from the repository's version.txt; run
python3 scripts/sync_version.py after changing it rather than editing
Cargo.toml directly.
Publishing
The crate compiles the C++ core, but Cargo can only publish files inside
rust/, so the native sources must be staged there first:
rust/native/ is generated and gitignored; build.rs uses it when present and
falls back to the repository root otherwise, so a checkout needs no vendoring to
run cargo test.
Verify the package builds as a consumer would before publishing, since a publish is irreversible — a version can be yanked but never replaced:
&&
CI runs this same check on every tag.
Platform support
Verified on Linux x86_64. The macOS and Windows link configuration is implemented but not yet exercised in CI.
avioflow/core/compat/glibc-finite-compat.c supplies the __*_finite math
symbols that glibc 2.31 removed, which the bundled libvorbis still refers to.
They are compiled in whenever FFmpeg is linked statically on Linux, which is
what the crate does; the other bindings link shared FFmpeg, which does not refer
to them.
License
MIT