preparation scripts added from past projects

This commit is contained in:
Jakub Jezek 2018-12-06 14:14:58 +01:00
parent c5c6927e61
commit 3a7ce1e1b2
2 changed files with 260 additions and 0 deletions

View file

@ -0,0 +1,153 @@
import os
import subprocess
import pyblish.api
import filelink
class ExtractTranscode(pyblish.api.InstancePlugin):
"""Extracts review movie from image sequence.
Offset to get images to transcode from.
"""
order = pyblish.api.ExtractorOrder + 0.1
label = "Transcode"
optional = True
families = ["review"]
def find_previous_index(self, index, indexes):
"""Finds the closest previous value in a list from a value."""
data = []
for i in indexes:
if i >= index:
continue
data.append(index - i)
return indexes[data.index(min(data))]
def process(self, instance):
if "collection" in instance.data.keys():
self.process_image(instance)
if "output_path" in instance.data.keys():
self.process_movie(instance)
def process_image(self, instance):
collection = instance.data.get("collection", [])
if not list(collection):
msg = "Skipping \"{0}\" because no frames was found."
self.log.warning(msg.format(instance.data["name"]))
return
# Temporary fill the missing frames.
missing = collection.holes()
if not collection.is_contiguous():
pattern = collection.format("{head}{padding}{tail}")
for index in missing.indexes:
dst = pattern % index
src_index = self.find_previous_index(
index, list(collection.indexes)
)
src = pattern % src_index
filelink.create(src, dst)
# Generate args.
# Has to be yuv420p for compatibility with older players and smooth
# playback. This does come with a sacrifice of more visible banding
# issues.
# -crf 18 is visually lossless.
args = [
"ffmpeg", "-y",
"-start_number", str(min(collection.indexes)),
"-framerate", str(instance.context.data["framerate"]),
"-i", collection.format("{head}{padding}{tail}"),
"-pix_fmt", "yuv420p",
"-crf", "18",
"-timecode", "00:00:00:01",
"-vframes",
str(max(collection.indexes) - min(collection.indexes) + 1),
"-vf",
"scale=trunc(iw/2)*2:trunc(ih/2)*2",
]
if instance.data.get("baked_colorspace_movie"):
args = [
"ffmpeg", "-y",
"-i", instance.data["baked_colorspace_movie"],
"-pix_fmt", "yuv420p",
"-crf", "18",
"-timecode", "00:00:00:01",
]
args.append(collection.format("{head}.mov"))
self.log.debug("Executing args: {0}".format(args))
# Can't use subprocess.check_output, cause Houdini doesn't like that.
p = subprocess.Popen(
args,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
stdin=subprocess.PIPE,
cwd=os.path.dirname(args[-1])
)
output = p.communicate()[0]
# Remove temporary frame fillers
for f in missing:
os.remove(f)
if p.returncode != 0:
raise ValueError(output)
self.log.debug(output)
def process_movie(self, instance):
# Generate args.
# Has to be yuv420p for compatibility with older players and smooth
# playback. This does come with a sacrifice of more visible banding
# issues.
args = [
"ffmpeg", "-y",
"-i", instance.data["output_path"],
"-pix_fmt", "yuv420p",
"-crf", "18",
"-timecode", "00:00:00:01",
]
if instance.data.get("baked_colorspace_movie"):
args = [
"ffmpeg", "-y",
"-i", instance.data["baked_colorspace_movie"],
"-pix_fmt", "yuv420p",
"-crf", "18",
"-timecode", "00:00:00:01",
]
split = os.path.splitext(instance.data["output_path"])
args.append(split[0] + "_review.mov")
self.log.debug("Executing args: {0}".format(args))
# Can't use subprocess.check_output, cause Houdini doesn't like that.
p = subprocess.Popen(
args,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
stdin=subprocess.PIPE,
cwd=os.path.dirname(args[-1])
)
output = p.communicate()[0]
if p.returncode != 0:
raise ValueError(output)
self.log.debug(output)

View file

@ -0,0 +1,107 @@
import os
import tempfile
import shutil
import nuke
import pyblish.api
class ExtractNukeBakedColorspace(pyblish.api.InstancePlugin):
"""Extracts movie with baked in luts
V:\Remote Apps\ffmpeg\bin>ffmpeg -y -i
V:/FUGA/VFX_OUT/VFX_070010/v02/VFX_070010_comp_v02._baked.mov
-pix_fmt yuv420p
-crf 18
-timecode 00:00:00:01
V:/FUGA/VFX_OUT/VFX_070010/v02/VFX_070010_comp_v02..mov
"""
order = pyblish.api.ExtractorOrder
label = "Baked Colorspace"
optional = True
families = ["review"]
hosts = ["nuke"]
def process(self, instance):
if "collection" not in instance.data.keys():
return
# Store selection
selection = [i for i in nuke.allNodes() if i["selected"].getValue()]
# Deselect all nodes to prevent external connections
[i["selected"].setValue(False) for i in nuke.allNodes()]
temporary_nodes = []
# Create nodes
first_frame = min(instance.data["collection"].indexes)
last_frame = max(instance.data["collection"].indexes)
temp_dir = tempfile.mkdtemp()
for f in instance.data["collection"]:
shutil.copy(f, os.path.join(temp_dir, os.path.basename(f)))
node = previous_node = nuke.createNode("Read")
node["file"].setValue(
os.path.join(temp_dir,
os.path.basename(instance.data["collection"].format(
"{head}{padding}{tail}"))).replace("\\", "/"))
node["first"].setValue(first_frame)
node["origfirst"].setValue(first_frame)
node["last"].setValue(last_frame)
node["origlast"].setValue(last_frame)
temporary_nodes.append(node)
reformat_node = nuke.createNode("Reformat")
reformat_node["format"].setValue("HD_1080")
reformat_node["resize"].setValue("fit")
reformat_node["filter"].setValue("Lanczos6")
reformat_node["black_outside"].setValue(True)
reformat_node.setInput(0, previous_node)
previous_node = reformat_node
temporary_nodes.append(reformat_node)
viewer_process_node = nuke.ViewerProcess.node()
dag_node = None
if viewer_process_node:
dag_node = nuke.createNode(viewer_process_node.Class())
dag_node.setInput(0, previous_node)
previous_node = dag_node
temporary_nodes.append(dag_node)
# Copy viewer process values
excludedKnobs = ["name", "xpos", "ypos"]
for item in viewer_process_node.knobs().keys():
if item not in excludedKnobs and item in dag_node.knobs():
x1 = viewer_process_node[item]
x2 = dag_node[item]
x2.fromScript(x1.toScript(False))
else:
self.log.warning("No viewer node found.")
write_node = nuke.createNode("Write")
path = instance.data["collection"].format("{head}_baked.mov")
instance.data["baked_colorspace_movie"] = path
write_node["file"].setValue(path.replace("\\", "/"))
write_node["file_type"].setValue("mov")
write_node["raw"].setValue(1)
write_node.setInput(0, previous_node)
temporary_nodes.append(write_node)
# Render frames
nuke.execute(write_node.name(), int(first_frame), int(last_frame))
# Clean up
for node in temporary_nodes:
nuke.delete(node)
shutil.rmtree(temp_dir)
# Restore selection
[i["selected"].setValue(False) for i in nuke.allNodes()]
[i["selected"].setValue(True) for i in selection]