mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-14 19:27:05 -04:00
Import: image sequences with a Sequence option, ranges, folders and missing frames (#297)
Image sequences were found only by the desktop media prober: one picked numbered still brought its whole run, with no way to import just that frame, picking every frame made one sequence item per frame, the browser couldn't make sequences at all, and a gap in the numbering closed up silently. The engine now groups numbered stills itself (engine/src/sequence.rs): one picked file brings its run from its folder, several picked files of one run import as that range, a picked or dropped folder imports its files with each run as a sequence, and Force Alphabetical Order takes every image of that type in the folder by name. `file.import` takes `sequence` (default on), `alphabetical` and `frameRate`; Replace Footage, Reload, proxies and render outputs probe the same way. The media layer probes one file; the browser lists its file table for the run and registers every frame with its media pool. File > Import > File... asks, like After Effects' "PNG Sequence" checkbox, whether picked numbered stills import as a sequence, with Force Alphabetical Order and the frame rate. Sequences are named `shot_[0001-0250].png`. Interpret Footage gains Missing Frames (Show Placeholder, colour bars as in After Effects, the new default; Hold Previous Frame; Skip) and Start Frame (the frame number at the footage's first frame: trims or pads the head). Saved projects keep Skip, so their sequences play as before. Form notes keep a readable width and the form fits its rows, so OK stays in view. docs/footage.md explains importing footage and sequences. Test: tests_sequence (engine: run, picked range, every frame, Sequence off, folder, alphabetical, Interpret Footage Missing Frames / Start Frame, Replace Footage and Reload), project sequence unit tests, sequence_gaps_show_placeholders_hold_or_close_up (media), import_dialog_offers_the_image_sequence_option and dropped_frames_import_as_one_sequence_with_sequence_interpretation (UI). Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
4aaadd0ed3
commit
50c9549529
27 files changed
+1365
-238
No files matched your search
@@ -138,6 +138,15 @@ impl Services for WebServices {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
/// The table's files in `dir` (picked and dropped files sit in `/`): picking or dropping a
|
||||
/// numbered file finds the other frames of its image sequence loaded before.
|
||||
fn list_dir(&self, dir: &str) -> Vec<String> {
|
||||
let dir = dir.trim_end_matches('/');
|
||||
list().into_iter().map(|(p, _)| p).filter(|p| p.rsplit_once('/').is_some_and(|(d, _)| d == dir)).collect()
|
||||
}
|
||||
fn is_dir(&self, _path: &str) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Media import from the table (the bytes are also handed to the media pool, which decodes them).
|
||||
@@ -154,6 +163,13 @@ impl effectcraft_engine::Importer for WebImporter {
|
||||
fn register(&self, path: &str, data: &[u8]) {
|
||||
self.pool.add_bytes(path, get(path).unwrap_or_else(|| data.into()));
|
||||
}
|
||||
fn add_frames(&self, paths: &[String]) {
|
||||
for p in paths {
|
||||
if let Some(bytes) = get(p) {
|
||||
self.pool.add_bytes(p, bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Render Queue output: files land in the table and are downloaded after the render
|
||||
|
||||
Reference in new issue
Block a user