""" This file here was created from multiple parts of ffmpeg-python """ import json import subprocess try: from collections.abc import Iterable except ImportError: from collections import Iterable def convert_kwargs_to_cmd_line_args(kwargs): """Helper function to build command line arguments out of dict.""" args = [] for k in sorted(kwargs.keys()): v = kwargs[k] if isinstance(v, Iterable) and not isinstance(v, str): for value in v: args.append('-{}'.format(k)) if value is not None: args.append('{}'.format(value)) continue args.append('-{}'.format(k)) if v is not None: args.append('{}'.format(v)) return args class Error(Exception): def __init__(self, cmd, stdout, stderr): super(Error, self).__init__( '{} error (see stderr output for detail)'.format(cmd) ) self.stdout = stdout self.stderr = stderr def probe(filename, cmd='ffprobe', timeout=None, **kwargs): """Run ffprobe on the specified file and return a JSON representation of the output. Raises: :class:`ffmpeg.Error`: if ffprobe returns a non-zero exit code, an :class:`Error` is returned with a generic error message. The stderr output can be retrieved by accessing the ``stderr`` property of the exception. """ args = [cmd, '-show_format', '-show_streams', '-of', 'json'] args += convert_kwargs_to_cmd_line_args(kwargs) args += [filename] p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) communicate_kwargs = {} if timeout is not None: communicate_kwargs['timeout'] = timeout out, err = p.communicate(**communicate_kwargs) if p.returncode != 0: print( p.returncode, out, err ) raise Error('ffprobe', out, err) return json.loads(out.decode('utf-8')) __all__ = ['probe']