Merge pull request #48 from punkhop/fix/sequence-inspect-readback
engine: sequence.inspect reports clip ends, gain and marker comments
This commit is contained in:
commit
7377def476
|
|
@ -2721,6 +2721,7 @@ pub fn inspect_sequence(s: &Session, id: ItemId, q: &filmcraft_project::Sequence
|
|||
"items": t.items.iter().map(|i| json!({
|
||||
"clip": i.id.0, "item": i.item.0, "name": i.name, "start": i.start.0, "duration": i.duration.0,
|
||||
"startFrame": rate.frame_at(i.start), "durationFrames": rate.frame_at(i.duration), "sourceIn": i.source_in.0, "speed": i.speed,
|
||||
"end": i.end().0, "endFrame": rate.frame_at(i.end()), "sourceOut": i.source_out().0, "gainDb": i.gain_db,
|
||||
"enabled": i.enabled, "link": i.link, "label": i.label.name(),
|
||||
"effects": i.effects.iter().map(|e| json!({"effect": e.effect, "enabled": e.enabled, "masks": e.masks.len(), "params": e.params.iter().map(|(k, p)| (k.clone(), json!({"value": format!("{:?}", p.value), "keyframes": p.keyframes.len()}))).collect::<serde_json::Map<_, _>>()})).collect::<Vec<_>>(),
|
||||
})).collect::<Vec<_>>(),
|
||||
|
|
@ -2737,7 +2738,7 @@ pub fn inspect_sequence(s: &Session, id: ItemId, q: &filmcraft_project::Sequence
|
|||
"in": q.mark_in.map(|t| t.0),
|
||||
"out": q.mark_out.map(|t| t.0),
|
||||
"split": q.split,
|
||||
"markers": q.markers.iter().map(|m| json!({"id": m.id.0, "start": m.start.0, "duration": m.duration.0, "kind": format!("{:?}", m.kind), "name": m.name, "color": m.color.name()})).collect::<Vec<_>>(),
|
||||
"markers": q.markers.iter().map(|m| json!({"id": m.id.0, "start": m.start.0, "duration": m.duration.0, "kind": format!("{:?}", m.kind), "name": m.name, "comment": m.comment, "color": m.color.name()})).collect::<Vec<_>>(),
|
||||
"video": q.video_tracks.iter().map(tr).collect::<Vec<_>>(),
|
||||
"audio": q.audio_tracks.iter().map(tr).collect::<Vec<_>>(),
|
||||
"selection": s.state.selection.iter().map(|c| c.0).collect::<Vec<_>>(),
|
||||
|
|
|
|||
|
|
@ -918,6 +918,8 @@ mod remix_tests;
|
|||
#[cfg(test)]
|
||||
mod scopes_tests;
|
||||
#[cfg(test)]
|
||||
mod sequence_inspect_tests;
|
||||
#[cfg(test)]
|
||||
mod sequence_tools_tests;
|
||||
#[cfg(test)]
|
||||
mod settings_tests;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
//! `sequence.inspect` is how an agent checks its edits: it has to show where a clip ends in the
|
||||
//! sequence and in its media, the clip's audio gain and what a marker says.
|
||||
|
||||
use serde_json::json;
|
||||
|
||||
use crate::Session;
|
||||
|
||||
#[test]
|
||||
fn sequence_inspect_reports_clip_ends_gain_and_marker_comments() {
|
||||
let mut s = Session::default();
|
||||
s.execute("file.openDemoProject", json!({})).unwrap();
|
||||
let rate = s.sequence_rate();
|
||||
// a clip at 200 %, a clip with gain and a marker with a comment, all made through commands
|
||||
s.execute("sequence.linkedSelection", json!({"on": false})).unwrap();
|
||||
let (fast, loud) = {
|
||||
let q = s.active_sequence().unwrap();
|
||||
(q.video_tracks[0].items.last().unwrap().id, q.audio_tracks[0].items[0].id)
|
||||
};
|
||||
s.execute("timeline.select", json!({"clips": [fast.0]})).unwrap();
|
||||
s.execute("clip.speedDuration", json!({"speed": 200})).unwrap();
|
||||
s.execute("timeline.select", json!({"clips": [loud.0]})).unwrap();
|
||||
s.execute("clip.audioGain", json!({"mode": "set", "db": -6.5})).unwrap();
|
||||
let marker = s.execute("markers.add", json!({"time": rate.tick_of(12).0, "name": "Beat", "comment": "cut on the downbeat"})).unwrap()["marker"].clone();
|
||||
|
||||
let q = s.active_sequence().unwrap().clone();
|
||||
let js = s.execute("sequence.inspect", json!({})).unwrap();
|
||||
let m = js["markers"].as_array().unwrap().iter().find(|m| m["id"] == marker).unwrap();
|
||||
assert_eq!((m["name"].as_str(), m["comment"].as_str()), (Some("Beat"), Some("cut on the downbeat")));
|
||||
let mut seen = 0;
|
||||
for (key, tracks) in [("video", &q.video_tracks), ("audio", &q.audio_tracks)] {
|
||||
for (ti, t) in tracks.iter().enumerate() {
|
||||
for (ci, c) in t.items.iter().enumerate() {
|
||||
let j = &js[key][ti]["items"][ci];
|
||||
assert_eq!(j["clip"], c.id.0);
|
||||
assert_eq!(j["end"], c.end().0, "{j}");
|
||||
assert_eq!(j["end"].as_i64(), j["start"].as_i64().zip(j["duration"].as_i64()).map(|(a, b)| a + b));
|
||||
assert_eq!(j["endFrame"], rate.frame_at(c.end()));
|
||||
assert_eq!(j["sourceOut"], c.source_out().0, "{j}");
|
||||
assert_eq!(j["gainDb"], c.gain_db);
|
||||
// the keys that were there before stay
|
||||
for old in ["item", "name", "start", "duration", "startFrame", "durationFrames", "sourceIn", "speed", "enabled", "link", "label", "effects"] {
|
||||
assert!(j.get(old).is_some(), "{old} is still reported");
|
||||
}
|
||||
if c.id == fast {
|
||||
assert_eq!(j["speed"], 2.0);
|
||||
assert_eq!(
|
||||
j["sourceOut"].as_i64().unwrap() - j["sourceIn"].as_i64().unwrap(),
|
||||
2 * j["duration"].as_i64().unwrap(),
|
||||
"at 200% a clip uses twice its length of media"
|
||||
);
|
||||
seen += 1;
|
||||
}
|
||||
if c.id == loud {
|
||||
assert_eq!(j["gainDb"], -6.5);
|
||||
seen += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
assert_eq!(seen, 2, "both edited clips were found in the readback");
|
||||
}
|
||||
|
|
@ -43,7 +43,7 @@ claude mcp add filmcraft-headless -- /abs/path/filmcraft/target/release/filmcraf
|
|||
| `doc_inspect` | both | the project tree and the active sequence in one call (`project_inspect` + `sequence_inspect`) |
|
||||
| `render_preview` | both | same as `render_frame` |
|
||||
| `project_inspect` | both | bins and items with ids, types, durations; active sequence |
|
||||
| `sequence_inspect` | both | the active sequence: tracks, clips (ticks and frames), effects, transitions, markers, playhead, selection |
|
||||
| `sequence_inspect` | both | the active sequence: tracks, clips (`start` / `end` and `sourceIn` / `sourceOut` in ticks, frames, `speed`, `gainDb`), effects, transitions, markers (name and `comment`), playhead, selection |
|
||||
| `media_import` | both | import files by absolute path (`text`, one path per line) |
|
||||
| `render_frame` | both | PNG of the program frame at `seconds` (headless renders; bridge screenshots the Program monitor) |
|
||||
| `ui_inspect` | bridge | UI state: tool, workspace, panels, zoom, playback, fps |
|
||||
|
|
|
|||
Loading…
Reference in New Issue