mirror of
https://github.com/ynput/ayon-core.git
synced 2026-01-01 16:34:53 +01:00
Merge branch 'hotfix/fixes_ind_edit_publish' into develop
This commit is contained in:
commit
5b64ad5ffa
9 changed files with 25 additions and 244 deletions
|
|
@ -30,7 +30,8 @@ class IntegrateFtrackInstance(pyblish.api.InstancePlugin):
|
||||||
'audio': 'audio',
|
'audio': 'audio',
|
||||||
'workfile': 'scene',
|
'workfile': 'scene',
|
||||||
'animation': 'cache',
|
'animation': 'cache',
|
||||||
'image': 'img'
|
'image': 'img',
|
||||||
|
'reference': 'reference'
|
||||||
}
|
}
|
||||||
|
|
||||||
def process(self, instance):
|
def process(self, instance):
|
||||||
|
|
|
||||||
|
|
@ -224,7 +224,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)
|
output = pype.api.subprocess(args, shell=True)
|
||||||
self.log.debug("Output: {}".format(output))
|
self.log.debug("Output: {}".format(output))
|
||||||
|
|
||||||
for filepath in temp_data["full_input_paths"]:
|
for filepath in temp_data["full_input_paths"]:
|
||||||
|
|
@ -964,7 +964,7 @@ class ExtractBurnin(pype.api.Extractor):
|
||||||
|
|
||||||
args = [executable, scriptpath, json_data]
|
args = [executable, scriptpath, json_data]
|
||||||
self.log.debug("Executing: {}".format(args))
|
self.log.debug("Executing: {}".format(args))
|
||||||
output = pype.api.subprocess(args)
|
output = pype.api.subprocess(args, shell=True)
|
||||||
self.log.debug("Output: {}".format(output))
|
self.log.debug("Output: {}".format(output))
|
||||||
|
|
||||||
repre_update = {
|
repre_update = {
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ class ExtractJpegEXR(pyblish.api.InstancePlugin):
|
||||||
|
|
||||||
# run subprocess
|
# run subprocess
|
||||||
self.log.debug("{}".format(subprocess_jpeg))
|
self.log.debug("{}".format(subprocess_jpeg))
|
||||||
pype.api.subprocess(subprocess_jpeg)
|
pype.api.subprocess(subprocess_jpeg, shell=True)
|
||||||
|
|
||||||
if "representations" not in instance.data:
|
if "representations" not in instance.data:
|
||||||
instance.data["representations"] = []
|
instance.data["representations"] = []
|
||||||
|
|
|
||||||
|
|
@ -175,7 +175,7 @@ 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)
|
output = pype.api.subprocess(subprcs_cmd, shell=True)
|
||||||
self.log.debug("Output: {}".format(output))
|
self.log.debug("Output: {}".format(output))
|
||||||
|
|
||||||
output_name = output_def["filename_suffix"]
|
output_name = output_def["filename_suffix"]
|
||||||
|
|
@ -193,6 +193,8 @@ class ExtractReview(pyblish.api.InstancePlugin):
|
||||||
# Force to pop these key if are in new repre
|
# Force to pop these key if are in new repre
|
||||||
new_repre.pop("preview", None)
|
new_repre.pop("preview", None)
|
||||||
new_repre.pop("thumbnail", None)
|
new_repre.pop("thumbnail", None)
|
||||||
|
if "clean_name" in new_repre.get("tags", []):
|
||||||
|
new_repre.pop("outputName")
|
||||||
|
|
||||||
# adding representation
|
# adding representation
|
||||||
self.log.debug(
|
self.log.debug(
|
||||||
|
|
@ -342,6 +344,12 @@ class ExtractReview(pyblish.api.InstancePlugin):
|
||||||
"-i \"{}\"".format(temp_data["full_input_path"])
|
"-i \"{}\"".format(temp_data["full_input_path"])
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if temp_data["output_is_sequence"]:
|
||||||
|
# Set start frame
|
||||||
|
ffmpeg_input_args.append(
|
||||||
|
"-start_number {}".format(temp_data["output_frame_start"])
|
||||||
|
)
|
||||||
|
|
||||||
# Add audio arguments if there are any. Skipped when output are images.
|
# Add audio arguments if there are any. Skipped when output are images.
|
||||||
if not temp_data["output_ext_is_image"]:
|
if not temp_data["output_ext_is_image"]:
|
||||||
audio_in_args, audio_filters, audio_out_args = self.audio_args(
|
audio_in_args, audio_filters, audio_out_args = self.audio_args(
|
||||||
|
|
@ -1482,7 +1490,7 @@ 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)
|
output = pype.api.subprocess(subprcs_cmd, shell=True)
|
||||||
self.log.debug("Output: {}".format(output))
|
self.log.debug("Output: {}".format(output))
|
||||||
|
|
||||||
# create representation data
|
# create representation data
|
||||||
|
|
@ -1522,6 +1530,8 @@ class ExtractReview(pyblish.api.InstancePlugin):
|
||||||
for repre in representations_new:
|
for repre in representations_new:
|
||||||
if "delete" in repre.get("tags", []):
|
if "delete" in repre.get("tags", []):
|
||||||
representations_new.remove(repre)
|
representations_new.remove(repre)
|
||||||
|
if "clean_name" in repre.get("tags", []):
|
||||||
|
repre_new.pop("outputName")
|
||||||
|
|
||||||
instance.data.update({
|
instance.data.update({
|
||||||
"reviewToWidth": self.to_width,
|
"reviewToWidth": self.to_width,
|
||||||
|
|
|
||||||
|
|
@ -186,7 +186,7 @@ class ExtractReviewSlate(pype.api.Extractor):
|
||||||
|
|
||||||
# run slate generation subprocess
|
# run slate generation subprocess
|
||||||
self.log.debug("Slate Executing: {}".format(slate_subprcs_cmd))
|
self.log.debug("Slate Executing: {}".format(slate_subprcs_cmd))
|
||||||
slate_output = pype.api.subprocess(slate_subprcs_cmd)
|
slate_output = pype.api.subprocess(slate_subprcs_cmd, shell=True)
|
||||||
self.log.debug("Slate Output: {}".format(slate_output))
|
self.log.debug("Slate Output: {}".format(slate_output))
|
||||||
|
|
||||||
# create ffmpeg concat text file path
|
# create ffmpeg concat text file path
|
||||||
|
|
@ -221,7 +221,7 @@ class ExtractReviewSlate(pype.api.Extractor):
|
||||||
|
|
||||||
# ffmpeg concat subprocess
|
# ffmpeg concat subprocess
|
||||||
self.log.debug("Executing concat: {}".format(concat_subprcs_cmd))
|
self.log.debug("Executing concat: {}".format(concat_subprcs_cmd))
|
||||||
concat_output = pype.api.subprocess(concat_subprcs_cmd)
|
concat_output = pype.api.subprocess(concat_subprcs_cmd, shell=True)
|
||||||
self.log.debug("Output concat: {}".format(concat_output))
|
self.log.debug("Output concat: {}".format(concat_output))
|
||||||
|
|
||||||
self.log.debug("__ repre[tags]: {}".format(repre["tags"]))
|
self.log.debug("__ repre[tags]: {}".format(repre["tags"]))
|
||||||
|
|
|
||||||
|
|
@ -351,7 +351,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin):
|
||||||
|
|
||||||
index_frame_start = None
|
index_frame_start = None
|
||||||
|
|
||||||
if repre.get("frameStart"):
|
if repre.get("frameStart") is not None:
|
||||||
frame_start_padding = int(
|
frame_start_padding = int(
|
||||||
anatomy.templates["render"].get(
|
anatomy.templates["render"].get(
|
||||||
"frame_padding",
|
"frame_padding",
|
||||||
|
|
@ -378,7 +378,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin):
|
||||||
|
|
||||||
dst_padding = src_padding_exp % i
|
dst_padding = src_padding_exp % i
|
||||||
|
|
||||||
if index_frame_start:
|
if index_frame_start is not None:
|
||||||
dst_padding_exp = "%0{}d".format(frame_start_padding)
|
dst_padding_exp = "%0{}d".format(frame_start_padding)
|
||||||
dst_padding = dst_padding_exp % index_frame_start
|
dst_padding = dst_padding_exp % index_frame_start
|
||||||
index_frame_start += 1
|
index_frame_start += 1
|
||||||
|
|
|
||||||
|
|
@ -18,15 +18,15 @@ class CollectClipInstances(pyblish.api.InstancePlugin):
|
||||||
"referenceMain": {
|
"referenceMain": {
|
||||||
"family": "review",
|
"family": "review",
|
||||||
"families": ["review", "ftrack"],
|
"families": ["review", "ftrack"],
|
||||||
"ftrackFamily": "review",
|
# "ftrackFamily": "review",
|
||||||
"extension": ".mp4"
|
"extension": ".mp4"
|
||||||
},
|
},
|
||||||
"audioMain": {
|
"audioMain": {
|
||||||
"family": "audio",
|
"family": "audio",
|
||||||
"families": ["ftrack"],
|
"families": ["ftrack"],
|
||||||
"ftrackFamily": "audio",
|
# "ftrackFamily": "audio",
|
||||||
"extension": ".wav",
|
"extension": ".wav",
|
||||||
"version": 1
|
# "version": 1
|
||||||
},
|
},
|
||||||
"shotMain": {
|
"shotMain": {
|
||||||
"family": "shot",
|
"family": "shot",
|
||||||
|
|
|
||||||
|
|
@ -1,199 +0,0 @@
|
||||||
import os
|
|
||||||
import tempfile
|
|
||||||
|
|
||||||
import pyblish.api
|
|
||||||
import clique
|
|
||||||
import pype.api
|
|
||||||
import pype.lib
|
|
||||||
|
|
||||||
|
|
||||||
class ExtractReviewSP(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 SP"
|
|
||||||
order = pyblish.api.ExtractorOrder + 0.02
|
|
||||||
families = ["review"]
|
|
||||||
hosts = ["standalonepublisher"]
|
|
||||||
|
|
||||||
def process(self, instance):
|
|
||||||
# adding plugin attributes from presets
|
|
||||||
presets = instance.context.data["presets"]
|
|
||||||
try:
|
|
||||||
publish_presets = presets["plugins"]["standalonepublisher"]["publish"]
|
|
||||||
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]
|
|
||||||
|
|
||||||
# prepare output file
|
|
||||||
repr_file = filename + "_{0}.{1}".format(name, ext)
|
|
||||||
out_stagigng_dir = tempfile.mkdtemp(prefix="extract_review_")
|
|
||||||
full_output_path = os.path.join(out_stagigng_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", []))
|
|
||||||
|
|
||||||
if isinstance(repre["files"], list):
|
|
||||||
# set length of video by len of inserted files
|
|
||||||
video_len = len(repre["files"])
|
|
||||||
else:
|
|
||||||
video_len = repre["frameEnd"] - repre["frameStart"] + 1
|
|
||||||
output_args.append(
|
|
||||||
"-frames {}".format(video_len)
|
|
||||||
)
|
|
||||||
|
|
||||||
# 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 = pype.lib.get_ffmpeg_tool_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,
|
|
||||||
"stagingDir": out_stagigng_dir,
|
|
||||||
"tags": new_tags,
|
|
||||||
"outputName": name,
|
|
||||||
"frameStartFtrack": 1,
|
|
||||||
"frameEndFtrack": video_len
|
|
||||||
})
|
|
||||||
# cleanup thumbnail from new repre
|
|
||||||
if repre_new.get("thumbnail"):
|
|
||||||
repre_new.pop("thumbnail")
|
|
||||||
if "thumbnail" in repre_new["tags"]:
|
|
||||||
repre_new["tags"].remove("thumbnail")
|
|
||||||
|
|
||||||
# adding representation
|
|
||||||
self.log.debug("Adding: {}".format(repre_new))
|
|
||||||
# cleanup repre from preview
|
|
||||||
if "preview" in repre:
|
|
||||||
repre.pop("preview")
|
|
||||||
if "preview" in repre["tags"]:
|
|
||||||
repre["tags"].remove("preview")
|
|
||||||
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)
|
|
||||||
|
|
@ -13,7 +13,6 @@ class ExtractShotData(pype.api.Extractor):
|
||||||
families = ["review", "audio"]
|
families = ["review", "audio"]
|
||||||
|
|
||||||
# presets
|
# presets
|
||||||
add_representation = None # ".jpeg"
|
|
||||||
|
|
||||||
def process(self, instance):
|
def process(self, instance):
|
||||||
representation = instance.data.get("representations")
|
representation = instance.data.get("representations")
|
||||||
|
|
@ -68,7 +67,7 @@ class ExtractShotData(pype.api.Extractor):
|
||||||
|
|
||||||
self.log.info(f"Processing: {args}")
|
self.log.info(f"Processing: {args}")
|
||||||
ffmpeg_args = " ".join(args)
|
ffmpeg_args = " ".join(args)
|
||||||
output = pype.api.subprocess(ffmpeg_args)
|
output = pype.api.subprocess(ffmpeg_args, shell=True)
|
||||||
self.log.info(output)
|
self.log.info(output)
|
||||||
|
|
||||||
repr = {
|
repr = {
|
||||||
|
|
@ -90,34 +89,4 @@ class ExtractShotData(pype.api.Extractor):
|
||||||
|
|
||||||
instance.data["representations"].append(repr)
|
instance.data["representations"].append(repr)
|
||||||
|
|
||||||
if self.add_representation:
|
|
||||||
# Generate jpegs.
|
|
||||||
clip_img_sequence = os.path.join(
|
|
||||||
staging_dir, instance.data["name"] + ".%04d.jpeg"
|
|
||||||
)
|
|
||||||
args = [
|
|
||||||
ffmpeg_path, "-i",
|
|
||||||
f"\"{clip_trimed_path}\"",
|
|
||||||
f"\"{clip_img_sequence}\""
|
|
||||||
]
|
|
||||||
self.log.info(f"Processing: {args}")
|
|
||||||
output = pype.lib._subprocess(args)
|
|
||||||
self.log.info(output)
|
|
||||||
|
|
||||||
# collect jpeg sequence if editorial data for publish
|
|
||||||
# are image sequence
|
|
||||||
collection = clique.Collection(
|
|
||||||
head=instance.data["name"] + ".", tail='.jpeg', padding=4
|
|
||||||
)
|
|
||||||
for f in os.listdir(staging_dir):
|
|
||||||
if collection.match(f):
|
|
||||||
collection.add(f)
|
|
||||||
|
|
||||||
instance.data["representations"].append({
|
|
||||||
"name": "jpeg",
|
|
||||||
"ext": "jpeg",
|
|
||||||
"files": list(collection),
|
|
||||||
"stagingDir": staging_dir
|
|
||||||
})
|
|
||||||
|
|
||||||
self.log.debug(f"Instance data: {pformat(instance.data)}")
|
self.log.debug(f"Instance data: {pformat(instance.data)}")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue