Import: missing sequence frames show a placeholder, as in After Effects (#297)

After Effects shows a missing frame of an image sequence as a
placeholder (colour bars) and has no Hold Previous Frame or Skip choice
in Interpret Footage, so EffectCraft doesn't either.

Interpret Footage loses its Missing Frames field, file.interpretFootage
its missingFrames parameter, and Footage its missing_frames setting. A
gap in a numbered sequence's numbering always shows colour bars. A
sequence imported with Force Alphabetical Order still plays its files
one after another (its numbering doesn't count), as in After Effects;
that is now an internal Footage.alphabetical flag, set on import and
kept by Reload. The Interpret Footage note lists the missing frames.

Projects saved before this have no such field and open with the After
Effects behaviour: a sequence with gaps shows placeholders where it
used to close them up.

Test: project sequence unit tests (placeholders, alphabetical order,
projects saved without the flag), tests_sequence (Start Frame instead
of Hold / Skip), sequence_gaps_show_placeholders (media) and the
Interpret Footage fields in ui_drag_drop.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
bflatastic
2026-10-09 18:52:19 +07:00
co-authored by Claude Opus 5.5
parent 50c9549529
commit efd348335f
14 changed files with 108 additions and 169 deletions
+4 -4
View File
@@ -12,7 +12,7 @@
//! picking every frame of a sequence imports it there too.
use effectcraft_project::sequence::{frame_number, missing_frame_ranges, sequence_name, split_frame_number};
use effectcraft_project::{Footage, FootageKind, MissingFrames};
use effectcraft_project::{Footage, FootageKind};
use effectcraft_time::FrameRate;
use crate::{Importer, Services};
@@ -186,8 +186,8 @@ pub fn sequences(services: &dyn Services, paths: &[String], alphabetical: bool)
}
/// Probe what a [`Source`] makes. A sequence is its first file's footage with every file, at
/// `rate`, showing gaps in its numbering as placeholders (or closing them up when
/// alphabetical).
/// `rate`, showing gaps in its numbering as placeholders, as in After Effects (in Force
/// Alphabetical Order the files play one after another).
pub fn probe(importer: &dyn Importer, src: &Source, rate: FrameRate) -> Result<Footage, String> {
let Source::Sequence { files, alphabetical } = src else { return importer.probe(src.path()) };
let mut f = importer.probe(src.path())?;
@@ -196,7 +196,7 @@ pub fn probe(importer: &dyn Importer, src: &Source, rate: FrameRate) -> Result<F
}
f.kind = FootageKind::Sequence;
f.sequence = files.clone();
f.missing_frames = if *alphabetical { MissingFrames::Skip } else { MissingFrames::Placeholder };
f.alphabetical = *alphabetical;
f.start_frame = None;
f.frame_rate = rate;
f.native_rate = None;