From 4bc5a43f87e9cd81b96ebe2f93fe2004af68dfe5 Mon Sep 17 00:00:00 2001 From: m3ultra Date: Tue, 21 Jul 2026 21:29:29 +1000 Subject: [PATCH] Console harvester: bulk-download all project videos, bypassing DL Mode's broken flyout Co-Authored-By: Claude Fable 5 --- tools/flow_console_harvest.js | 55 +++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 tools/flow_console_harvest.js diff --git a/tools/flow_console_harvest.js b/tools/flow_console_harvest.js new file mode 100644 index 0000000..58bb199 --- /dev/null +++ b/tools/flow_console_harvest.js @@ -0,0 +1,55 @@ +/* Flow console harvester — paste into DevTools Console on the project's + Videos page (labs.google/fx/tools/flow/project/ with Videos filter). + Auto-scrolls the grid to load every tile, collects every unique video + source, and downloads them sequentially as flowvid_NNN.mp4 into the + browser's Downloads folder. Grid previews are the full mp4s at ~720p, + which is the game's target resolution anyway. + Safe: read-only against Flow; no clicks on app buttons. */ +(async () => { + const sleep = (ms) => new Promise((r) => setTimeout(r, ms)); + const seen = new Set(); + + const collect = () => { + document.querySelectorAll("video").forEach((v) => { + const s = v.currentSrc || v.src || v.querySelector?.("source")?.src; + if (s) seen.add(s); + }); + }; + + // Find the scrollable container (falls back to window) + const scroller = + [...document.querySelectorAll("*")].find( + (el) => el.scrollHeight > el.clientHeight + 500 && el.clientHeight > 400 + ) || document.scrollingElement; + + console.log("%cHarvest: scrolling to load all tiles…", "color:#0f0"); + let lastCount = -1, stable = 0; + while (stable < 3) { + collect(); + scroller.scrollBy?.(0, 900) ?? window.scrollBy(0, 900); + await sleep(700); + collect(); + if (seen.size === lastCount) stable++; + else { stable = 0; lastCount = seen.size; } + } + console.log(`%cHarvest: found ${seen.size} unique videos. Downloading…`, "color:#0f0"); + + let n = 0; + for (const src of seen) { + n++; + try { + const blob = await fetch(src).then((r) => r.blob()); + const a = document.createElement("a"); + a.href = URL.createObjectURL(blob); + a.download = `flowvid_${String(n).padStart(3, "0")}.mp4`; + document.body.appendChild(a); + a.click(); + a.remove(); + console.log(`downloaded ${n}/${seen.size}`); + await sleep(1200); // gentle: don't trip the download shelf + } catch (e) { + console.warn(`miss ${n}: ${e.message}`); + } + } + console.log("%cHarvest complete. Check your Downloads folder.", "color:#0f0"); +})();