본문으로 건너뛰기
cccskills
무료GitHub에 공개

ffprobe-cli

Read a media file's real structure with ffprobe through media_run - the JSON invocation and how to read it, what every family of field means, how to count frames, sample without decoding everything, detect HDR and interlacing, and diagnose a missing duration, a stream with no frames or a container that lies. Covers when media_probe's own report is already enough.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(2)

  • SKILL.md11.3 KB
  • reference/fields.md16.2 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Reading media with ffprobe

ffprobe answers questions about a file's header and its packets without decoding it. That makes it cheap and safe on a damaged or huge file, and it makes its answers statements about what the container claims: it will report a stream with zero frames, a duration of N/A, and a frame rate the file does not actually deliver, because those are the facts it has.

Run it through media_run with binary: "ffprobe". args is an array, and ffprobe gets none of the flags ffmpeg gets - no -n, no -nostdin, no -hide_banner. The wrapper still applies the timeout (120 s default, 600 s maximum), the output cap, and the cwd (the conversation workspace unless you name one).

The invocation worth memorising

{ "binary": "ffprobe",
  "args": ["-v","error","-print_format","json","-show_format","-show_streams","-show_chapters","-show_error","clip.mp4"] }

-v error keeps the answer JSON rather than JSON behind a warning; -print_format json (-of json is the same option) gives one parseable object instead of one key=value line per field; and each -show_* adds a section - format the container, streams every stream, chapters the chapters, error a structured error when there is one.

This is exactly what media_probe runs, which is the first thing to know: if a report is enough, do not run ffprobe at all. Reach for a raw call for a field the report does not print, or a section it does not read (packets, frames, programs, -count_frames).

Pulling one value out

{ "binary": "ffprobe", "args": ["-v","error","-select_streams","v:0",
  "-show_entries","stream=width,height,r_frame_rate","-of","default=nw=1","clip.mp4"] }
width=640
height=480
r_frame_rate=30/1
  • -select_streams v:0 reads only the first video stream; a = audio, s = subtitle, 0 = stream index 0.
  • -show_entries takes section=field,field pairs: stream=codec_name,profile, format=duration,bit_rate, stream_tags=language to reach a nested object.
  • -of default=nw=1 sets the default writer with noprint_wrappers (no section header); nokey=1 drops the key= half and leaves the value. They are independent, and nokey alone still prints [STREAM]/[/STREAM] wrappers - use nw=1:nk=1 for bare values, -of csv=p=0 for one per line, or -of compact=p=0:nk=1 for one space-free key=value line per stream.
  • Beware a section that prints events: asking for side_data=rotation with no -select_streams and no other restriction can bring back packets_and_frames too.

What the fields mean

Container. format_name is ffprobe's family list: mov,mp4,m4a,3gp,3g2,mj2 is the ISO-BMFF family, matroska,webm is MKV or WebM - which ffprobe cannot tell apart, so the extension is the tie-break, and that is why media_probe uses it. format_long_name is the human name. duration and bit_rate are the container's own claims, and start_time is its timeline origin - the number that explains a negative first-packet timestamp. probe_score (0-100) is ffprobe's confidence, and a high score on the wrong format is how a misnamed file gets accepted.

Video streams. codec_name (h264, hevc, vp9, mpeg4, png) is what to compare against a browser's decoders, with profile/level beside it. width and height are the coded pixels a decoder produces, which a rotation flag does not change. sample_aspect_ratio is the pixel shape (1:1 square, 32:27 anamorphic on 720x480) and display_aspect_ratio the shape a player shows (4:3 on 640x480, 16:9 on that anamorphic pair) - the pixels do not change, the DAR does, so a resize has to decide whether it means "look like the DAR". pix_fmt is yuv420p (universal), yuv420p10le (10-bit), yuv444p (many browsers draw black) or rgb24 (a PNG). r_frame_rate and avg_frame_rate are exact rationals - 30000/1001 is 29.97, 30/1 is exactly 30 - and r_frame_rate can be wrong on a raw elementary stream (a 30 fps H.264 dump read back as 60/1 on this host). field_order is progressive or tt/bb when interlaced. nb_frames is often absent, and N/A means "the header does not say", not "zero".

Audio streams. sample_rate (48000; a string in some builds and a number in others - read it as text), channels and channel_layout (2 / stereo, 1 / mono, 6 / 5.1 - the layout is what an encoder needs, channels alone is not enough), sample_fmt (fltp for AAC, s16 for PCM), bits_per_raw_sample (often absent; for PCM the depth is in codec_name, such as pcm_s16le).

Dispositions, tags, rotation. disposition is an object of 0/1 flags: default (what a player picks when nothing chooses), forced (show this subtitle even with subtitles off), comment, hearing_impaired, attached_pic (an embedded cover image, which is technically a video stream) and more. tags.language (eng, spa, und), tags.title, tags.handler_name. A hand-made MKV often has no language at all, which is not an error - it is a file that does not say. Rotation lives in side_data_list[].rotation, in degrees counter-clockwise (an iPhone's -90 is a clockwise 90° display rotation), and it is metadata, not pixels, so -c copy preserves it. Read it with -select_streams v:0 -show_entries "stream=width,height:side_data=rotation", which answers width=640, height=480, rotation=90.

Reading deeper when it matters

-count_frames decodes every frame, so on a two-hour file it is minutes of work - and the call has a timeout. On the 3-second fixture it returned nb_read_frames=90. -show_packets and -show_frames without a -read_intervals window print the whole file's packets, which is the one way to turn a small probing call enormous - always bound it:

["-v","error","-select_streams","v:0","-count_frames","-show_entries","stream=nb_read_frames","-of","default=nw=1","clip.mp4"]

%+#3 is "from the start, three items", %+3 a three-second window, 1:00%+10 a window starting at 1:00. flags=K__ on a packet means a keyframe. -read_intervals bounds packets; -skip_frame nokey is the option that makes a -show_frames walk decode keyframes only, and it does not filter a packet listing. HDR is color_transfer=smpte2084 (PQ, HDR10) or arib-std-b67 (HLG), with color_primaries=bt2020 and color_space=bt2020nc beside it; interlacing is anything but field_order=progressive; variable frame rate is avg_frame_rate differing from r_frame_rate. None of those colour fields appear in media_probe's report, which gives hevc (Main 10) · yuv420p10le (10-bit) and a transcode verdict instead.

reference/fields.md beside this file has the whole catalogue: every -show_* section with what it reads and what it costs, the container/codec/audio/subtitle/ attachment/side-data families in full, the working invocations with their measured output, and the long-form diagnosis. It also carries the three measurements a container does not give you - a bitrate from the packets, a frame count, and the proof that a file is really variable-rate - the transport-stream program/PID layer (-show_programs, which an MP4 simply does not have), and -show_data, which hexdumps the bytes behind a section so a stream's real configuration record can be read instead of assumed.

Diagnosing from the output alone

The five diagnoses worth knowing by heart:

  • duration=N/A with streams present means the container carries no duration
    • a raw .h264, a growing capture, a pipe - and media_probe says unknown on the same facts. Measure with -count_frames or -show_packets.
  • A stream with no frames at all is an empty track: a remux that dropped its packets, or a header written before the data. There is nothing to decode.
  • format_name=h264 with a nonsense r_frame_rate is a raw elementary stream: no container, no timestamps, no duration. Remux into MP4 before believing any timing.
  • An image reported as a one-frame video is a PNG/GIF/WebP - a video stream with no duration, which is exactly why media_probe gives it the image verdict instead of calling a PNG undecodable.
  • Only an audio stream, no video is an audio file: -select_streams v:0 returns nothing rather than an error, and the same is true in reverse.

reference/fields.md carries the rest of the table - a container that says one thing and holds another, a low probe_score, unreadable streams, and what an exit code of 1 with no output means.

media_probe first, ffprobe second

media_probe runs exactly the invocation at the top of this file and then translates the JSON: container, duration, bitrate, one line per stream with the dimensions, the exact rational frame rate and its decimal reading (30 fps (exact 30/1)), sample rate, channel layout, bit depth, rotation, language, title, disposition flags, and the chapters with their timestamps. It adds the one thing ffprobe cannot: a verdict on whether a Chrome/Firefox-class browser can play the file as it is - playable, image, remux or transcode - with the exact ffmpeg command that would fix a remux/transcode.

Use it first, always: it is cheap, it reads the header only, and it cannot fail on a damaged tail. Then:

  • If a field you need is missing from the report, call media_probe with raw: true - it appends ffprobe's own JSON under the report, one call instead of two.
  • Use a media_run ffprobe call for packets, frames, -count_frames, -read_intervals, -show_programs, and the colour/interlace fields, because those are not sections the report reads.
  • The report's browser verdict is an opinion about browser decoders. It says transcode for HEVC and nothing whatever about whether this host's ffmpeg can encode or decode HEVC - it very likely can. Do not read a browser verdict as a statement about ffmpeg, and do not read ffprobe's ability to read a codec as evidence a browser can play it. Nor does it know whether a technically playable file is watchable on the user's connection: a 40 Mb/s MP4 is decodable and still unwatchable.
  • A file media_probe cannot identify is a file ffprobe found no container in. Do not retry it with a longer timeout: re-check the path, and consider that a truncated download or a text file with a .mp4 name looks exactly like this.
  • When the question changes from reading to changing, this is the wrong skill. ffprobe never writes a byte: the moment the answer is a different container, a smaller file or a frame on disk, the work belongs to the ffmpeg-cli skill - whose own reference/failures.md (in that skill's folder, not this one) is also where to look when an action taken on a probe's answer fails.

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Author an editorial HTML+SVG diagram with the Diagram Design kit - choose the visual type, read its reference, start from an example, and satisfy the safety and accessibility contract that diagram_write({kind:"html"}) enforces.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

vecnode/vn-code92026년 10월 19일 업데이트

Drive ffmpeg through the media_run tool as an argv array - remux instead of re-encode, map streams explicitly, trim at keyframes, scale and crop, extract audio and frames, and build GIFs, contact sheets and concatenations. Covers the flags this pack injects, reading a failure from its exit code and last log lines, and the version-dependent spellings to hedge.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

vecnode/vn-code92026년 10월 19일 업데이트

Use when the user wants to design, redesign, shape, critique, audit, polish, simplify, harden, animate, or otherwise improve a frontend interface: websites, landing pages, dashboards, product UI, components, forms, settings, onboarding, empty states, and native iOS or Android screens. Handles UX review, hierarchy, layout, typography, color, motion, UX copy, accessibility, responsive behavior, edge cases, and capturing or documenting design systems (DESIGN.md, tokens). Also for making bland UI bolder, loud UI quieter, or ambitious visual effects. Not for backend-only or non-UI tasks.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

vecnode/vn-code92026년 10월 19일 업데이트

Author Mermaid diagrams that parse the first time: choose the right diagram type for the question, write syntax the parser accepts, and keep the picture readable in a narrow panel. A bundled reference covers complex, large diagrams.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

vecnode/vn-code92026년 10월 19일 업데이트

Write openFrameworks prototypes into the lab — real C++ (ofApp.h, ofApp.cpp, main.cpp) that builds into an app with the projectGenerator and make. Use for native/desktop sketches, performance-sensitive work, OpenGL, audio input, sensors, anything that has to be an application rather than a page.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

vecnode/vn-code92026년 10월 19일 업데이트

Write p5.js prototypes into the lab — sketches that actually run in a browser, seed-reproducible, with controls generated from the sketch's own parameters. Use for generative art, flow fields, particle systems, noise, animation, anything sketched visually in the browser.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

vecnode/vn-code92026년 10월 19일 업데이트

vecnode의 스킬 모두 보기

이 스킬의 문제 신고