The whole piece only runs about '
+ + filmed.toFixed(1) + ' seconds filmed, but ' + bought + ' seconds are being shot. '
+ + 'No arrangement of these words fills the video — it needs more written, or a '
+ + 'shorter length.
'
+ : '')
+ + (filmed > bought + 1.5
+ ? '
The whole piece runs about '
+ + filmed.toFixed(1) + ' seconds filmed against ' + bought + ' seconds of video, so the '
+ + 'end would be cut off. Trim it, or buy more length.
'
+ : '');
+ }
+
+ b.onclick = async function () {
+ hideMsg("msg");
+ b.disabled = true; b.textContent = "Measuring…";
+ var r = await api("align_script", { email: email, project_id: pid, refresh: true });
+ if (r.ok && r.pending) {
+ var waited = 0;
+ r = await new Promise(function (done) {
+ var t = setInterval(async function () {
+ waited += 4;
+ var g = await api("align_script", { email: email, project_id: pid });
+ if (g.ok && !g.pending) { clearInterval(t); done(g); return; }
+ if (waited > 240) { clearInterval(t); done({ ok: false, error: "That is taking unusually long." }); }
+ }, 4000);
+ });
+ }
+ b.disabled = false; b.textContent = "Cut it to the clock";
+ if (!r.ok) { showMsg("msg", r.error || "Could not measure that."); return; }
+ if (r.note) { showMsg("msg", r.note); return; }
+ paint(r);
+ showMsg("msg", "Shots re-cut at real word endings.", "ok");
+ load();
+ };
+
+ api("align_script", { email: email, project_id: pid }).then(function (r) {
+ if (r && r.ok && !r.pending && r.audio) paint(r);
+ });
+}
+
+function bindPreviz() {
+ var b = document.getElementById("pzmake");
+ if (!b) return;
+ var note = document.getElementById("pznote");
+
+ async function poll() {
+ var waited = 0;
+ return await new Promise(function (done) {
+ var t = setInterval(async function () {
+ waited += 4;
+ var g = await api("make_previz", { email: email, project_id: pid });
+ if (g.ok && !g.pending) { clearInterval(t); done(g); return; }
+ if (g.ok && g.pending && note) note.textContent = g.status_text || "";
+ if (waited > 240) { clearInterval(t); done({ ok: false, error: "That is taking unusually long." }); }
+ }, 4000);
+ });
+ }
+
+ b.onclick = async function () {
+ hideMsg("msg");
+ b.disabled = true; b.textContent = "Speaking…";
+ var r = await api("make_previz", { email: email, project_id: pid });
+ if (r.ok && r.pending) { note.textContent = r.status_text || ""; r = await poll(); }
+ b.disabled = false; b.textContent = "Speak it again";
+ if (!r.ok) { note.textContent = ""; showMsg("msg", r.error || "Could not speak that."); return; }
+ note.textContent = r.status_text || "";
+ pzPaint(r.lines || []);
+ };
+
+ // Already spoken? Show it without asking again.
+ api("make_previz", { email: email, project_id: pid }).then(function (r) {
+ if (r && r.ok && !r.pending && (r.lines || []).length) {
+ b.textContent = "Speak it again";
+ note.textContent = r.status_text || "";
+ pzPaint(r.lines);
+ }
+ });
+}
+
+// The picture is the hook; the link carries the video. Never the video itself
+// over MMS - carriers transcode it into mush.
+function bindShare() {
+ var b = document.getElementById("sharebtn");
+ if (!b) return;
+ var note = document.getElementById("sharenote"),
+ out = document.getElementById("shareout");
+
+ // The file URL ends in /public with no filename. The headers are already
+ // correct (video/mp4, filename=final.mp4) so anything that reads them is
+ // fine, but clients that sniff the extension from the URL string are not.
+ // A filename query is accepted and ignored by the file service.
+ // Filled in by share_link, which owns the address. A link straight to the
+ // file would be invisible to us; this one is counted server side.
+ var SHARE_LINK = "";
+ function named(url) { return SHARE_LINK || ""; }
+
+ function paint(r) {
+ var kb = Math.round((r.bytes || 0) / 1024);
+ var link = named(r.video || "");
+ var msg = ((DATA && DATA.script && DATA.script.title)
+ ? DATA.script.title + " — " : "")
+ + ((DATA && DATA.project && DATA.project.pet_name) || "your pet")
+ + " has something to say. " + link;
+ out.innerHTML = '
'
+ + ''
+ + '
'
+ + '
' + esc(r.size || "") + ' · ' + kb + ' KB'
+ + ' · well inside the 600KB most carriers allow, so it will not be '
+ + 'downsampled.