From b3f279c3ba57061b037777000bb341603807f015 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 20 Aug 2020 14:59:26 +0200 Subject: [PATCH 1/6] return extract thumbnail to SP --- .../publish/extract_thumbnail.py | 122 ++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 pype/plugins/standalonepublisher/publish/extract_thumbnail.py diff --git a/pype/plugins/standalonepublisher/publish/extract_thumbnail.py b/pype/plugins/standalonepublisher/publish/extract_thumbnail.py new file mode 100644 index 0000000000..cddc9c3a82 --- /dev/null +++ b/pype/plugins/standalonepublisher/publish/extract_thumbnail.py @@ -0,0 +1,122 @@ +import os +import tempfile +import subprocess +import pyblish.api +import pype.api +import pype.lib + + +class ExtractThumbnailSP(pyblish.api.InstancePlugin): + """Extract jpeg thumbnail from component input from standalone publisher + + Uses jpeg file from component if possible (when single or multiple jpegs + are loaded to component selected as thumbnail) otherwise extracts from + input file/s single jpeg to temp. + """ + + label = "Extract Thumbnail SP" + hosts = ["standalonepublisher"] + order = pyblish.api.ExtractorOrder + + # Presetable attribute + ffmpeg_args = None + + def process(self, instance): + repres = instance.data.get('representations') + if not repres: + return + + thumbnail_repre = None + for repre in repres: + if repre.get("thumbnail"): + thumbnail_repre = repre + break + + if not thumbnail_repre: + return + + files = thumbnail_repre.get("files") + if not files: + return + + if isinstance(files, list): + files_len = len(files) + file = str(files[0]) + else: + files_len = 1 + file = files + + is_jpeg = False + if file.endswith(".jpeg") or file.endswith(".jpg"): + is_jpeg = True + + if is_jpeg and files_len == 1: + # skip if already is single jpeg file + return + + elif is_jpeg: + # use first frame as thumbnail if is sequence of jpegs + full_thumbnail_path = file + self.log.info( + "For thumbnail is used file: {}".format(full_thumbnail_path) + ) + + else: + # Convert to jpeg if not yet + full_input_path = os.path.join(thumbnail_repre["stagingDir"], file) + self.log.info("input {}".format(full_input_path)) + + full_thumbnail_path = tempfile.mkstemp(suffix=".jpg")[1] + self.log.info("output {}".format(full_thumbnail_path)) + + ffmpeg_path = pype.lib.get_ffmpeg_tool_path("ffmpeg") + + ffmpeg_args = self.ffmpeg_args or {} + + jpeg_items = [] + jpeg_items.append(ffmpeg_path) + # override file if already exists + jpeg_items.append("-y") + # add input filters from peresets + jpeg_items.extend(ffmpeg_args.get("input") or []) + # input file + jpeg_items.append("-i {}".format(full_input_path)) + # extract only single file + jpeg_items.append("-vframes 1") + + jpeg_items.extend(ffmpeg_args.get("output") or []) + + # output file + jpeg_items.append(full_thumbnail_path) + + subprocess_jpeg = " ".join(jpeg_items) + + # run subprocess + self.log.debug("Executing: {}".format(subprocess_jpeg)) + subprocess.Popen( + subprocess_jpeg, + stdout=subprocess.PIPE, + shell=True + ) + + # remove thumbnail key from origin repre + thumbnail_repre.pop("thumbnail") + + filename = os.path.basename(full_thumbnail_path) + staging_dir = os.path.dirname(full_thumbnail_path) + + # create new thumbnail representation + representation = { + 'name': 'jpg', + 'ext': 'jpg', + 'files': filename, + "stagingDir": staging_dir, + "thumbnail": True, + "tags": [] + } + + # # add Delete tag when temp file was rendered + # if not is_jpeg: + # representation["tags"].append("delete") + + instance.data["representations"].append(representation) From 6516e8536162a6d9aa9f662293be9568914015be Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 20 Aug 2020 14:59:46 +0200 Subject: [PATCH 2/6] remove add_representation --- .../publish/extract_shot_data.py | 33 +------------------ 1 file changed, 1 insertion(+), 32 deletions(-) diff --git a/pype/plugins/standalonepublisher/publish/extract_shot_data.py b/pype/plugins/standalonepublisher/publish/extract_shot_data.py index 6cbc2c7882..c39247d6d6 100644 --- a/pype/plugins/standalonepublisher/publish/extract_shot_data.py +++ b/pype/plugins/standalonepublisher/publish/extract_shot_data.py @@ -13,7 +13,6 @@ class ExtractShotData(pype.api.Extractor): families = ["review", "audio"] # presets - add_representation = None # ".jpeg" def process(self, instance): representation = instance.data.get("representations") @@ -68,7 +67,7 @@ class ExtractShotData(pype.api.Extractor): self.log.info(f"Processing: {args}") ffmpeg_args = " ".join(args) - output = pype.api.subprocess(ffmpeg_args) + output = pype.api.subprocess(ffmpeg_args, shell=True) self.log.info(output) repr = { @@ -90,34 +89,4 @@ class ExtractShotData(pype.api.Extractor): 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)}") From f5cb0b04891f367ccdf7bc07270259b4ac22ec2a Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 20 Aug 2020 15:00:07 +0200 Subject: [PATCH 3/6] fix padding with start frame 0 --- pype/plugins/global/publish/integrate_new.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pype/plugins/global/publish/integrate_new.py b/pype/plugins/global/publish/integrate_new.py index 4510fc2d04..28a52e4353 100644 --- a/pype/plugins/global/publish/integrate_new.py +++ b/pype/plugins/global/publish/integrate_new.py @@ -351,7 +351,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): index_frame_start = None - if repre.get("frameStart"): + if repre.get("frameStart") is not None: frame_start_padding = int( anatomy.templates["render"].get( "frame_padding", @@ -378,7 +378,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): 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 = dst_padding_exp % index_frame_start index_frame_start += 1 From 9876bfa4cf0d6270f74f2fa16bfb5206b2910c0b Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 20 Aug 2020 15:00:29 +0200 Subject: [PATCH 4/6] add option to remove outputName from template data --- pype/plugins/global/publish/extract_review.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pype/plugins/global/publish/extract_review.py b/pype/plugins/global/publish/extract_review.py index ac8766f5a7..2807376d54 100644 --- a/pype/plugins/global/publish/extract_review.py +++ b/pype/plugins/global/publish/extract_review.py @@ -193,6 +193,8 @@ class ExtractReview(pyblish.api.InstancePlugin): # Force to pop these key if are in new repre new_repre.pop("preview", None) new_repre.pop("thumbnail", None) + if "clean_name" in new_repre.get("tags", []): + new_repre.pop("outputName") # adding representation self.log.debug( @@ -1528,6 +1530,8 @@ class ExtractReview(pyblish.api.InstancePlugin): for repre in representations_new: if "delete" in repre.get("tags", []): representations_new.remove(repre) + if "clean_name" in repre.get("tags", []): + repre_new.pop("outputName") instance.data.update({ "reviewToWidth": self.to_width, From f41bf542e8adddf372d142a3c97f912cb060cc70 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 20 Aug 2020 15:59:16 +0200 Subject: [PATCH 5/6] simplify default --- .../standalonepublisher/publish/collect_clip_instances.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pype/plugins/standalonepublisher/publish/collect_clip_instances.py b/pype/plugins/standalonepublisher/publish/collect_clip_instances.py index 3d9773d0b2..a7af8df143 100644 --- a/pype/plugins/standalonepublisher/publish/collect_clip_instances.py +++ b/pype/plugins/standalonepublisher/publish/collect_clip_instances.py @@ -18,15 +18,15 @@ class CollectClipInstances(pyblish.api.InstancePlugin): "referenceMain": { "family": "review", "families": ["review", "ftrack"], - "ftrackFamily": "review", + # "ftrackFamily": "review", "extension": ".mp4" }, "audioMain": { "family": "audio", "families": ["ftrack"], - "ftrackFamily": "audio", + # "ftrackFamily": "audio", "extension": ".wav", - "version": 1 + # "version": 1 }, "shotMain": { "family": "shot", From 016f529a90ef5ece370a1e6f1636805cc06c4876 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 20 Aug 2020 15:59:33 +0200 Subject: [PATCH 6/6] add reference family to ftrack --- pype/plugins/ftrack/publish/integrate_ftrack_instances.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pype/plugins/ftrack/publish/integrate_ftrack_instances.py b/pype/plugins/ftrack/publish/integrate_ftrack_instances.py index f5d7689678..9ef82cbc4b 100644 --- a/pype/plugins/ftrack/publish/integrate_ftrack_instances.py +++ b/pype/plugins/ftrack/publish/integrate_ftrack_instances.py @@ -30,7 +30,8 @@ class IntegrateFtrackInstance(pyblish.api.InstancePlugin): 'audio': 'audio', 'workfile': 'scene', 'animation': 'cache', - 'image': 'img' + 'image': 'img', + 'reference': 'reference' } def process(self, instance):