Initialize gstreamer only once

This commit is contained in:
Rafael Caricio 2021-03-13 18:07:45 +01:00
parent 1269cbf68e
commit 378584b626
Signed by: rafaelcaricio
GPG key ID: 3C86DBCE8E93C947
6 changed files with 41 additions and 3 deletions

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
/target
Cargo.lock
*.png

18
examples/simple.rs Normal file
View file

@ -0,0 +1,18 @@
use std::path::Path;
use std::fs::File;
use std::io::Write;
// Capture fist frame of the video file
fn main() {
let file_path = Path::new("resources/video.mp4");
let mut first_frame = File::create("first_frame.png").unwrap();
let frame_source = vid2img::FileSource::new(file_path, (1280, 534)).unwrap();
for frame in frame_source.into_iter() {
if let Ok(Some(png_img_data)) = frame {
println!("{}", png_img_data.len());
first_frame.write_all(&png_img_data).unwrap();
break;
}
}
}

BIN
resources/video.mp4 Normal file

Binary file not shown.

View file

@ -1,6 +1,8 @@
use crate::StreamError;
use crate::{FrameData, VideoStream, VideoStreamIterator};
use std::path::{Path, PathBuf};
use std::fs;
use std::io;
pub struct FileSource {
source: PathBuf,
@ -9,11 +11,12 @@ pub struct FileSource {
impl FileSource {
pub fn new(source: &Path, frame_size: (u32, u32)) -> Result<Self, CaptureError> {
let source = fs::canonicalize(source)?;
if !source.exists() {
return Err(CaptureError::FileNotFound);
}
Ok(Self {
source: source.to_path_buf(),
source,
frame_size,
})
}
@ -34,6 +37,14 @@ impl IntoIterator for FileSource {
}
}
#[derive(Debug)]
pub enum CaptureError {
IoError(io::Error),
FileNotFound,
}
impl From<io::Error> for CaptureError {
fn from(err: io::Error) -> Self {
CaptureError::IoError(err)
}
}

View file

@ -14,12 +14,11 @@
//!
//! ```no_run
//! use std::path::Path;
//! use vid2img::FileSource;
//!
//! fn main() {
//! let file_path = Path::new("video.mp4");
//!
//! let frame_source = FileSource::new(file_path, (200, 200)).unwrap();
//! let frame_source = vid2img::FileSource::new(file_path, (200, 200)).unwrap();
//! for frame in frame_source.into_iter() {
//! if let Ok(Some(png_img_data)) = frame {
//! // do something with the image data here ...

View file

@ -3,21 +3,29 @@ use gst::prelude::*;
use gstreamer as gst;
use gstreamer_app as gst_app;
use std::sync::mpsc::{sync_channel, Receiver, TryRecvError, TrySendError};
use std::sync::Once;
pub type FrameData = Vec<u8>;
static INIT_GST: Once = Once::new();
pub struct VideoStream {
pipeline_description: String,
}
impl VideoStream {
pub fn new<S: AsRef<str>>(pipeline_description: S) -> Self {
INIT_GST.call_once(|| {
log::trace!("Initializing GStreamer..");
gst::init().expect("Could not initialize GStreamer!");
});
Self {
pipeline_description: String::from(pipeline_description.as_ref()),
}
}
}
#[derive(Debug)]
pub struct GstErrorMessage {
pub src: String,
pub error: String,
@ -25,6 +33,7 @@ pub struct GstErrorMessage {
pub source: glib::Error,
}
#[derive(Debug)]
pub enum StreamError {
GstError(GstErrorMessage),
FrameCaptureError,