fix(cli): show output video length in render summary, not render time (#1812)

The render-complete summary printed `<fileSize> · <time> · completed`
where `<time>` was the wall-clock render duration. Presented as a bare
middle value, users read it as the video length and compared it to
ffprobe, repeatedly reporting a "wrong duration".

Show the actual output video length (from the perf summary's
compositionDurationSeconds, which equals the rendered frame span) as the
primary figure and label the render time explicitly:
`<fileSize> · <videoLength> video · rendered in <renderTime>`.

png-sequence (directory) output has no single muxed video, so it shows a
frame count instead; when neither is known the summary falls back to
render time only. Docker renders run the producer in a child process
with no perf summary threaded back, so they show render time only rather
than a misleading number.
This commit is contained in:
Miguel Ángel
2026-06-30 10:43:27 -07:00
committed by GitHub
parent 466ee08ffa
commit e7939ccd53
3 changed files with 94 additions and 5 deletions
+25
View File
@@ -14,6 +14,31 @@ export function formatDuration(ms: number): string {
return `${minutes}m ${remaining.toFixed(1)}s`;
}
/**
* Build the detail portion of the render-complete summary (everything after the
* file size). The output video length is shown as the primary figure, with the
* wall-clock render time explicitly labeled "rendered in" so the two are never
* confused (users were comparing the render time to ffprobe's media duration).
* Directory (png-sequence) output has no single muxed video, so it shows a frame
* count instead, or just the render time when neither is known.
*/
export function formatRenderSummaryDetail(input: {
elapsedMs: number;
outputDurationSeconds?: number;
isDirectory: boolean;
frameCount?: number;
}): string {
const middle = input.isDirectory
? input.frameCount != null
? `${input.frameCount} frames`
: undefined
: input.outputDurationSeconds != null && input.outputDurationSeconds > 0
? `${formatDuration(input.outputDurationSeconds * 1000)} video`
: undefined;
const renderTime = `rendered in ${formatDuration(input.elapsedMs)}`;
return [middle, renderTime].filter(Boolean).join(" · ");
}
export function label(name: string, value: string): string {
const pad = 14 - name.length;
return ` ${c.dim(name)}${" ".repeat(Math.max(1, pad))}${c.bold(value)}`;