diff --git a/openpype/hosts/maya/plugins/publish/collect_review.py b/openpype/hosts/maya/plugins/publish/collect_review.py index 80fd5b0dbd..3d3ee09eed 100644 --- a/openpype/hosts/maya/plugins/publish/collect_review.py +++ b/openpype/hosts/maya/plugins/publish/collect_review.py @@ -146,11 +146,24 @@ class CollectReview(pyblish.api.InstancePlugin): ) # Collect focal length. - data = { - "cameraFocalLength": cmds.getAttr(camera + ".focalLength") - } + #Refactor to lib or use available lib method. + plug = "{0}.focalLength".format(camera) + focal_length = None + if not cmds.listConnections(plug, destination=False, source=True): + # Static. + focal_length = cmds.getAttr(plug) + else: + # Dynamic. + start = instance.data["frameStart"] + end = instance.data["frameEnd"] + 1 + focal_length = [ + cmds.getAttr(plug, time=t) for t in range(int(start), int(end)) + ] + + key = "focalLength" + instance.data[key] = focal_length try: - instance.data["customData"].update(data) + instance.data["burninDataMembers"].append(key) except KeyError: - instance.data["customData"] = data + instance.data["burninDataMembers"] = [key] diff --git a/openpype/lib/execute.py b/openpype/lib/execute.py index 759a4db0cb..5ba62f177f 100644 --- a/openpype/lib/execute.py +++ b/openpype/lib/execute.py @@ -8,6 +8,8 @@ import tempfile from .log import Logger from .vendor_bin_utils import find_executable +from .openpype_version import is_running_from_build + # MSDN process creation flag (Windows only) CREATE_NO_WINDOW = 0x08000000 @@ -196,6 +198,11 @@ def run_openpype_process(*args, **kwargs): # Skip envs that can affect OpenPype process # - fill more if you find more env = clean_envs_for_openpype_process(os.environ) + + # Add OpenPype version if we are running from build. + if not is_running_from_build(): + env.pop("OPENPYPE_VERSION", None) + return run_subprocess(args, env=env, **kwargs) diff --git a/openpype/plugins/publish/extract_burnin.py b/openpype/plugins/publish/extract_burnin.py index f113e61bb0..de876c8486 100644 --- a/openpype/plugins/publish/extract_burnin.py +++ b/openpype/plugins/publish/extract_burnin.py @@ -254,6 +254,10 @@ class ExtractBurnin(publish.Extractor): # Add context data burnin_data. burnin_data["custom"] = custom_data + # Add data members. + for key in instance.data.get("burninDataMembers", []): + burnin_data[key] = instance.data[key] + # Add source camera name to burnin data camera_name = repre.get("camera_name") if camera_name: diff --git a/openpype/scripts/otio_burnin.py b/openpype/scripts/otio_burnin.py index cb4646c099..bb7a208103 100644 --- a/openpype/scripts/otio_burnin.py +++ b/openpype/scripts/otio_burnin.py @@ -4,8 +4,10 @@ import re import subprocess import platform import json -import opentimelineio_contrib.adapters.ffmpeg_burnins as ffmpeg_burnins +import tempfile +from string import Formatter +import opentimelineio_contrib.adapters.ffmpeg_burnins as ffmpeg_burnins from openpype.lib import ( get_ffmpeg_tool_path, get_ffmpeg_codec_args, @@ -23,7 +25,7 @@ FFMPEG = ( ).format(ffmpeg_path) DRAWTEXT = ( - "drawtext=fontfile='%(font)s':text=\\'%(text)s\\':" + "drawtext@'%(label)s'=fontfile='%(font)s':text=\\'%(text)s\\':" "x=%(x)s:y=%(y)s:fontcolor=%(color)s@%(opacity).1f:fontsize=%(size)d" ) TIMECODE = ( @@ -39,6 +41,34 @@ TIMECODE_KEY = "{timecode}" SOURCE_TIMECODE_KEY = "{source_timecode}" +def convert_list_to_cmd(list_to_convert, fps, label=""): + path = None + #need to clean up temp file when done + with tempfile.NamedTemporaryFile(mode="w", delete=False) as f: + for i, value in enumerate(list_to_convert): + seconds = i / fps + + # Escape special character + value = str(value).replace(":", "\\:") + + filter = "drawtext" + if label: + filter += "@" + label + + line = ( + "{start} {filter} reinit text='{value}';" + "\n".format(start=seconds, filter=filter, value=value) + ) + + f.write(line) + f.flush() + path = f.name + path = path.replace("\\", "/") + path = path.replace(":", "\\:") + + return "sendcmd=f='{}'".format(path) + + def _get_ffprobe_data(source): """Reimplemented from otio burnins to be able use full path to ffprobe :param str source: source media file @@ -144,7 +174,7 @@ class ModifiedBurnins(ffmpeg_burnins.Burnins): self.options_init.update(options_init) def add_text( - self, text, align, frame_start=None, frame_end=None, options=None + self, text, align, frame_start=None, frame_end=None, options=None, cmd="" ): """ Adding static text to a filter. @@ -165,7 +195,13 @@ class ModifiedBurnins(ffmpeg_burnins.Burnins): if frame_end is not None: options["frame_end"] = frame_end - self._add_burnin(text, align, options, DRAWTEXT) + draw_text = DRAWTEXT + if cmd: + draw_text = "{}, {}".format(cmd, DRAWTEXT) + + options["label"] = align + + self._add_burnin(text, align, options, draw_text) def add_timecode( self, align, frame_start=None, frame_end=None, frame_start_tc=None, @@ -501,7 +537,7 @@ def burnins_from_data( if not value: continue - if isinstance(value, (dict, list, tuple)): + if isinstance(value, (dict, tuple)): raise TypeError(( "Expected string or number type." " Got: {} - \"{}\"" @@ -573,8 +609,43 @@ def burnins_from_data( burnin.add_timecode(*args) continue - text = value.format(**data) - burnin.add_text(text, align, frame_start, frame_end) + cmd = "" + text = None + keys = [i[1] for i in Formatter().parse(value) if i[1] is not None] + list_to_convert = [] + + # Warn about nested dictionary support for lists. Ei. we dont support + # it. + if "[" in "".join(keys): + print( + "We dont support converting nested dictionaries to lists," + " so skipping {}".format(value) + ) + else: + for key in keys: + data_value = data[key] + + # Multiple lists are not supported. + if isinstance(data_value, list) and list_to_convert: + raise ValueError( + "Found multiple lists to convert, which is not " + "supported: {}".format(value) + ) + + if isinstance(data_value, list): + print("Found list to convert: {}".format(data_value)) + for v in data_value: + data[key] = v + list_to_convert.append(value.format(**data)) + + if list_to_convert: + text = list_to_convert[0] + cmd = convert_list_to_cmd(list_to_convert, 25.0, label=align)# need to fetch fps properly + print("cmd: " + cmd) + else: + text = value.format(**data) + print(text) + burnin.add_text(text, align, frame_start, frame_end, cmd=cmd) ffmpeg_args = [] if codec_data: @@ -613,6 +684,8 @@ if __name__ == "__main__": with open(in_data_json_path, "r") as file_stream: in_data = json.load(file_stream) + print(json.dumps(in_data, indent=4, sort_keys=True)) + burnins_from_data( in_data["input"], in_data["output"],