Render the proposed cuts, with a free in-browser preview
A cut is an ordered list of shot ids, so previewing one costs nothing: the page plays that cut's clips back to back. That is what makes asking for ten proposals reasonable. Only a cut somebody chooses gets joined into a real mp4 with its own share page, which is also what makes the watch-through numbers comparable - one page per version.
This commit is contained in:
parent
800ba28387
commit
73a8f5d166
1 changed files with 53 additions and 1 deletions
54
trailer.html
54
trailer.html
|
|
@ -379,6 +379,58 @@
|
|||
+ (worst && over > 5 ? "<ul>" + worst + "</ul>" : "") + "</div>";
|
||||
}
|
||||
|
||||
// A cut is an ordering, not a render. Playing one is free, so all of them
|
||||
// can be looked at before anything is joined into a file.
|
||||
function cutsHtml(meta) {
|
||||
if (meta.writer !== RUN.lead_writer) return "";
|
||||
var shots = PKG.shots || [];
|
||||
var filmed = shots.filter(function (s) { return s.clip_url; }).length;
|
||||
var cuts = PKG.cuts || [];
|
||||
var st = String(PKG.cuts_state || "");
|
||||
var out = '<div class="cuts"><h4>Shorter cuts of this same shoot</h4>'
|
||||
+ '<p class="lede">Nothing here is re-filmed. A cut is an order to play '
|
||||
+ 'the shots in, so making another one costs nothing — which is why '
|
||||
+ 'the question is not “what is the right length” but “which '
|
||||
+ 'version do people watch to the end”.</p>';
|
||||
|
||||
if (st === "thinking") out += '<p class="busy">Working out what to drop…</p>';
|
||||
else if (/^failed/.test(st)) out += '<p class="cont">' + esc(st) + '</p>';
|
||||
|
||||
out += cuts.map(function (c) {
|
||||
var stat = STATS[c.id];
|
||||
var play = (PLAYING === c.id)
|
||||
? '<div class="playbox"><video id="cutv" controls playsinline></video>'
|
||||
+ '<div class="bar2"><span id="cutat">loading…</span>'
|
||||
+ '<button type="button" class="btn" data-stop="1">Close</button></div></div>'
|
||||
: '';
|
||||
var tools = '<button type="button" class="btn" data-play="' + esc(c.id) + '">'
|
||||
+ (PLAYING === c.id ? 'Playing' : 'Watch it · free') + '</button>';
|
||||
if (c.state === "made" && c.video_url)
|
||||
tools += '<a class="btn" href="/videos.html">Published · in My videos</a>';
|
||||
else if (c.state === "making")
|
||||
tools += '<span class="busy">joining…</span>';
|
||||
else if (filmed)
|
||||
tools += '<button type="button" class="btn primary" data-makecut="' + esc(c.id)
|
||||
+ '">Publish this version</button>';
|
||||
|
||||
return '<div class="cut"><b>' + esc(c.name || "") + '</b>'
|
||||
+ '<span class="len">' + mmss(c.seconds || 0) + ' · '
|
||||
+ (c.shot_ids || []).length + ' shots</span>'
|
||||
+ (c.strategy ? '<p class="strat">' + esc(c.strategy) + '</p>' : '')
|
||||
+ (c.why ? '<p class="why">' + esc(c.why) + '</p>' : '')
|
||||
+ (c.sacrifices ? '<p class="sac">gives up: ' + esc(c.sacrifices) + '</p>' : '')
|
||||
+ (stat ? '<p class="stat">' + stat.views + ' viewer'
|
||||
+ (stat.views === 1 ? '' : 's') + ' · median ' + stat.median_percent
|
||||
+ '% watched · ' + stat.completion_rate + '% reached the end</p>' : '')
|
||||
+ '<p class="ids">' + esc((c.shot_ids || []).join(" ")) + '</p>'
|
||||
+ '<div class="tools">' + tools + '</div>' + play + '</div>';
|
||||
}).join("");
|
||||
|
||||
if (!cuts.length && st !== "thinking")
|
||||
out += '<p class="cont">No cuts proposed yet.</p>';
|
||||
return out + '</div>';
|
||||
}
|
||||
|
||||
function reviewsHtml(meta) {
|
||||
var mine = REVIEWS.filter(function (r) {
|
||||
return r.subject === meta.writer && Number(r.iteration) === Number(meta.iteration); });
|
||||
|
|
@ -465,7 +517,7 @@
|
|||
shots.forEach(function (s) { body += shotHtml(s, voice) + insertHtml(s.id); });
|
||||
|
||||
return head + probs + '<div class="bar">' + barHtml(meta) + '</div>'
|
||||
+ spineHtml() + reviewsHtml(meta) + castHtml + body;
|
||||
+ spineHtml() + cutsHtml(meta) + reviewsHtml(meta) + castHtml + body;
|
||||
}
|
||||
|
||||
function insertHtml(after) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue