Storyboard: one long take of several shots on Seedance (to 30 s); H3 Max Turbo in the camera list
This commit is contained in:
parent
b4543b9c13
commit
ebafaf6be1
1 changed files with 55 additions and 2 deletions
57
trailer.html
57
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 = '<div style="margin-top:8px;border-top:1px dashed var(--line,#ccc);padding-top:6px">'
|
||||
+ '<label><b>One long take</b> — this shot and the ones after it filmed as a single take of up to 30 seconds, '
|
||||
+ 'the picture cutting from person to person inside it. The long-take camera speaks the lines itself, in voices like our actors’. '
|
||||
+ 'It is kept here beside the shots’ own clips and replaces none of them.</label>'
|
||||
+ 'from shot ' + esc(s.id) + ' through shot <input type="text" data-ltto="' + esc(s.id) + '" value="' + esc(lt.to || "") + '" style="width:56px;font:inherit;font-size:12px"> on '
|
||||
+ '<select data-lteng="' + esc(s.id) + '">' + LONG_CAMERAS.map(function (k) {
|
||||
return '<option value="' + k + '"' + ((lt.engine || LONG_CAMERAS[0]) === k ? ' selected' : '') + '>' + CAMERAS[k].name + ' — $' + CAMERAS[k].rate.toFixed(2) + ' a second</option>'; }).join("") + '</select> '
|
||||
+ '<button type="button" class="btn small" data-longtake="' + esc(s.id) + '">' + (lt.clip_url ? 'Film the long take again' : 'Film the long take') + '</button>';
|
||||
if (lt.state === "filming") h += '<p class="tiny">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.</p>';
|
||||
if (lt.error) h += '<p class="tiny" style="color:#b4531f">The long take could not be made: ' + esc(lt.error) + '</p>';
|
||||
if (lt.unchanged) h += '<p class="tiny">Nothing that reaches the camera has changed since this long take was filmed, so it was not bought again.</p>';
|
||||
if (lt.clip_url) h += '<div class="frames"><figure><video src="' + esc(lt.clip_url) + '" controls preload="metadata"></video><figcaption>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 ? '<br>heard: “' + esc(lt.check.heard) + '”' : '')
|
||||
+ '</figcaption></figure></div>';
|
||||
return h + '</div>';
|
||||
}
|
||||
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 @@
|
|||
+ '</select></label>')
|
||||
+ '<label style="margin-top:6px">Which camera films this shot '
|
||||
+ '<select data-engine="' + esc(s.id) + '">'
|
||||
+ ["", "hf-seedance-2.5-480p", "hf-seedance-2.5-720p", "fal-seedance-2.5-480p", "fal-seedance-2.5-720p"].map(function (k) {
|
||||
+ ["", "h3-max-turbo", "hf-seedance-2.5-480p", "hf-seedance-2.5-720p", "fal-seedance-2.5-480p", "fal-seedance-2.5-720p"].map(function (k) {
|
||||
var c = CAMERAS[k];
|
||||
return '<option value="' + k + '"' + ((s.engine || "") === k ? ' selected' : '') + '>'
|
||||
+ (k ? 'The long-take camera: ' + c.name : 'The usual camera')
|
||||
+ (k === "h3-max-turbo" ? 'The tuned camera (H3 Max Turbo)' : k ? 'The long-take camera: ' + c.name : 'The usual camera')
|
||||
+ ' — a shot up to ' + c.max + ' seconds, about $' + c.rate.toFixed(2) + ' a second</option>'; }).join("")
|
||||
+ '</select></label>'
|
||||
+ longTakeHtml(s)
|
||||
+ '</div>';
|
||||
}
|
||||
|
||||
|
|
@ -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")) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue