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

View file

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

View file

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