2021-03-13 15:15:28 +00:00
|
|
|
use crate::StreamError;
|
|
|
|
use crate::{FrameData, VideoStream, VideoStreamIterator};
|
|
|
|
use std::path::{Path, PathBuf};
|
2021-03-13 17:07:45 +00:00
|
|
|
use std::fs;
|
|
|
|
use std::io;
|
2021-03-13 17:14:12 +00:00
|
|
|
use std::io::ErrorKind;
|
2021-03-13 15:15:28 +00:00
|
|
|
|
|
|
|
pub struct FileSource {
|
|
|
|
source: PathBuf,
|
|
|
|
frame_size: (u32, u32),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl FileSource {
|
|
|
|
pub fn new(source: &Path, frame_size: (u32, u32)) -> Result<Self, CaptureError> {
|
2021-03-13 17:07:45 +00:00
|
|
|
let source = fs::canonicalize(source)?;
|
2021-03-13 15:15:28 +00:00
|
|
|
if !source.exists() {
|
2021-03-13 17:14:12 +00:00
|
|
|
return Err(CaptureError::IoError(io::Error::new(ErrorKind::NotFound, "File not found")));
|
2021-03-13 15:15:28 +00:00
|
|
|
}
|
|
|
|
Ok(Self {
|
2021-03-13 17:07:45 +00:00
|
|
|
source,
|
2021-03-13 15:15:28 +00:00
|
|
|
frame_size,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl IntoIterator for FileSource {
|
|
|
|
type Item = Result<Option<FrameData>, StreamError>;
|
|
|
|
type IntoIter = VideoStreamIterator;
|
|
|
|
|
|
|
|
fn into_iter(self) -> Self::IntoIter {
|
|
|
|
let pipeline_description = format!(
|
|
|
|
"uridecodebin uri=file://{} ! videoconvert ! videoscale ! capsfilter caps=\"video/x-raw, width={}, height={}\"",
|
|
|
|
self.source.to_string_lossy(),
|
|
|
|
self.frame_size.0,
|
|
|
|
self.frame_size.1
|
|
|
|
);
|
|
|
|
VideoStream::new(pipeline_description).into_iter()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-20 21:45:10 +00:00
|
|
|
#[derive(Debug, thiserror::Error)]
|
2021-03-13 15:15:28 +00:00
|
|
|
pub enum CaptureError {
|
2022-04-20 21:45:10 +00:00
|
|
|
#[error("IO error: {0}")]
|
|
|
|
IoError(#[from] io::Error),
|
2021-03-13 17:07:45 +00:00
|
|
|
}
|