fix(connector): anchor built comps on the plate's own EXR timecode
Build Shot produced comps starting at 00:00:00:00 because the panel never actually read the EXR timecode. getFootageStartFrames ranked a fragile "New Comp from Selection" probe first: it toggles the Project panel via the Window menu to get focus, and where that does not land the menu item is greyed out, executeCommand silently does nothing, and the probe returns null. A shot with no timecodeStart then fell through the API rank to zero. The worker already reads EXR headers properly in ExrHeader.cs, and its validation ranks the plate's own timeCode above the API value, which stores the editorial in-point and sits a handle-length ahead of the plate by design. Shots were therefore being built from rank 3 and validated against rank 1. That is a timecode desync waiting to reach a delivery, not just a cosmetic start frame. readExrTimecode ports the worker's reader to ExtendScript and becomes rank 1: one short header read, walking `name\0 type\0 int32 size data` for timeCode and falling back to timeCodeString where a writer omitted the packed attribute. decodePackedTimecode mirrors Timecode.FromPacked, decoding the SMPTE 12M BCD a byte at a time so the arithmetic never touches the sign bit. The menu probe is kept as rank 2 and now runs only when the plate carries no timecode at all, so the Project-panel toggle is off the normal path. setCompStartFrame was the second failure. Assigning displayStartFrame on a version of AE that does not have the property is ignored silently rather than throwing, so the early return skipped the displayStartTime fallback entirely. It now reads the value back, falls through when it did not take, and returns whether anything stuck; buildShotFromCode logs when nothing does. A start frame that cannot be set is now visible in the diagnostics report instead of a comp quietly sitting at zero. A plate whose timecode is present but zero still falls through to the API rank, keeping the existing frames > 0 convention so the safety net survives. If a genuine 00:00:00:00 plate should win outright that is a deliberate follow-up. The parser is covered against synthetic headers, including the 0x18585712 example documented in ExrHeader.cs, drop-frame, truncated and non-EXR input. What is not yet exercised in a live After Effects session is mainSource.file resolving to the sequence's first frame and displayStartFrame taking on a given AE build, so build one shot and check its start against the plate before relying on this. Picture-lock automation was reverted for a timecode desync of the same shape. PANEL_VERSION goes to 2.6.0 per the documented rule, so Pipeline → Machines does not show two workstations on one version behaving differently. The startSource comment in the manifest schema enumerated only the two older values; the queue-time provenance check keys on /\bAPI\b/ and so already reads "EXR timecode …" as trustworthy rather than suspect. The same silent-failure setCompStartFrame still exists in the farm-side vfxr_build_preview.jsx, which is fed the right value from the manifest but can drop it the same way. Left for its own change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -74,9 +74,11 @@ export const renderManifestSchema = z
|
||||
timingPlate: plateRefSchema.optional(),
|
||||
plates: z.array(plateRefSchema).optional(),
|
||||
/**
|
||||
* Verbatim from the panel's start-frame resolution: "footage metadata"
|
||||
* (trustworthy) or "API timecode …" (fallback, suspect). Known at queue
|
||||
* time, so a suspect export is flagged before it burns render hours.
|
||||
* Verbatim from the panel's start-frame resolution, in the order it
|
||||
* ranks them: "EXR timecode …" (the plate's own header, best),
|
||||
* "footage metadata" (AE's read of it, trustworthy) or
|
||||
* "API timecode …" (fallback, suspect). Known at queue time, so a
|
||||
* suspect export is flagged before it burns render hours.
|
||||
*/
|
||||
startSource: z.string().optional(),
|
||||
startFrames: z.number().int().optional(),
|
||||
|
||||
Reference in New Issue
Block a user