ayon-core/pype/plugins/standalonepublisher/publish/extract_thumbnail.py

124 lines
3.7 KiB
Python

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 = os.path.join(
thumbnail_repre["stagingDir"], 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)
full_input_path = '"{}"'.format(full_input_path)
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("\"{}\"".format(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,
"tags": ["thumbnail"],
}
# # add Delete tag when temp file was rendered
if not is_jpeg:
representation["tags"].append("delete")
instance.data["representations"].append(representation)