14 个版本 (3 个稳定版)
1.1.0 | 2024 年 4 月 14 日 |
---|---|
1.0.1 | 2024 年 2 月 23 日 |
0.5.1 | 2023 年 10 月 13 日 |
0.4.1 | 2023 年 4 月 26 日 |
0.1.0 | 2023 年 2 月 15 日 |
#7 在 多媒体 类别中
每月下载量 887
被 4 个 Crates 使用(其中 3 个直接使用)
110KB
2K SLoC
FFmpeg Sidecar 🏍
将独立的 FFmpeg 二进制文件包裹在直观的 Iterator 接口内。
特性
- ✨ 最小化依赖
- ⚡ 自动下载 FFmpeg CLI(如果需要)
- 🤗 支持 Windows、MacOS 和 Linux
- 🧪 详尽的单元测试
👉 跳转到 入门指南 👈
动机
本项目的核心目标是提供一种方法,可以将任何视频 视为一组原始 RGB 帧数组。
当然,从本质上讲,视频就是这样,但在到达那里之前,接收和解析视频涉及到的复杂性就像潘多拉的盒子一样。
使用 FFmpeg 作为核心引擎提供了与大量格式、容器、扩展、协议、编码器、解码器、硬件加速等之间的互操作性。
为什么使用 CLI?
使用 FFmpeg 的方法之一是将其 CLI 内部的代码进行低级绑定 -- Rust 生态系统中有一些 优秀的 Crates 可以做到这一点。
低级绑定有一些缺点
- 构建、工具链和依赖关系困难、耗时,尤其是在 Windows 上
- 复杂性,特别是对于初学者来说
- 您需要从头开始手动实现许多标准转换
通过封装 CLI,这个 Crates 避免了这些缺点,并解决了一些在使用 CLI 时可能会遇到的问题
- 原始数据可以轻松地进出 FFmpeg 实例,或者在它们之间进行管道传输。在底层,它们通过 stdin 和 stdout 传输。
- 从 FFmpeg 的 stderr 日志中恢复丰富的语义信息,包括
- 进度更新(帧号、时间戳、速度、比特率等)
- 输入/输出元数据和流映射
- 警告和错误
- 参数预设和可通过Intellisense/自动完成发现的别名
唯一的缺点是FFmpeg二进制文件的大小,但压缩后不到100MB。它可以通过crate自动下载,因此您可以选择不在自己的应用程序中包含它,而是在运行时下载。
入门
1. Cargo 安装
cargo add ffmpeg-sidecar
2. 下载FFmpeg
要在您的平台(Windows、MacOS和Linux)上自动下载和安装FFmpeg二进制文件,请在任何地方调用此函数
ffmpeg_sidecar::download::auto_download().unwrap();
您只需这样做一次来设置您的开发环境,或者将其作为客户端应用程序的一个功能。
要自定义或扩展下载,请参阅
/examples/download_ffmpeg.rs
。
示例
你好世界 👋
读取原始视频帧。
use ffmpeg_sidecar::{command::FfmpegCommand, event::FfmpegEvent};
fn main() -> anyhow::Result<()> {
FfmpegCommand::new() // <- Builder API like `std::process::Command`
.testsrc() // <- Discoverable aliases for FFmpeg args
.rawvideo() // <- Convenient argument presets
.spawn()? // <- Uses an ordinary `std::process::Child`
.iter()? // <- Iterator over all log messages and video output
.for_each(|event: FfmpegEvent| {
match event {
FfmpegEvent::OutputFrame(frame) => {
println!("frame: {}x{}", frame.width, frame.height);
let _pixels: Vec<u8> = frame.data; // <- raw RGB pixels! 🎨
}
FfmpegEvent::Progress(progress) => {
eprintln!("Current speed: {}x", progress.speed); // <- parsed progress updates
}
FfmpegEvent::Log(_level, msg) => {
eprintln!("[ffmpeg] {}", msg); // <- granular log message from stderr
}
_ => {}
}
});
Ok(())
}
cargo run --example hello-world
H265转码
解码H265,修改解码的帧,然后写回H265。
来源: /examples/h265_transcode.rs
cargo run --example h265_transcode
FFplay
将FFmpeg实例通过FFplay进行调试。
来源: /examples/ffplay_preview.rs
cargo run --example ffplay_preview
其他
有关其他大量示例,请查看本存储库中 /src/test.rs 中的任何单元测试。
待办事项
- 添加
/examples
- 从stdin接收输入,并在迭代器之间进行管道传输
- 直接将数据传输到
ffplay
以进行调试 - 使用惯用错误类型而不是
Result<_, String>
- 处理不确定的输出格式,如H264/H265
- 由于这些格式需要直接消耗
stdout
,因此在使用iter()
时相互排斥
- 由于这些格式需要直接消耗
另请参阅
受Node.js fluent-ffmpeg
的启发,它在JavaScript中执行类似操作。
使用 setup-ffmpeg
进行Github Actions,并作为自动下载行为的参考。
📣 欢迎拉取请求 📣
依赖关系
~130KB