scuffle-ffmpeg
[!WARNING]
This crate is under active development and may not be stable.
A crate designed to provide a simple interface to the native ffmpeg c-bindings.
See the changelog for a full release history.
Feature flags
channel— Enables channel support for IOtokio-channel— Enables tokio channel supportcrossbeam-channel— Enables crossbeam-channel supporttracing— Enables tracing supportlink_system_ffmpeg(enabled by default) — Links ffmpeg via systemlink_vcpkg_ffmpeg— Links ffmpeg via vcpkgdocs— Enables changelog and documentation of feature flags
Why do we need this?
This crate aims to provide a simple-safe interface to the native ffmpeg c-bindings.
Currently this crate only supports the latest versions of ffmpeg (7.x.x).
How is this different from other ffmpeg crates?
The other main ffmpeg crate is ffmpeg-next.
This crate adds a few features and has a safer API. Notably it adds the ability to provide an in-memory decode / encode buffer.
Examples
Decoding a audio/video file
// 1. Store the input of the file from the path `path`
// this can be any seekable io stream (std::io::Read + std::io::Seek)
// if you don't have seek, you can just use Input::new(std::io::Read) (no seeking support)
let mut input = seekable?;
// 2. Get the streams from the input
let streams = input.streams;
dbg!;
// 3. Find the best audio & video streams.
let best_video_stream = streams.best.expect;
let best_audio_stream = streams.best.expect;
dbg!;
dbg!;
// 4. Create a decoder for each stream
let mut video_decoder = new?
.video
.expect;
let mut audio_decoder = new?
.audio
.expect;
dbg!;
dbg!;
// 5. Get the stream index of the video and audio streams.
let video_stream_index = best_video_stream.index;
let audio_stream_index = best_audio_stream.index;
// 6. Iterate over the packets in the input.
for packet in input.packets
// 9. Send the EOF to the decoders.
video_decoder.send_eof?;
audio_decoder.send_eof?;
// 10. Receive the remaining frames from the decoders.
while let Some = video_decoder.receive_frame?
while let Some = audio_decoder.receive_frame?
Re-encoding a audio/video file
// 1. Create an input for reading. In this case we open it from a std::fs::File, however
// it can be from any seekable io stream (std::io::Read + std::io::Seek) for example a std::io::Cursor.
// It can also be a non-seekable stream in that case you can use Input::new(std::io::Read)
let input = seekable?;
// 2. Get the streams from the input.
let streams = input.streams;
// 3. Find the best audio & video streams.
let best_video_stream = streams.best.expect;
let best_audio_stream = streams.best.expect;
// 4. Create a decoder for each stream
let mut video_decoder = new?
.video
.expect;
let mut audio_decoder = new?
.audio
.expect;
// 5. Create an output for writing. In this case we use a std::io::Cursor,
// however it can be any seekable io stream (std::io::Read + std::io::Seek)
// for example a std::io::Cursor. It can also be a non-seekable stream
// in that case you can use Output::new(std::io::Read)
let mut output = seekable?;
// 6. Find encoders for the streams by name or codec
let x264 = by_name
.expect;
let aac = new
.expect;
// 7. Setup the settings for each encoder
let video_settings = builder
.width
.height
.frame_rate
.pixel_format
.build;
let audio_settings = builder
.sample_rate
.ch_layout
.sample_fmt
.build;
// 8. Initialize the encoders
let mut video_encoder = new.expect;
let mut audio_encoder = new.expect;
// 9. Write the header to the output.
output.write_header?;
loop
// 15. Send the EOF to the decoders.
video_decoder.send_eof?;
audio_decoder.send_eof?;
// 16. Receive the remaining packets from the encoders.
while let Some = video_encoder.receive_packet?
while let Some = audio_encoder.receive_packet?
// 17. Write the trailer to the output.
output.write_trailer?;
// 18. Do something with the output data (write to disk, upload to s3, etc).
let output_data = output.into_inner;
License
This project is licensed under the MIT or Apache-2.0 license. You can choose between one of them if you use this work.
SPDX-License-Identifier: MIT OR Apache-2.0