最小化的 FFmpeg Rust 封装,专注于音频解码与在线流播放。
- 零环境依赖 — FFmpeg 与 mbedTLS 源码以 git submodule 内嵌,
cargo build一气呵成,不需要FFMPEG_DIR/PKG_CONFIG_PATH等环境变量,也不依赖系统装的 FFmpeg - 开箱即用的 HTTPS — 编译时启用
file/http/https/tcp/tls协议与 mbedTLS 后端,无需任何额外 TLS 库 - API 兼容 — 上层 API 形状镜像
ffmpeg-next8.x 的音频子集,可作为精简替代 - 小巧 — 仅包含
libavcodec/libavformat/libavutil/libswresample,不带lavfilter/lavdevice/swscale/ 编码器 / muxer - 音频解码齐全 — 内置 MP3 / AAC / FLAC / Opus / Vorbis / ALAC / APE / WAV / WMA / DSD / DCA / EAC3 / TrueHD 等常见格式
- 跨平台 — Windows x64 (MSVC) / macOS (arm64 + x64) / Linux x64
Cargo.toml:
[dependencies]
ffmpeg-min = { git = "https://github.com/SPlayer-Dev/ffmpeg-min" }解码本地音频:
use ffmpeg_min as ffmpeg;
use ffmpeg_min::media::Type;
let mut input = ffmpeg::format::input("song.mp3")?;
let stream = input.streams().best(Type::Audio).unwrap();
let stream_index = stream.index();
let ctx = ffmpeg::codec::context::Context::from_parameters(stream.parameters())?;
let mut decoder = ctx.decoder().audio()?;
let mut packet = ffmpeg::codec::packet::Packet::empty();
let mut frame = ffmpeg::frame::Audio::empty();
loop {
match packet.read(&mut input) {
Ok(()) if packet.stream() == stream_index => {
decoder.send_packet(&packet)?;
while decoder.receive_frame(&mut frame).is_ok() {
// frame.plane::<f32>(0) 拿样本
}
}
Err(ffmpeg::Error::Eof) => break,
_ => continue,
}
}打开 HTTPS 流:
let mut opts = ffmpeg::Dictionary::new();
opts.set("reconnect", "1");
opts.set("reconnect_streamed", "1");
opts.set("rw_timeout", "15000000");
opts.set("user_agent", "MyApp/1.0");
let mut input = ffmpeg::format::input_with_dictionary(
"https://example.com/track.flac",
opts,
)?;完整可运行示例见 ffmpeg-min/examples/。
| 平台 | 工具链 | CI | 备注 |
|---|---|---|---|
| Windows x64 | MSVC 2022 | ✅ | |
| macOS arm64 | clang (≥ 11.0) | ✅ | |
| Linux x64 | gcc / clang (glibc) | ✅ | |
| macOS x64 | clang (≥ 10.15) | GitHub Actions Intel runner 排队太久;用 scripts/bootstrap-unix.sh 在 Intel Mac 本地生成 configs |
其他目标(iOS、Android、Linux musl 等)可仿照 scripts/bootstrap-unix.sh 自行添加配置。
ffmpeg-min/
├── ffmpeg-min-sys/ 底层 sys crate(裸 FFI)
│ ├── ffmpeg/ FFmpeg 源码 submodule(锁 n8.1.1)
│ ├── mbedtls/ mbedTLS 源码 submodule(锁 v3.6.2)
│ ├── configs/ 每平台预生成的 FFmpeg configure 产物
│ └── build.rs 读 configs/ → cc 静态编 → bindgen 生成绑定
└── ffmpeg-min/ 高层 safe wrapper(镜像 ffmpeg-next 8.x 音频子集)
├── src/ error / log / dict / format / codec / frame / resampling …
└── examples/ 可运行示例
git clone --recurse-submodules https://github.com/SPlayer-Dev/ffmpeg-min
cd ffmpeg-min
cargo build --release首次构建约 5-10 分钟(编 200+ 个 C 文件 + mbedTLS),后续增量构建走 Cargo 缓存基本瞬时。
如果是初次设置仓库(configs/ 为空),需要先为目标平台生成 FFmpeg 配置——详见 BOOTSTRAP.md。
如果 clone 时忘了 --recurse-submodules:
git submodule update --init --recursive# 自检:必须包含 file / http / https / tcp / tls
cargo run --release --example sanity -p ffmpeg-min
# 本地解码
cargo run --release --example decode_local -p ffmpeg-min -- path/to/song.mp3
# HTTPS 流链路
cargo run --release --example stream_https -p ffmpeg-min为保持最小化,以下功能不会纳入:视频解码 / 帧处理、编码器、muxer、滤镜(lavfilter)、图像缩放(swscale)、硬件加速、输入/输出设备(avdevice / indevs / outdevs)。
如需上述能力,请使用完整的 ffmpeg-next。
LGPL-2.1-or-later