Skip to content

Instantly share code, notes, and snippets.

@dcbark01
Created November 16, 2019 03:18
Show Gist options
  • Save dcbark01/1a695c6c301bdb144529e092c533e70a to your computer and use it in GitHub Desktop.
Save dcbark01/1a695c6c301bdb144529e092c533e70a to your computer and use it in GitHub Desktop.
Convenient class for getting video metadata
"""
@author: dcbark01
@date: Nov 2019
@license: MIT
"""
import os
import json
import shlex
import subprocess
def split_filepath(path_to_file):
base_path, filename_with_ext = os.path.split(path_to_file)
base_name, file_ext = filename_with_ext.split(".")
return (base_path, base_name, file_ext)
def get_video_metadata(filename, print_output=False):
vid_fullname = os.path.abspath(filename)
cmd_str = f"ffprobe -v error -print_format json -show_format -show_streams '{vid_fullname}'"
# print(cmd_str)
output = json.loads(subprocess.run(shlex.split(cmd_str), check=True, stdout=subprocess.PIPE).stdout)
if print_output:
pprint(output)
return output
class VidMetadata(object):
def __init__(self, input_file, stream_num=0):
self._md = get_video_metadata(input_file)
self._format = self._md["format"]
self._streams = self._md["streams"][stream_num]
# Read-only video attributes from ffprobe JSON response
self._filename = ""
self._format_name = ""
self._fps = -1
self._duration = -1.0
self._num_frames = -1
self._size = -1
self._resolution = (-1, -1)
@property
def filename(self):
return self._filename
@filename.getter
def filename(self):
return self._format["filename"]
@property
def format_name(self):
return self._format_name
@format_name.getter
def format_name(self):
return self._format["format_name"]
@property
def fps(self):
return self._fps
@fps.getter
def fps(self):
num, den = [int(i) for i in self._streams["avg_frame_rate"].split("/")]
fps = int(num / den)
return fps
@property
def duration(self):
return self._duration
@duration.getter
def duration(self):
return float(self._streams["duration"])
@property
def num_frames(self):
return self._num_frames
@num_frames.getter
def num_frames(self):
return int(self._streams["nb_frames"])
@property
def size(self):
return self._size
@size.getter
def size(self):
return int(self._format["size"])
@property
def resolution(self):
return self._resolution
@resolution.getter
def resolution(self):
""" Resolution as 2-tuple (height x width)"""
height = int(self._streams["height"])
width = int(self._streams["width"])
return (height, width)
def print_data(self):
print(f"Video Filename = {self.filename}")
print(f"Video Format = {self.format_name}")
print(f"Video FPS (frames/sec) = {self.fps}")
print(f"Video Duration (sec) = {self.duration}")
print(f"Video Total Frames = {self.num_frames}")
print(f"Video Size (MB) = {self.size}")
print(f"Video Resolution (h x w) = {self.resolution}")
def _print_raw_ffmpeg_json(self):
""" Might occasionally be useful for debugging. """
pprint(self._md)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment