1 unstable release
new 0.2.0 | Dec 22, 2024 |
---|
#227 in Video
Used in 3 crates
(2 directly)
2.5MB
467 lines
A crate for reading video frames and processing them as images, using gstreamer as a backend.
To start reading frames, you create a VideoFrameIterBuilder
with a URI to the location of the video. Then call spawn_gray
of spawn_rgb
to receive
an iterator over video frames.
Has integration with the image
crate for easy image processing (but also allows direct access to raw pixels if that's what you want)
The interface is small and minimal.
Examples
Iterate over all video frames, and print the total number of frames.
use vid_frame_iter::VideoFrameIterBuilder;
use glib::Error;
fn main() -> Result<(), glib::Error> {
//Must call this first.
vid_frame_iter::init_gstreamer();
//(If you have a file on disk you have to convert it to a URI string first)
// Create a VideoFrameIterBuilder. There are a few extra methods for
// providing options, but for now we can just provide the URI.
let builder = VideoFrameIterBuilder::from_uri(VIDEO_URI_HERE);
let mut frames = builder.spawn_rgb()?;
// Count the frames and print them!
let total_frames = frames.count();
println!("total frames: {total_frames}");
Ok(())
}
Save one from per second to disk
use vid_frame_iter::VideoFrameIterBuilder;
use vid_frame_iter::ImageFns;
use glib::Error;
fn main() -> Result<(), glib::Error> {
//Must call this first.
vid_frame_iter::init_gstreamer();
//(If you have a file on disk you have to convert it to a URI string first)
let mut builder = VideoFrameIterBuilder::from_uri(VIDEO_URI_HERE);
builder.frame_rate((1, 1));
let mut frames = builder.spawn_rgb()?;
//Gstreamer is internally discarding unwanted frames, so we just process every frame we receive.
for (idx, frame) in frames.enumerate() {
match frame {
Err(e) => return Err(e),
Ok(frame) => {
// We have to convert the frame to an [`image::ImageBuffer`] to be able to save it.
let frame_buf: image::RgbImage = frame.to_imagebuffer();
match frame_buf.save_with_format(format!("{idx}.bmp"), image::ImageFormat::Bmp) {
Ok(()) => (),
Err(_e) => () //handle image save error here
}
}
}
}
Ok(())
}
Error handling
Instead of defining its own error type this crate uses the libglib glib::Error
type. You can handle errors by switching on the matches
method
from glib::Error
.
use vid_frame_iter::VideoFrameIterBuilder;
use glib::Error;
fn main() -> Result<(), glib::Error> {
vid_frame_iter::init_gstreamer();
// A video file that doesn't exist...
match VideoFrameIterBuilder::from_uri(BAD_VIDEO_URI_HERE).spawn_rgb() {
Ok(frame_iterator) => (),//no error
Err(e) => {
// You need to write an if-elsif chain for all the errors you
// want to handle.
if e.matches(gstreamer::ResourceError::NotFound) {
println!("oh no! That file doesn't exist!");
} else {
println!("whoops! This is a different error!")
}
}
}
Ok(())
}
Supported operating systems
Currently only tested on Ubuntu Linux 22.04. This crate should work in MacOS and windows but this has not been tested.
Installing
You should follow the detailed instructions written for gstreamer-rs here.
Dependencies
~13MB
~286K SLoC