Skip to content

Instantly share code, notes, and snippets.

@AlmightyOatmeal
Last active May 8, 2018 23:01
Show Gist options
  • Save AlmightyOatmeal/3ef156a3a1f8d264e7973f47392c258d to your computer and use it in GitHub Desktop.
Save AlmightyOatmeal/3ef156a3a1f8d264e7973f47392c258d to your computer and use it in GitHub Desktop.
Fun with Python subprocess! Works on Python 2.7.x.
import json
import logging
import os
import subprocess
logger = logging.getLogger(os.path.splitext(os.path.basename(__file__))[0])
# If you have ever used jq and tried to use it in Python but ran into
# issues with building a new jq instance rather than using the system-
# available jq binary then this may be beneficial to you!
# Please note that this has been tested on rather large JSON documents
# but it can be quite easy to overrun the buffers and cause the
# operation to fail but this is a good start.
def execute_jq_cmd(data_str, jq_query):
proc = subprocess.Popen(
'jq \'{}\' -'.format(jq_query),
shell=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
proc.stdin.write(data_str)
proc_comm = proc.communicate()
proc_stdout = proc_comm[0].strip()
proc_stderr = proc_comm[1].strip()
if proc_stdout:
try:
return json.loads(proc_stdout)
except Exception as err:
logger.exception(err)
return []
elif proc_stderr:
raise Exception(proc_stdout)
# This assumes that you already have ffmpeg/ffprobe installed.
def ffprobe_json(file_path):
"""Execute ffprobe and return a dictionary object containing media medata.
:param file_path: Path of the file to analyze.
:type file_path: str
:return: Dictionary structure containing media metadata.
:rtype: dict
"""
file_path = os.path.abspath(file_path)
FFPROBE_CMD = [
'ffprobe',
# '/usr/local/bin/ffprobe',
'-v quiet',
'-show_format',
'-show_streams',
'-show_programs',
'-show_chapters',
'-show_private_data',
'-show_pixel_formats',
'-show_error',
'-print_format json',
'-i "{}"'.format(file_path)
]
p = subprocess.Popen(
' '.join(FFPROBE_CMD),
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
# Better handling of large quanitties of data without overloading buffers.
draineddata = []
drainerthread = threading.Thread(target=draineddata.extend, args=(p.stdout,))
drainerthread.daemon = True
drainerthread.start()
p.wait()
drainerthread.join()
out = ''.join(draineddata)
data_dict = {}
if out:
data_dict.update(json.loads(out))
return data_dict
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment