Watch selected folders and reconcile bounded changes with media freshness guards
This commit is contained in:
1 parent
99748bd99f
commit
657de3de86
22 files changed
+2022
-149
No files matched your search
@@ -93,6 +93,29 @@ mod tests {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn owned_frame_scratch_validates_parent_and_cleans_batch() -> Result<()> {
|
||||
let root = tempfile::tempdir()?;
|
||||
let parent = root.path().join("owned scratch");
|
||||
let limits = MediaLimits {
|
||||
scratch_directory: Some(parent.clone()),
|
||||
..Default::default()
|
||||
};
|
||||
let batch = frame_scratch(&limits)?;
|
||||
assert_eq!(batch.path().parent(), Some(parent.as_path()));
|
||||
let batch_path = batch.path().to_owned();
|
||||
fs::write(batch.path().join("frame.png"), b"owned temporary bytes")?;
|
||||
drop(batch);
|
||||
assert!(!batch_path.exists());
|
||||
assert!(parent.is_dir());
|
||||
let relative = MediaLimits {
|
||||
scratch_directory: Some(PathBuf::from("relative")),
|
||||
..Default::default()
|
||||
};
|
||||
assert!(frame_scratch(&relative).is_err());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn identity_rejects_changes_and_oversized_input() -> Result<()> {
|
||||
let temp = tempfile::tempdir()?;
|
||||
@@ -170,10 +193,19 @@ mod tests {
|
||||
])
|
||||
.arg(&video);
|
||||
run(command, Duration::from_secs(30), 4096, 65536)?;
|
||||
let limits = MediaLimits::default();
|
||||
let scratch = temp.path().join("owned scratch");
|
||||
let limits = MediaLimits {
|
||||
scratch_directory: Some(scratch.clone()),
|
||||
..Default::default()
|
||||
};
|
||||
let probe = probe(&tools, &video, &limits)?;
|
||||
assert!(probe.has_video && probe.has_audio);
|
||||
let frames = decode_frames(&tools, &video, &probe, 2000, false, &limits)?;
|
||||
assert!(frames.directory().starts_with(&scratch));
|
||||
assert!(frames
|
||||
.frames
|
||||
.iter()
|
||||
.all(|frame| frame.path.starts_with(&scratch)));
|
||||
assert_eq!(frames.frames.len(), 1);
|
||||
assert!((1900..=2100).contains(&frames.frames[0].timestamp_ms));
|
||||
let audio = decode_audio(
|
||||
@@ -312,6 +344,10 @@ pub struct MediaLimits {
|
||||
pub audio_overlap_ms: u32,
|
||||
pub max_audio_windows: usize,
|
||||
pub command_timeout: Duration,
|
||||
/// Owned decoded-frame scratch parent. Desktop callers place this below
|
||||
/// excluded application data to avoid indexing their own temporary frames.
|
||||
/// None preserves the normal operating-system temporary directory.
|
||||
pub scratch_directory: Option<PathBuf>,
|
||||
}
|
||||
impl Default for MediaLimits {
|
||||
fn default() -> Self {
|
||||
@@ -325,6 +361,7 @@ impl Default for MediaLimits {
|
||||
audio_overlap_ms: 2000,
|
||||
max_audio_windows: 600,
|
||||
command_timeout: Duration::from_secs(45),
|
||||
scratch_directory: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -615,6 +652,23 @@ impl FrameBatch {
|
||||
self.directory.path()
|
||||
}
|
||||
}
|
||||
fn frame_scratch(limits: &MediaLimits) -> Result<tempfile::TempDir> {
|
||||
match &limits.scratch_directory {
|
||||
Some(parent) => {
|
||||
ensure!(
|
||||
parent.is_absolute(),
|
||||
"Media scratch directory must be absolute"
|
||||
);
|
||||
fs::create_dir_all(parent).context("Create owned media scratch directory")?;
|
||||
tempfile::Builder::new()
|
||||
.prefix("searchi-frames-")
|
||||
.tempdir_in(parent)
|
||||
.context("Create owned frame batch")
|
||||
}
|
||||
None => tempfile::tempdir().context("Create frame batch"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn decode_frames(
|
||||
tools: &FfmpegTools,
|
||||
path: &Path,
|
||||
@@ -623,7 +677,7 @@ pub fn decode_frames(
|
||||
include_scene: bool,
|
||||
limits: &MediaLimits,
|
||||
) -> Result<FrameBatch> {
|
||||
let directory = tempfile::tempdir()?;
|
||||
let directory = frame_scratch(limits)?;
|
||||
let mut command = Command::new(&tools.ffmpeg);
|
||||
command.args(["-protocol_whitelist", "file,pipe"]);
|
||||
command.args(["-nostdin","-hide_banner","-loglevel","info","-threads","1","-hwaccel","none","-copyts","-ss"])
|
||||
|
||||
Reference in new issue
Block a user