61 lines
1.9 KiB
Python
61 lines
1.9 KiB
Python
"""
|
|
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:
|
|
raise Error('ffprobe', out, err)
|
|
return json.loads(out.decode('utf-8'))
|
|
|
|
|
|
__all__ = ['probe']
|