diff --git a/crates/interchange/src/import.rs b/crates/interchange/src/import.rs index 8a15e874e..6831103a7 100644 --- a/crates/interchange/src/import.rs +++ b/crates/interchange/src/import.rs @@ -189,10 +189,12 @@ const EDL_MEDIA_TIME_NOTE: &str = "EDL source timecodes were imported as media t /// when it links the media of an imported EDL. Returns the names of the media that stay on /// timecode though their clips use an hour or more of it (the file is missing or has none). fn rebase_to_file_timecode(project: &mut fp::Project, probe: &mut dyn FnMut(&str) -> Option) -> Vec { - let hour = filmcraft_time::Tick(3600 * filmcraft_time::TICKS_PER_SECOND); let mut on_timecode: HashSet = HashSet::new(); for it in project.items.values() { if let fp::ItemKind::Sequence(seq) = &it.kind { + // 01:00:00:00 as the list counts it: 01:00:00;00 drop-frame at 29.97 fps is 3599.996 s + let (rate, df) = (seq.settings.frame_rate, seq.settings.drop_frame); + let hour = rate.tick_of(filmcraft_time::fields_to_frames(1, 0, 0, 0, rate, df)); on_timecode.extend(seq.all_tracks().flat_map(|t| &t.items).filter(|ti| ti.source_in >= hour).map(|ti| ti.item)); } } diff --git a/crates/interchange/src/tests.rs b/crates/interchange/src/tests.rs index 6e738e86c..7fec3840b 100644 --- a/crates/interchange/src/tests.rs +++ b/crates/interchange/src/tests.rs @@ -408,6 +408,18 @@ fn edl_media_left_on_timecode_is_named() { assert_eq!(notes, ["EDL source timecodes stay media time for b.mov, c.mov: the file is missing or has no start timecode"], "{:?}", r.warnings); } +/// A drop-frame list counts its hour in timecode: a clip cut at 01:00:00;00 (3599.996 s at 29.97 +/// fps) from a missing file is still named. +#[test] +fn edl_drop_frame_media_left_on_timecode_is_named() { + let edl = "TITLE: CUT\nFCM: DROP FRAME\n\n001 C V C 01:00:00;00 01:00:01;00 01:00:00;00 01:00:01;00\n* FROM CLIP NAME: c.mov\n* SOURCE FILE: /media/c.mov\n"; + let mut p = Project::default(); + let opts = ImportOptions { name: "cut.edl".into(), edl_frame_rate: Some(29.97), ..Default::default() }; + let r = import(&mut p, edl.as_bytes(), None, &opts, &mut |_: &str| None).unwrap(); + let notes: Vec<&String> = r.warnings.iter().filter(|w| w.contains("media time")).collect(); + assert_eq!(notes, ["EDL source timecodes stay media time for c.mov: the file is missing or has no start timecode"], "{:?}", r.warnings); +} + #[test] fn rejects_unknown_documents() { let mut p = Project::default();