diff --git a/trailer.html b/trailer.html index 801b133..b737edb 100644 --- a/trailer.html +++ b/trailer.html @@ -451,6 +451,40 @@ "fal-seedance-2.5-480p": { name: "Seedance 2.5 from fal, standard picture", rate: 0.2205, min: 4, max: 30 }, "fal-seedance-2.5-720p": { name: "Seedance 2.5 from fal, sharper picture", rate: 0.4730, min: 4, max: 30 } }; CAMERAS["minimax-h3"] = CAMERAS[""]; + CAMERAS["h3-max-turbo"] = { name: "the tuned camera (H3 Max Turbo)", rate: 0.04, min: 5, max: 15 }; + var LONG_CAMERAS = ["hf-seedance-2.5-480p", "hf-seedance-2.5-720p", "fal-seedance-2.5-480p", "fal-seedance-2.5-720p"]; + // The shots a long take would hold, and how many seconds they run together. + function longRun(fromId, toId) { + var all = (PKG.shots || []).filter(function (x) { return !x.floor; }) + .sort(function (a, b) { return String(a.id) < String(b.id) ? -1 : 1; }); + var ids = all.map(function (x) { return String(x.id); }); + var a = ids.indexOf(String(fromId)), b = ids.indexOf(String(toId)); + if (a < 0 || b <= a) return null; + var run = all.slice(a, b + 1), secs = 0; + run.forEach(function (x) { secs += Math.max(2, Math.round(Number(x.edit_seconds) || 4)); }); + return { shots: run.length, seconds: secs }; + } + function longTakeHtml(s) { + var lt = s.long_take || {}; + var h = '
' + + '' + + 'from shot ' + esc(s.id) + ' through shot on ' + + ' ' + + ''; + if (lt.state === "filming") h += '

The long take is being filmed (started ' + esc(String(lt.since || "").replace("T", " ").slice(0, 16)) + '). It takes several minutes; reload the page to see it.

'; + if (lt.error) h += '

The long take could not be made: ' + esc(lt.error) + '

'; + if (lt.unchanged) h += '

Nothing that reaches the camera has changed since this long take was filmed, so it was not bought again.

'; + if (lt.clip_url) h += '
one long take, shots ' + + esc((lt.shots || []).join(", ")) + ' · ' + Number(lt.clip_seconds || 0).toFixed(1) + 's' + + madeOn({ filmed_on: lt.engine, film_usd: lt.usd, film_wait: lt.wait }) + + ((lt.check || {}).verdict ? ' · words: ' + esc(lt.check.verdict) : '') + + ((lt.check || {}).heard ? '
heard: “' + esc(lt.check.heard) + '”' : '') + + '
'; + return h + '
'; + } function cameraOf(x) { return CAMERAS[(x && x.engine) || ""] || CAMERAS[""]; } function filmCost(x) { var c = cameraOf(x); return Math.min(c.max, Math.max(c.min, Math.ceil((Number(x.edit_seconds) || 5) + 1.5))) * c.rate; } @@ -1317,12 +1351,13 @@ + '') + '' + + longTakeHtml(s) + ''; } @@ -2356,6 +2391,24 @@ }, 700); }); + document.getElementById("pane").addEventListener("click", async function (e) { + var b = e.target.closest && e.target.closest("[data-longtake]"); + if (!b) return; + var sid = b.getAttribute("data-longtake"); + var to = ((document.querySelector('[data-ltto="' + sid + '"]') || {}).value || "").trim(); + var eng = (document.querySelector('[data-lteng="' + sid + '"]') || {}).value || LONG_CAMERAS[0]; + var run = longRun(sid, to); + if (!run) { showMsg("msg", "Give the last shot of the long take — a later shot of this script, by its number."); return; } + if (run.seconds > 30) { showMsg("msg", "Shots " + sid + " to " + to + " run " + run.seconds + " seconds together; one take holds 30. End it on an earlier shot."); return; } + var had = ((PKG.shots || []).filter(function (x) { return String(x.id) === sid; })[0] || {}).long_take || {}; + if (!confirm(run.shots + " shots as one take of " + run.seconds + " seconds on " + CAMERAS[eng].name + + ": about $" + (run.seconds * CAMERAS[eng].rate).toFixed(2) + ". Film it?")) return; + var r = await api("long_take", { draft_id: CUR, shot_id: sid, to_shot: to, engine: eng, force: !!had.clip_url && had.to === to && had.engine === eng }); + await refresh(); + if (r.ok) showMsg("msg", "The long take is being filmed: " + r.shots + " shots, " + r.seconds + " seconds, about $" + Number(r.usd).toFixed(2) + ". It takes several minutes; reload the page to see it.", "ok"); + else showMsg("msg", r.error || "The long take could not be started."); + }); + document.getElementById("pane").addEventListener("change", async function (e) { var el = e.target; if (el.getAttribute && el.getAttribute("data-pagepick")) {