Merged in feature/PYPE-552_standalon_preview_create (pull request #321)

Feature/PYPE-552 standalon preview create
This commit is contained in:
Jakub Trllo 2019-10-16 14:26:57 +00:00 committed by Jakub Ježek
commit a1d4e25895
3 changed files with 200 additions and 3 deletions

View file

@ -106,6 +106,12 @@ class CollectContextDataSAPublish(pyblish.api.ContextPlugin):
instance.data["frameEnd"] = int(component["frameEnd"])
instance.data['fps'] = int(component['fps'])
if component["preview"]:
instance.data["families"].append("review")
instance.data["repreProfiles"] = ["h264"]
component["tags"] = ["review", "delete"]
self.log.debug("Adding review family")
instance.data["representations"].append(component)
self.log.info(in_data)

View file

@ -0,0 +1,186 @@
import os
import pyblish.api
from pype.vendor import clique
import pype.api
class ExtractReviewSaP(pyblish.api.InstancePlugin):
"""Extracting Review mov file for Ftrack
Compulsory attribute of representation is tags list with "review",
otherwise the representation is ignored.
All new represetnations are created and encoded by ffmpeg following
presets found in `pype-config/presets/plugins/global/publish.json:ExtractReview:outputs`. To change the file extension
filter values use preset's attributes `ext_filter`
"""
label = "Extract Review SaP"
order = pyblish.api.ExtractorOrder + 0.02
families = ["review"]
hosts = ["standalonepublisher"]
def process(self, instance):
# adding plugin attributes from presets
presets = instance.context.data["presets"]
publish_presets = presets["plugins"]["global"]["publish"]
try:
plugin_attrs = publish_presets[self.__class__.__name__]
except KeyError:
raise KeyError("Preset for plugin \"{}\" are not set".format(
self.__class__.__name__
))
output_profiles = plugin_attrs.get("outputs", {})
fps = instance.data.get("fps")
start_frame = instance.data.get("frameStart")
self.log.debug("Families In: `{}`".format(instance.data["families"]))
# get specific profile if was defined
specific_profiles = instance.data.get("repreProfiles")
new_repres = []
# filter out mov and img sequences
for repre in instance.data["representations"]:
tags = repre.get("tags", [])
if "review" not in tags:
continue
staging_dir = repre["stagingDir"]
for name in specific_profiles:
profile = output_profiles.get(name)
if not profile:
self.log.warning(
"Profile \"{}\" was not found in presets".format(name)
)
continue
self.log.debug("Processing profile: {}".format(name))
ext = profile.get("ext", None)
if not ext:
ext = "mov"
self.log.debug((
"`ext` attribute not in output profile \"{}\"."
" Setting to default ext: `mov`"
).format(name))
if isinstance(repre["files"], list):
collections, remainder = clique.assemble(repre["files"])
full_input_path = os.path.join(
staging_dir,
collections[0].format("{head}{padding}{tail}")
)
filename = collections[0].format('{head}')
if filename.endswith("."):
filename = filename[:-1]
else:
full_input_path = os.path.join(staging_dir, repre["files"])
filename = repre["files"].split(".")[0]
repr_file = filename + "_{0}.{1}".format(name, ext)
full_output_path = os.path.join(staging_dir, repr_file)
self.log.info("input {}".format(full_input_path))
self.log.info("output {}".format(full_output_path))
repre_new = repre.copy()
new_tags = [x for x in tags if x != "delete"]
p_tags = profile.get("tags", [])
self.log.info("p_tags: `{}`".format(p_tags))
for _tag in p_tags:
if _tag not in new_tags:
new_tags.append(_tag)
self.log.info("new_tags: `{}`".format(new_tags))
input_args = []
# overrides output file
input_args.append("-y")
# preset's input data
input_args.extend(profile.get("input", []))
# necessary input data
# adds start arg only if image sequence
if isinstance(repre["files"], list):
input_args.extend([
"-start_number {}".format(start_frame),
"-framerate {}".format(fps)
])
input_args.append("-i {}".format(full_input_path))
output_args = []
# preset's output data
output_args.extend(profile.get("output", []))
# set length of video by len of inserted files
output_args.append("-frames {}".format(len(repre["files"])))
# letter_box
lb_string = (
"-filter:v "
"drawbox=0:0:iw:round((ih-(iw*(1/{0})))/2):t=fill:c=black,"
"drawbox=0:ih-round((ih-(iw*(1/{0})))/2):iw:"
"round((ih-(iw*(1/{0})))/2):t=fill:c=black"
)
letter_box = profile.get("letter_box", None)
if letter_box:
output_args.append(lb_string.format(letter_box))
# output filename
output_args.append(full_output_path)
ffmpeg_path = os.getenv("FFMPEG_PATH", "")
if ffmpeg_path:
ffmpeg_path += "/ffmpeg"
else:
ffmpeg_path = "ffmpeg"
mov_args = [
ffmpeg_path,
" ".join(input_args),
" ".join(output_args)
]
subprcs_cmd = " ".join(mov_args)
# run subprocess
self.log.debug("Executing: {}".format(subprcs_cmd))
output = pype.api.subprocess(subprcs_cmd)
self.log.debug("Output: {}".format(output))
# create representation data
repre_new.update({
"name": name,
"ext": ext,
"files": repr_file,
"tags": new_tags,
"outputName": name
})
if repre_new.get("preview"):
repre_new.pop("preview")
if repre_new.get("thumbnail"):
repre_new.pop("thumbnail")
# adding representation
self.log.debug("Adding: {}".format(repre_new))
new_repres.append(repre_new)
for repre in instance.data["representations"]:
if "delete" in repre.get("tags", []):
instance.data["representations"].remove(repre)
for repre in new_repres:
self.log.debug("Adding repre: \"{}\"".format(
repre
))
instance.data["representations"].append(repre)

View file

@ -297,18 +297,23 @@ class DropDataFrame(QtWidgets.QFrame):
if ext in exts:
icon = ico
break
new_is_seq = data['is_sequence']
# Add 's' to icon_name if is sequence (image -> images)
if data['is_sequence']:
if new_is_seq:
icon += 's'
data['icon'] = icon
data['thumb'] = (
ext in self.presets['extensions']['image_file'] or
ext in self.presets['extensions']['video_file']
)
data['prev'] = ext in self.presets['extensions']['video_file']
data['prev'] = (
ext in self.presets['extensions']['video_file'] or
(new_is_seq and ext in self.presets['extensions']['image_file'])
)
actions = []
new_is_seq = data['is_sequence']
found = False
for item in self.components_list.widgets():