add: queue total ETA from current encode speed
The queue card now shows an estimated time to clear: current job remaining + sum(pending source durations) / current speed. Durations come from a path+mtime-keyed cache that probes each file once in the background (ffprobe format=duration, header-only), so the 1s poll never re-probes; entries are pruned to the live queue. No speed (idle/held) -> no estimate; files still being probed mark it partial (shown as '~Xh+'). Closes #9
This commit is contained in:
@@ -97,6 +97,7 @@
|
||||
.qsum { display:flex; align-items:baseline; gap:.5rem; flex-wrap:wrap; margin-bottom:.8rem; }
|
||||
.qsum .qn { font-family:var(--mono); font-size:1.4rem; color:var(--amber); line-height:1; }
|
||||
.qsum .ql { color:var(--muted); font-size:.85rem; }
|
||||
.qsum .qeta { font-family:var(--mono); font-size:.8rem; color:var(--amber-soft); margin-left:auto; }
|
||||
ul.list { list-style:none; margin:0; padding:0; font-family:var(--mono); font-size:.82rem; }
|
||||
ul.list li { padding:.35rem 0; border-bottom:1px solid var(--line); color:var(--muted); word-break:break-word; }
|
||||
ul.list li:last-child { border-bottom:0; }
|
||||
@@ -325,7 +326,8 @@
|
||||
for (const s of arr) { while (!s.startsWith(p)) p = p.slice(0, -1); if (!p) break; }
|
||||
return p;
|
||||
}
|
||||
function renderQueue(queue, current) {
|
||||
function renderQueue(d) {
|
||||
const queue = d.queue, current = d.current;
|
||||
const cur = base(current && current.file);
|
||||
const pending = (queue || []).filter(f => f !== cur);
|
||||
const el = $("queue");
|
||||
@@ -334,7 +336,10 @@
|
||||
return;
|
||||
}
|
||||
const pre = pending.length > 1 ? commonPrefix(pending) : "";
|
||||
const head = `<div class="qsum"><span class="qn">${pending.length}</span><span class="ql">${pending.length === 1 ? "file" : "files"} waiting</span></div>`;
|
||||
const eta = d.queue_eta_sec > 0
|
||||
? `<span class="qeta">~${fmtDurLong(d.queue_eta_sec)}${d.queue_eta_partial ? "+" : ""} to clear</span>`
|
||||
: "";
|
||||
const head = `<div class="qsum"><span class="qn">${pending.length}</span><span class="ql">${pending.length === 1 ? "file" : "files"} waiting</span>${eta}</div>`;
|
||||
const rows = pending.slice(0, 3).map(f => {
|
||||
const tail = pre ? f.slice(pre.length) : f;
|
||||
return `<li>${pre ? `<span class="pre">${esc(pre)}</span>` : ""}<span class="key">${esc(tail)}</span></li>`;
|
||||
@@ -429,7 +434,7 @@
|
||||
renderControls(d);
|
||||
renderJob(d.current);
|
||||
renderFailed(d.failed);
|
||||
renderQueue(d.queue, d.current);
|
||||
renderQueue(d);
|
||||
renderEvents(d.recent);
|
||||
const active = d.current && d.current.file && d.current.phase !== "idle";
|
||||
setLive(d.current && d.current.paused ? "idle" : active ? "ok" : "idle");
|
||||
|
||||
Reference in New Issue
Block a user