mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-24 10:09:32 -06:00
This commit is contained in:
@@ -129,17 +129,22 @@ pub fn reload_items(s: &mut Session, ids: &[ItemId]) -> crate::Result<usize> {
|
||||
/// writing it) is left as it was. Returns the number reloaded and the files that couldn't be read
|
||||
/// (only without `undoable`).
|
||||
fn reload(s: &mut Session, ids: &[ItemId], undoable: bool) -> crate::Result<(usize, BTreeSet<String>)> {
|
||||
if s.importer.is_none() {
|
||||
let Some(importer) = s.importer.clone() else {
|
||||
return Err(crate::EngineError::Other("media import is not available in this build".into()));
|
||||
}
|
||||
};
|
||||
let mut updates = vec![];
|
||||
let mut paths = BTreeSet::new();
|
||||
let mut failed = BTreeSet::new();
|
||||
for i in ids {
|
||||
if let Some(ItemKind::Footage(f)) = s.project.item(*i).map(|x| &x.kind) {
|
||||
// Probed the way it imports by default, so a sequence is found as one. A path that
|
||||
// is not followed is not read.
|
||||
let probed = s.stored_paths.check(f).map_err(|(p, why)| crate::doc_path::refusal(&p, why)).and_then(|_| s.probe_footage(&f.path));
|
||||
// A sequence is probed the way it imports by default, so its run is found again; any
|
||||
// other item is its one file, not the run a numbered still sits in (#2074). A path
|
||||
// that is not followed is not read.
|
||||
let probed = s
|
||||
.stored_paths
|
||||
.check(f)
|
||||
.map_err(|(p, why)| crate::doc_path::refusal(&p, why))
|
||||
.and_then(|_| if f.kind == FootageKind::Sequence { s.probe_footage(&f.path) } else { importer.probe(&f.path) });
|
||||
let nf = match probed {
|
||||
Ok(p) => refreshed(s, f, p),
|
||||
Err(_) if undoable => Footage { missing: true, ..f.clone() },
|
||||
|
||||
@@ -8,14 +8,16 @@ use serde_json::{Value, json};
|
||||
|
||||
use crate::Session;
|
||||
|
||||
/// Probes every file as a 64×32 still (the media layer's single-file probe).
|
||||
/// Probes every file as a still 64 + its byte length wide and 32 high (the media layer's
|
||||
/// single-file probe).
|
||||
struct Stills;
|
||||
impl crate::Importer for Stills {
|
||||
fn probe(&self, path: &str) -> Result<Footage, String> {
|
||||
if !std::path::Path::new(path).is_file() {
|
||||
return Err(format!("{path}: no such file"));
|
||||
}
|
||||
Ok(Footage { path: path.into(), kind: FootageKind::Still, width: 64, height: 32, has_video: true, codec: "PNG".into(), ..Default::default() })
|
||||
let width = 64 + std::fs::metadata(path).map_or(0, |m| m.len() as u32);
|
||||
Ok(Footage { path: path.into(), kind: FootageKind::Still, width, height: 32, has_video: true, codec: "PNG".into(), ..Default::default() })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,6 +198,19 @@ fn replace_footage_and_reload_keep_sequences() {
|
||||
assert_eq!(f.duration, FrameRate::from_f64(12.0).tick_of(5));
|
||||
}
|
||||
|
||||
/// #2074: reloading a numbered still probed it as its run, so it took the first file's size.
|
||||
#[test]
|
||||
fn reloading_a_numbered_still_measures_its_own_file() {
|
||||
let dir = folder(&RUN);
|
||||
let mut s = session();
|
||||
let item = s.execute("file.import", json!({"paths": [at(&dir, "shot_0002.png")], "sequence": false})).unwrap()["items"][0].clone();
|
||||
std::fs::write(at(&dir, "shot_0002.png"), [0; 16]).unwrap();
|
||||
s.execute("file.reloadFootage", json!({"items": [item]})).unwrap();
|
||||
let (name, f) = footage(&s, &item);
|
||||
assert_eq!((name.as_str(), f.kind, f.width, f.sequence.len()), ("shot_0002.png", FootageKind::Still, 80, 0));
|
||||
assert_eq!(f.path, at(&dir, "shot_0002.png"));
|
||||
}
|
||||
|
||||
/// #756: numbered DPX and Cineon scans import as sequences, as in After Effects (`.cin` was not
|
||||
/// an image to the Media Browser, so its runs came in one file at a time).
|
||||
#[test]
|
||||
|
||||
+2
-1
@@ -148,7 +148,8 @@ including files overwritten at the same path and byte size.
|
||||
File ▸ Open tries each missing file at the same place under the project's new folder, without
|
||||
marking the project modified.
|
||||
- **File ▸ Reload Footage** (Ctrl+Alt+L) reads the files again. A sequence picks up frames
|
||||
added to its folder (a render still in progress) and keeps its interpretation.
|
||||
added to its folder (a render still in progress) and keeps its interpretation; a still is
|
||||
read as its one file, even when numbered files sit next to it.
|
||||
|
||||
**File ▸ Dependencies ▸ Relink Missing Footage…** searches a chosen folder and its subfolders
|
||||
for missing source files on the desktop. It relinks unique exact filenames whose decoded type,
|
||||
|
||||
Reference in New Issue
Block a user