diff --git a/script.html b/script.html index a8e4e6d..c2d7c4f 100644 --- a/script.html +++ b/script.html @@ -148,6 +148,13 @@ function shotHtml(s, locked) { : '') + (locked ? '' : '') + // The subject is the writer's guess at what the line is about, so the + // picture it draws is hit and miss. Making and remaking were possible; + // throwing one away was not, which left a wrong image in the film with + // no way to take it out. + + ((locked || !s.broll_url) ? '' + : '') + ''; } @@ -191,12 +198,23 @@ function stageOf(st) { return 1; } -function stepper(stage, view) { +// How far the stepper may be CLICKED, as opposed to how far the project has +// got. Approved means the words are settled and filming is the next thing to +// do, so the Filming step has to be reachable - it is where the button lives. +// Until this existed the only way to start a film was a button at the bottom +// of the Layout page, below the shot cards and the photo uploader. +function reachOf(st) { + if (st === "approved") return 3; + return stageOf(st); +} + +function stepper(stage, view, reach) { + if (reach === undefined || reach === null) reach = stage; return '
' + STAGES.map(function (n, k) { var i = k + 1; var cls = i === view ? "on" : (i <= stage ? "done" : ""); return ''; + + (i <= reach ? '' : ' disabled') + '>' + i + ' · ' + esc(n) + ''; }).join("") + '
'; } @@ -498,15 +516,22 @@ function render(r) { + 'go straight to filming.

' + '

Hear it first

' + '
' + // "A hundredth of a cent" was wrong by three orders of magnitude. A + // measured run of an 80s script came back at 15.89 cents - the + // ElevenLabs rate is 22 dollars per 131,000 characters. + '

Filming costs real money; speaking the ' - + 'words costs about a hundredth of a cent. Run it through in your pet’s voice ' + + 'words costs a few cents. Run it through in your pet’s voice ' + 'over the opening stills first, and only film once the timing and the jokes land.

' + '' + '' + '' - + '

Cutting to the clock speaks the whole piece once, ' - + 'measures where every word actually falls, and moves the shot boundaries to real word ' - + 'endings. It rewrites how the lines are divided — not the words themselves.

' + // It no longer moves anything. Setup shots does the division, locally + // and for nothing, at the performing engine's own measured rate. This + // reads the result back so you can hear it and check the timing. + + '

This speaks the whole piece once and measures ' + + 'where every word actually falls, so you can check the timing against the shots. ' + + 'It does not move the shot boundaries — Setup shots, on the words page, does ' + + 'that in code at the engine’s own measured rate.

' + '
' + '
' + '
' @@ -520,7 +545,7 @@ function render(r) { body = head + post + film; } - out.innerHTML = cams + stepper(stage, VIEW) + body; + out.innerHTML = cams + stepper(stage, VIEW, reachOf(p.status)) + body; wire(locked); } @@ -1160,11 +1185,19 @@ function bindAlign() { + 's filmed, against ' + bought + 's of shots.

' + (r.audio ? '' : '') + (r.shots || []).map(function (s) { - var fit = Math.abs((s.filmed || 0) - each) <= 1.2; + // Under the clock is FINE. The engine finishes the line and waits - + // measured, Omni "barely stretches, it finishes early". Only an + // OVERRUN is a problem, because that is cut off mid-word. + // + // This used to flag anything more than 1.2s from the clip length in + // either direction, so a 7.0s line in a 10s shot was marked exactly + // like a genuine 11.4s overrun, and sent people rewriting lines that + // fitted perfectly well. + var over = (s.filmed || 0) > each + 0.3; return '
' + 'shot ' + s.index + ' · ' + (s.start || 0).toFixed(1) + '-' + (s.end || 0).toFixed(1) + 's spoken · ~' + (s.filmed || 0).toFixed(1) + 's filmed' - + (fit ? '' : ' off the clock') + + (over ? ' runs long' : '') + '
' + esc(s.line || "") + '
'; }).join("") + (filmed < bought - 1.5