fix(film): capture resilience + scene fixes; finalize 20-clip durations

Orchestrator: bind ctx.spaNavigate to the page (fixes breadth-flash/role-perspective doing nothing) and wrap each clip in try/catch so one bad scene can't abort the run or lose the manifest. Cursor: guard page.evaluate against navigation-mid-move (fixes storm-intel 'execution context destroyed'). territory-map now leads with an existing Hot-Lead parcel (full populated detail); crane-close shows the full crane (mast+cable) then pans to the swinging card. Manifest holds real ffprobe durations for all 20 clips (film = 14m56s).
This commit is contained in:
Satyam Rastogi
2026-05-31 00:07:44 +05:30
parent f76a9da7b4
commit ba52200d08
5 changed files with 380 additions and 210 deletions
+6 -4
View File
@@ -64,8 +64,10 @@ export const CURSOR_INIT_SCRIPT = `
export function makeCursor(page) {
let pos = { x: 960, y: 540 };
const apply = async (x, y) => {
await page.evaluate(([px, py]) => window.__cursorMove?.(px, py), [x, y]);
await page.mouse.move(x, y);
// Tolerate a navigation/re-render landing mid-move: a destroyed execution context
// must never throw out of the scene (this previously aborted whole captures).
await page.evaluate(([px, py]) => window.__cursorMove?.(px, py), [x, y]).catch(() => {});
await page.mouse.move(x, y).catch(() => {});
};
return {
async moveTo(x, y, ms = 600) {
@@ -78,8 +80,8 @@ export function makeCursor(page) {
},
async click(x, y, ms = 600) {
if (x != null) await this.moveTo(x, y, ms);
await page.evaluate(([px, py]) => window.__cursorPulse?.(px, py), [pos.x, pos.y]);
await page.mouse.click(pos.x, pos.y);
await page.evaluate(([px, py]) => window.__cursorPulse?.(px, py), [pos.x, pos.y]).catch(() => {});
await page.mouse.click(pos.x, pos.y).catch(() => {});
},
async clickLocator(locator, ms = 600) {
const box = await locator.boundingBox();