Skip to content
Back to skills

Cf Tools Video Metadata

ASecurity

Probe a video and display codec, duration, bitrate, fps, resolution, audio streams in a pretty table. Trigger: /cf-tools-video-metadata

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added November 11, 2026
developmentpythonrustgobash

Security analysis

A100/100

Scanned November 11, 2026

npx -y skills add pauldx/claudifying --skill cf-tools-video-metadata --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Cf Tools Video Metadata?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Cf Tools Video Metadata
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/pauldx-cf-tools-video-metadata/badge)](https://www.skillsdirectory.com/skills/pauldx-cf-tools-video-metadata)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: cf-tools-video-metadata
description: "Probe a video and display codec, duration, bitrate, fps, resolution, audio streams in a pretty table. Trigger: /cf-tools-video-metadata"
trigger: /cf-tools-video-metadata
version: 1.0.0
---

# /cf-tools-video-metadata

Run `ffprobe` against a video and produce a human-readable summary table plus an optional JSON dump for piping. The pretty output is grouped into Container, Video, Audio, Subtitles sections.

Related skills:
- `/cf-tools-video-thumbnail` — preview using probed timestamps
- `/cf-tools-video-resize` — make decisions based on resolution / bitrate
- `/cf-tools-video-compress` — see current bitrate before re-encoding

## Usage

```
/cf-tools-video-metadata input.mp4
/cf-tools-video-metadata input.mov --json
/cf-tools-video-metadata input.mkv --json > metadata.json
```

Arguments:
1. `input` (required) — video file
2. `--json` (optional) — emit raw ffprobe JSON to stdout instead of pretty table

## What You Must Do When Invoked

### Step 1 — Run ffprobe

```bash
JSON=$(ffprobe -v error -print_format json -show_format -show_streams "$INPUT")
```

If `--json` flag set, print `$JSON` and exit.

### Step 2 — Pretty-format

Use Python (always available) to extract fields:

```bash
python3 - <<PY
import json, sys
d = json.loads('''$JSON''')
fmt = d.get('format', {})
streams = d.get('streams', [])
v = next((s for s in streams if s['codec_type'] == 'video'), None)
a = [s for s in streams if s['codec_type'] == 'audio']
sub = [s for s in streams if s['codec_type'] == 'subtitle']

def hms(sec):
    sec = float(sec); h = int(sec//3600); m = int((sec%3600)//60); s = sec - h*3600 - m*60
    return f"{h:02d}:{m:02d}:{s:06.3f}"

def kbps(b):
    try: return f"{int(b)//1000} kbps"
    except: return "?"

print("=" * 60)
print(f"  {fmt.get('filename', '?')}")
print("=" * 60)
print(f"  Container   : {fmt.get('format_long_name','?')}")
print(f"  Duration    : {hms(fmt.get('duration', 0))}")
print(f"  Size        : {int(fmt.get('size', 0))/1024/1024:.2f} MB")
print(f"  Bitrate     : {kbps(fmt.get('bit_rate'))}")
print()
if v:
    fps_num, fps_den = (v.get('r_frame_rate','0/1').split('/') + ['1'])[:2]
    fps = float(fps_num)/float(fps_den or 1)
    print(f"  Video       : {v.get('codec_name','?')} ({v.get('profile','')})")
    print(f"    Resolution: {v.get('width')}x{v.get('height')}")
    print(f"    FPS       : {fps:.3f}")
    print(f"    Pixel fmt : {v.get('pix_fmt','?')}")
    print(f"    Bitrate   : {kbps(v.get('bit_rate'))}")
else:
    print("  Video       : (none)")
print()
if a:
    for i, s in enumerate(a):
        print(f"  Audio #{i}    : {s.get('codec_name','?')} {s.get('channels','?')}ch "
              f"@ {s.get('sample_rate','?')} Hz, {kbps(s.get('bit_rate'))}")
else:
    print("  Audio       : (none)")
if sub:
    for i, s in enumerate(sub):
        print(f"  Subtitle #{i}: {s.get('codec_name','?')} ({s.get('tags',{}).get('language','??')})")
print("=" * 60)
PY
```

### Step 3 — Done

No output file is produced unless `--json` is redirected.

## Output Contract

```
## Video metadata

============================================================
  /path/to/sample.mp4
============================================================
  Container   : QuickTime / MOV
  Duration    : 00:00:05.000
  Size        : 0.17 MB
  Bitrate     : 278 kbps

  Video       : h264 (Constrained Baseline)
    Resolution: 320x240
    FPS       : 25.000
    Pixel fmt : yuv420p
    Bitrate   : 270 kbps

  Audio       : (none)
============================================================
```

## Gotchas

- `r_frame_rate` is a rational like `30000/1001` for 29.97 fps. Always divide rather than parsing as integer.
- Variable-frame-rate sources report `r_frame_rate` as the max guess. For true average FPS, use `avg_frame_rate`.
- Per-stream `bit_rate` is sometimes missing (especially for MKV). The container `bit_rate` is then the only reliable number.
- ffprobe can hang on broken files; consider adding `-timeout 5000000` (microseconds) for untrusted input.
- JSON mode is the most reliable for scripting — the pretty table is human-only.

## Cross-Platform Notes

Pure ffprobe + Python 3, works on macOS, Linux, Windows. No fonts or codecs needed (probe-only). For batch use, the `--json` mode is friendliest for `jq`-style pipelines.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

View all in development →

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.