Skip to main content
You write the command and Rendobar runs ffprobe as written, the same model as FFmpeg. A bare media URL is a valid command: the defaults get filled in and you get a normalized summary next to the raw format, streams, and chapters.
Live. Accepts video, audio, and image URLs.
From a shell? Use the CLI: rb ffprobe https://example.com/video.mp4. Local files upload automatically.

Probe a file

A probe is a data job. The answer lands in output.data, and output.file is null because nothing is written. Most probes finish in a few seconds. The SDK’s jobs.wait polls for you; over raw HTTP, poll GET /jobs/{id} or subscribe with webhooks.

What comes back

Your flags are honored. Rendobar fills in only what you left out: So a bare URL returns summary, format, streams, and chapters. Name one -show_* yourself and it replaces the whole trio, so -show_frames -read_intervals %+#5 comes back with frames and no summary. Pick a writer other than JSON and nothing is parsed at all: ffprobe’s text lands in output.data.stdout. Four things are rejected with VALIDATION_ERROR before the job is created: -protocol_whitelist, -protocol_blacklist, shell control characters (>, |, ;), and -o/-output_file. Output always comes back to you and is never written to a file. Rendobar reads the URL directly, so a faststart MP4 transfers only its header and a file over your plan’s input limit still probes. When a server refuses range requests, the runner downloads the file first and the input limit applies.

The summary

summary normalizes what’s awkward to read raw: rotation buried in side data, fractional frame rates, HDR spread across three color fields, cover art masquerading as video. Here is the sample file above, probed:
Switch on kind first. It tells you which block to read: Three things it gets right that raw ffprobe doesn’t. video.rotation is 0, 90, 180, or 270, read from the display matrix, while width and height stay as stored, so a portrait phone clip reads 1920×1080 with rotation: 90. An MP3 with embedded art reads kind: "audio", because the attached_pic stream is excluded from both streamCounts.video and summary.video. And video.isHdr collapses PQ, HLG, and BT.2020 primaries into one boolean, with the exact color fields left in the raw stream. Fields are null, never absent, when a value doesn’t apply or ffprobe couldn’t read it. sizeBytes is null when a remote server doesn’t report length, and tags is {} when the container carries none.
Every summary field name is stable. Write your checks against summary.kind and summary.video.width directly.

Parameters

string
required
A raw ffprobe command, run as written. Minimal form is the media URL on its own. The ffprobe prefix is optional.
integer
default:"plan maximum"
Max execution time in seconds. Plan caps apply, same as FFmpeg. A probe rarely approaches it.

Reading the result

On a JSON run, output.data carries summary plus every section ffprobe emitted, under ffprobe’s own field names:
Pick a non-JSON writer and you get ffprobe’s text verbatim instead, with nothing parsed and no summary:
warnings appears only when there’s something to say. Each entry is { code, message }, and you branch on code.

Errors

Two things are caught before a job exists, so nothing is billed: a malformed command (no URL, a blocked flag, a shell redirect) returns VALIDATION_ERROR, and a URL that resolves somewhere Rendobar won’t fetch from, such as a private address, returns INPUT_URL_BLOCKED. Both are 400s on POST /jobs. A probe that fails after it starts carries error with code, message, detail, and retryable.
Read error.retryable rather than mapping codes yourself. A file that probes but looks truncated succeeds with a DURATION_UNKNOWN warning instead of failing, so treat a video with durationSec: null as suspect.

See also

  • Job output: the output shape every job returns
  • FFmpeg: run a command against the file you probed
  • Webhooks: receive job.completed instead of polling
  • Error codes: the full error catalogue