Created
August 1, 2026 06:28
-
-
Save ichux/4f8e89d57d71de18166a538ce3a65636 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import json | |
| import subprocess | |
| import sys | |
| def get_metadata_ffprobe(file_path): | |
| cmd = [ | |
| "ffprobe", | |
| "-hide_banner", | |
| "-v", | |
| "error", | |
| "-print_format", | |
| "json", | |
| "-show_streams", | |
| "-show_format", | |
| file_path, | |
| ] | |
| proc = subprocess.run(cmd, capture_output=True, text=True) | |
| if proc.returncode != 0: | |
| raise RuntimeError(proc.stderr.strip() or f"ffprobe failed on {file_path}") | |
| return json.loads(proc.stdout) | |
| def format_duration(seconds): | |
| seconds = float(seconds) | |
| h, rem = divmod(seconds, 3600) | |
| m, s = divmod(rem, 60) | |
| if h: | |
| return f"{int(h)}h{int(m)}m{int(s)}s" | |
| if m: | |
| return f"{int(m)}m{int(s)}s" | |
| return f"{int(s)}s" | |
| def summarize(meta): | |
| streams = meta.get("streams", []) | |
| fmt = meta.get("format", {}) | |
| video = next((s for s in streams if s.get("codec_type") == "video"), None) | |
| audio = next((s for s in streams if s.get("codec_type") == "audio"), None) | |
| lines = [] | |
| duration = fmt.get("duration") or (video or {}).get("duration") or "?" | |
| lines.append(f"file: {fmt.get('filename', '?')}") | |
| lines.append(f"container: {fmt.get('format_name', '?')}") | |
| lines.append(f"duration: {format_duration(duration)}") | |
| if fmt.get("size"): | |
| lines.append(f"size: {int(fmt['size']) / 1024 / 1024:.1f} MiB") | |
| if fmt.get("bit_rate"): | |
| lines.append(f"bit_rate: {int(fmt['bit_rate']) / 1000:.0f} kbps") | |
| if video: | |
| lines.append("") | |
| lines.append("video:") | |
| lines.append(f" codec: {video.get('codec_name')} ({video.get('profile', '?')})") | |
| lines.append(f" size: {video.get('width')}x{video.get('height')}") | |
| lines.append(f" fps: {video.get('avg_frame_rate')}") | |
| if video.get("bit_rate"): | |
| lines.append(f" bit_rate: {int(video['bit_rate']) / 1000:.0f} kbps") | |
| if audio: | |
| lines.append("") | |
| lines.append("audio:") | |
| lines.append(f" codec: {audio.get('codec_name')} ({audio.get('profile', '?')})") | |
| lines.append(f" sample_rate: {audio.get('sample_rate')} Hz") | |
| lines.append(f" channels: {audio.get('channels')} ({audio.get('channel_layout', '?')})") | |
| if audio.get("bit_rate"): | |
| lines.append(f" bit_rate: {int(audio['bit_rate']) / 1000:.0f} kbps") | |
| if not video and not audio: | |
| lines.append("") | |
| lines.append("no video or audio streams found") | |
| return "\n".join(lines) | |
| if __name__ == "__main__": | |
| as_json = "--json" in sys.argv | |
| try: | |
| file_path = next(a for a in sys.argv[1:] if not a.startswith("-")) | |
| except StopIteration: | |
| print("usage: python3 getmeta.py [--json] file.mp4") | |
| sys.exit(1) | |
| try: | |
| meta = get_metadata_ffprobe(file_path) | |
| except (FileNotFoundError, RuntimeError) as err: | |
| print(f"error: {err}") | |
| sys.exit(1) | |
| if as_json: | |
| print(json.dumps(meta, indent=2)) | |
| else: | |
| print(summarize(meta)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment