Skip to content

Outputs and formats

pconv promises three outputs a script can read: the plain result lines, the --json manifest, and pconv probe’s JSON. Keys in the JSON are printed in alphabetical order; read them by name.

On success pconv prints, on stdout:

  1. the output’s path;
  2. for a join, one line saying how it was made: joined N clips by stream copy, no re-encode: <why> or joined N clips by re-encoding to WxH at F fps (<profile>): <why>;
  3. with --loudness, two lines: loudness before: … and loudness after: … (<mode>, target <T> LUFS, ceiling <C> dBTP).
upload.mp4
loudness before: -31.07 LUFS, LRA 0.10 LU, true peak -19.56 dBTP
loudness after: -14.21 LUFS, LRA 0.20 LU, true peak -2.58 dBTP (linear, target -14 LUFS, ceiling -2 dBTP)

With --json, stdout is one JSON document on one line. This one is pconv talk.mp4 upload.mp4 --loudness youtube --json, pretty-printed, with the hashes and arguments shortened:

{
"device": "CPU",
"files": [
{
"args": [["…"]],
"bytes": 2259013,
"file": "upload.mp4",
"loudness": { "integrated": -14.21, "range": 0.2, "threshold": -24.21, "true_peak": -2.58 },
"sha256": "…"
}
],
"params": {
"audio": { "encoder": "aac", "kbps": 320, "layout": "stereo", "sample_rate": 48000 },
"encoder": { "codec": "h264", "encoder": "copy" },
"fps": 30.0,
"loudness": { "integrated": -14.0, "mode": "linear", "true_peak": -2.0 },
"profile": "balanced",
"quality": null,
"size": { "height": 720, "width": 1280 },
"tune": null
},
"seconds": 0.933667917,
"source": {
"loudness": { "integrated": -31.07, "range": 0.1, "threshold": -41.07, "true_peak": -19.56 },
"path": "talk.mp4",
"sha256": "…"
},
"tool": { "name": "pconv", "version": "1.0.1" }
}
Field What it holds
tool name ("pconv") and version.
source The input: path, its sha256, and its measured loudness with --loudness, else null. Absent for a join.
sources A join’s clips in order, each with path and sha256. Absent otherwise.
join A join’s method ("copy" or "encode"), reason (the sentence the plain output prints after the colon), clips (how many), and the measured loudness of the joined audio before levelling, or null. Absent otherwise.
params.profile "fast", "balanced" or "best".
params.encoder The video encoder, tagged by encoder: {"encoder":"x264","preset","crf"}, {"encoder":"h264_vaapi","qp"}, {"encoder":"vp9","cpu_used","crf"}, {"encoder":"gif","dither","tolerance"}, {"encoder":"webp","quality","compression_level"}, or {"encoder":"copy","codec"} when the video is copied.
params.quality {"crf": N} for x264 and VP9, {"qp": N} for VAAPI, {"quality": N} for WebP, null for a GIF or a copy.
params.size The output’s width and height in pixels.
params.fps The output’s frame rate, or null when the source has none pconv can read.
params.tune The x264 --tune given, or null.
params.loudness With --loudness, the target: integrated (LUFS), true_peak (dBTP) and mode ("linear" or "dynamic"); else null.
params.audio The audio, tagged by encoder: {"encoder":"aac","kbps","layout","sample_rate"}, {"encoder":"opus","kbps"}, {"encoder":"copy","codec"}, or null when the output has no audio (GIF, WebP, or a source without any).
device "CPU", or "VAAPI" / "VAAPI: <GPU name>" for --profile fast.
seconds Wall time of the whole run.
files One entry, the output: file (its path), sha256, bytes, args (each ffmpeg step’s arguments, in order), and its measured loudness with --loudness, else null.

A measured loudness has integrated (LUFS), range (LRA, LU), true_peak (dBTP) and threshold (LUFS), from ffmpeg’s EBU R128 loudnorm pass.

pconv probe <input> prints what pconv reads from a file, as one JSON line, with its keys in this order:

$ pconv probe site.mp4
{"width":1280,"height":720,"fps":30.0,"seconds":6.0,"codec":"h264","pix_fmt":"yuv420p","audio":"aac","color_space":"bt709","color_range":"tv","color_primaries":"bt709","color_transfer":"bt709","rotation":0,"sar":null,"video_index":0,"profile":"High","extradata":"CRC32:e67468b7","audio_index":1,"audio_rate":48000,"audio_channels":2,"audio_layout":"stereo","audio_extradata":"CRC32:6ddafd20"}
Field What it holds
width, height The first video stream’s size as stored, before rotation and pixel aspect are applied.
fps Its frame rate, or null.
seconds The duration, or null.
codec, profile, pix_fmt The video codec, its profile (or null) and pixel format, as ffprobe names them.
color_space, color_range, color_primaries, color_transfer The colour tags, or null when untagged. pconv’s own outputs read bt709 and tv.
rotation The display rotation in degrees, 0 to 359.
sar The sample (pixel) aspect as [num, den], or null when pixels are square.
video_index, audio_index The stream indexes pconv uses; audio_index is null without audio.
audio, audio_rate, audio_channels, audio_layout The first audio stream’s codec, sample rate, channels and layout, or null.
extradata, audio_extradata A checksum of each stream’s codec headers, which a join compares to decide whether clips can be copied.
Code Meaning
0 It worked.
1 Failed or refused once the input was read; one line on stderr starting pconv: .
2 The command line is wrong: error: …, the usage line where clap gives one, and For more information, try '--help'. on stderr.
128 plus the signal A signal stopped it; 130 for Ctrl-C on Windows.

The command line reference has every option.