Merge pull request #641 from pypeclub/feature/burnin_script_output

Burnin script logs better output
This commit is contained in:
Milan Kolar 2020-10-16 10:53:03 +02:00 committed by GitHub
commit a9aff3b030
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 84 additions and 39 deletions

View file

@ -81,42 +81,69 @@ def get_ffmpeg_tool_path(tool="ffmpeg"):
# Special naming case for subprocess since its a built-in method. # Special naming case for subprocess since its a built-in method.
def _subprocess(*args, **kwargs): def _subprocess(*args, logger=None, **kwargs):
"""Convenience method for getting output errors for subprocess.""" """Convenience method for getting output errors for subprocess.
# make sure environment contains only strings Entered arguments and keyword arguments are passed to subprocess Popen.
if not kwargs.get("env"):
filtered_env = {k: str(v) for k, v in os.environ.items()} Args:
else: logger (logging.Logger): Logger object if want to use different than
filtered_env = {k: str(v) for k, v in kwargs.get("env").items()} lib's logger.
*args: Variable length arument list passed to Popen.
**kwargs : Arbitary keyword arguments passed to Popen.
Returns:
str: Full output of subprocess concatenated stdout and stderr.
Raises:
RuntimeError: Exception is raised if process finished with nonzero
return code.
"""
# Get environents from kwarg or use current process environments if were
# not passed.
env = kwargs.get("env") or os.environ
# Make sure environment contains only strings
filtered_env = {k: str(v) for k, v in env.items()}
# Use lib's logger if was not passed with kwargs.
if not logger:
logger = log
# set overrides # set overrides
kwargs['stdout'] = kwargs.get('stdout', subprocess.PIPE) kwargs['stdout'] = kwargs.get('stdout', subprocess.PIPE)
kwargs['stderr'] = kwargs.get('stderr', subprocess.STDOUT) kwargs['stderr'] = kwargs.get('stderr', subprocess.PIPE)
kwargs['stdin'] = kwargs.get('stdin', subprocess.PIPE) kwargs['stdin'] = kwargs.get('stdin', subprocess.PIPE)
kwargs['env'] = filtered_env kwargs['env'] = filtered_env
proc = subprocess.Popen(*args, **kwargs) proc = subprocess.Popen(*args, **kwargs)
output, error = proc.communicate() full_output = ""
_stdout, _stderr = proc.communicate()
if _stdout:
_stdout = _stdout.decode("utf-8")
full_output += _stdout
logger.debug(_stdout)
if output: if _stderr:
output = output.decode("utf-8") _stderr = _stderr.decode("utf-8")
output += "\n" # Add additional line break if output already containt stdout
for line in output.strip().split("\n"): if full_output:
log.info(line) full_output += "\n"
full_output += _stderr
if error: logger.warning(_stderr)
error = error.decode("utf-8")
error += "\n"
for line in error.strip().split("\n"):
log.error(line)
if proc.returncode != 0: if proc.returncode != 0:
raise ValueError( exc_msg = "Executing arguments was not successful: \"{}\"".format(args)
"\"{}\" was not successful:\nOutput: {}\nError: {}".format( if _stdout:
args, output, error)) exc_msg += "\n\nOutput:\n{}".format(_stdout)
return output
if _stderr:
exc_msg += "Error:\n{}".format(_stderr)
raise RuntimeError(exc_msg)
return full_output
def get_hierarchy(asset_name=None): def get_hierarchy(asset_name=None):

View file

@ -227,8 +227,7 @@ class ExtractBurnin(pype.api.Extractor):
self.log.debug("Executing: {}".format(args)) self.log.debug("Executing: {}".format(args))
# Run burnin script # Run burnin script
output = pype.api.subprocess(args, shell=True) pype.api.subprocess(args, shell=True, logger=self.log)
self.log.debug("Output: {}".format(output))
for filepath in temp_data["full_input_paths"]: for filepath in temp_data["full_input_paths"]:
filepath = filepath.replace("\\", "/") filepath = filepath.replace("\\", "/")

View file

@ -181,8 +181,10 @@ class ExtractReview(pyblish.api.InstancePlugin):
# run subprocess # run subprocess
self.log.debug("Executing: {}".format(subprcs_cmd)) self.log.debug("Executing: {}".format(subprcs_cmd))
output = pype.api.subprocess(subprcs_cmd, shell=True)
self.log.debug("Output: {}".format(output)) pype.api.subprocess(
subprcs_cmd, shell=True, logger=self.log
)
output_name = output_def["filename_suffix"] output_name = output_def["filename_suffix"]
if temp_data["without_handles"]: if temp_data["without_handles"]:

View file

@ -4,18 +4,16 @@ import re
import subprocess import subprocess
import json import json
import opentimelineio_contrib.adapters.ffmpeg_burnins as ffmpeg_burnins import opentimelineio_contrib.adapters.ffmpeg_burnins as ffmpeg_burnins
from pype.api import Logger, config from pype.api import config
import pype.lib import pype.lib
log = Logger().get_logger("BurninWrapper", "burninwrap")
ffmpeg_path = pype.lib.get_ffmpeg_tool_path("ffmpeg") ffmpeg_path = pype.lib.get_ffmpeg_tool_path("ffmpeg")
ffprobe_path = pype.lib.get_ffmpeg_tool_path("ffprobe") ffprobe_path = pype.lib.get_ffmpeg_tool_path("ffprobe")
FFMPEG = ( FFMPEG = (
'{} -loglevel panic -i "%(input)s" %(filters)s %(args)s%(output)s' '{} -i "%(input)s" %(filters)s %(args)s%(output)s'
).format(ffmpeg_path) ).format(ffmpeg_path)
FFPROBE = ( FFPROBE = (
@ -54,7 +52,7 @@ def _streams(source):
def get_fps(str_value): def get_fps(str_value):
if str_value == "0/0": if str_value == "0/0":
log.warning("Source has \"r_frame_rate\" value set to \"0/0\".") print("WARNING: Source has \"r_frame_rate\" value set to \"0/0\".")
return "Unknown" return "Unknown"
items = str_value.split("/") items = str_value.split("/")
@ -299,17 +297,34 @@ class ModifiedBurnins(ffmpeg_burnins.Burnins):
args=args, args=args,
overwrite=overwrite overwrite=overwrite
) )
log.info("Launching command: {}".format(command)) print("Launching command: {}".format(command))
proc = subprocess.Popen(
command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True
)
_stdout, _stderr = proc.communicate()
if _stdout:
print(_stdout.decode("utf-8"))
# This will probably never happen as ffmpeg use stdout
if _stderr:
print(_stderr.decode("utf-8"))
proc = subprocess.Popen(command, shell=True)
log.info(proc.communicate()[0])
if proc.returncode != 0: if proc.returncode != 0:
raise RuntimeError("Failed to render '%s': %s'" raise RuntimeError(
% (output, command)) "Failed to render '{}': {}'".format(output, command)
)
if is_sequence: if is_sequence:
output = output % kwargs.get("duration") output = output % kwargs.get("duration")
if not os.path.exists(output): if not os.path.exists(output):
raise RuntimeError("Failed to generate this fucking file '%s'" % output) raise RuntimeError(
"Failed to generate this f*cking file '%s'" % output
)
def example(input_path, output_path): def example(input_path, output_path):
@ -542,6 +557,7 @@ def burnins_from_data(
if __name__ == "__main__": if __name__ == "__main__":
print("* Burnin script started")
in_data = json.loads(sys.argv[-1]) in_data = json.loads(sys.argv[-1])
burnins_from_data( burnins_from_data(
in_data["input"], in_data["input"],
@ -551,3 +567,4 @@ if __name__ == "__main__":
options=in_data.get("options"), options=in_data.get("options"),
burnin_values=in_data.get("values") burnin_values=in_data.get("values")
) )
print("* Burnin script has finished")