mirror of
https://github.com/ynput/ayon-core.git
synced 2026-01-02 00:44:52 +01:00
feat(nks): adding empty black frames at handle start if missing
This commit is contained in:
parent
7ac7600611
commit
d4899b69dc
6 changed files with 119 additions and 23 deletions
21
pype/plugins/nukestudio/publish/collect_clip_resolution.py
Normal file
21
pype/plugins/nukestudio/publish/collect_clip_resolution.py
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import pyblish.api
|
||||
|
||||
|
||||
class CollectClipResolution(pyblish.api.InstancePlugin):
|
||||
"""Collect clip geometry resolution"""
|
||||
|
||||
order = pyblish.api.CollectorOrder + 0.101
|
||||
label = "Collect Clip Resoluton"
|
||||
hosts = ["nukestudio"]
|
||||
|
||||
def process(self, instance):
|
||||
sequence = instance.context.data['activeSequence']
|
||||
resolution_width = int(sequence.format().width())
|
||||
resolution_height = int(sequence.format().height())
|
||||
pixel_aspect = sequence.format().pixelAspect()
|
||||
|
||||
instance.data.update({
|
||||
"resolutionWidth": resolution_width,
|
||||
"resolutionHeight": resolution_height,
|
||||
"pixelAspect": pixel_aspect
|
||||
})
|
||||
|
|
@ -124,7 +124,7 @@ class CollectClips(api.ContextPlugin):
|
|||
"effects": effects,
|
||||
"sourceIn": int(item.sourceIn()),
|
||||
"sourceOut": int(item.sourceOut()),
|
||||
"mediaDuration": source.duration(),
|
||||
"mediaDuration": int(source.duration()),
|
||||
"clipIn": clip_in,
|
||||
"clipOut": clip_out,
|
||||
"clipDuration": (
|
||||
|
|
|
|||
|
|
@ -39,9 +39,9 @@ class CollectHierarchyInstance(pyblish.api.ContextPlugin):
|
|||
clip = instance.data["item"]
|
||||
asset = instance.data["asset"]
|
||||
sequence = context.data['activeSequence']
|
||||
width = int(sequence.format().width())
|
||||
height = int(sequence.format().height())
|
||||
pixel_aspect = sequence.format().pixelAspect()
|
||||
resolution_width = instance.data["resolutionWidth"]
|
||||
resolution_height = instance.data["resolutionHeight"]
|
||||
pixel_aspect = instance.data["pixelAspect"]
|
||||
clip_in = instance.data["clipIn"]
|
||||
clip_out = instance.data["clipOut"]
|
||||
fps = context.data["fps"]
|
||||
|
|
@ -187,8 +187,8 @@ class CollectHierarchyInstance(pyblish.api.ContextPlugin):
|
|||
"asset": asset,
|
||||
"hierarchy": hierarchy,
|
||||
"parents": parents,
|
||||
"resolutionWidth": width,
|
||||
"resolutionHeight": height,
|
||||
"resolutionWidth": resolution_width,
|
||||
"resolutionHeight": resolution_height,
|
||||
"pixelAspect": pixel_aspect,
|
||||
"fps": fps,
|
||||
"tasks": instance.data["tasks"]
|
||||
|
|
|
|||
|
|
@ -64,15 +64,15 @@ class CollectPlates(api.InstancePlugin):
|
|||
# adding SourceResolution if Tag was present
|
||||
if instance.data.get("sourceResolution") and instance.data.get("main"):
|
||||
item = instance.data["item"]
|
||||
width = int(item.source().mediaSource().width())
|
||||
height = int(item.source().mediaSource().height())
|
||||
resolution_width = int(item.source().mediaSource().width())
|
||||
resolution_height = int(item.source().mediaSource().height())
|
||||
pixel_aspect = int(item.source().mediaSource().pixelAspect())
|
||||
|
||||
self.log.info("Source Width and Height are: `{0} x {1} : {2}`".format(
|
||||
width, height, pixel_aspect))
|
||||
resolution_width, resolution_height, pixel_aspect))
|
||||
data.update({
|
||||
"width": width,
|
||||
"height": height,
|
||||
"resolutionWidth": resolution_width,
|
||||
"resolutionHeight": resolution_height,
|
||||
"pixelAspect": pixel_aspect
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -110,7 +110,15 @@ class CollectReviews(api.InstancePlugin):
|
|||
representation.update({
|
||||
"frameStart": instance.data.get("sourceInH"),
|
||||
"frameEnd": instance.data.get("sourceOutH"),
|
||||
"tags": ["cut-up", "delete"]
|
||||
"tags": ["_cut-bigger", "delete"]
|
||||
})
|
||||
elif media_duration < clip_duration_h:
|
||||
self.log.debug("Media duration higher: {}".format(
|
||||
(media_duration - clip_duration_h)))
|
||||
representation.update({
|
||||
"frameStart": instance.data.get("sourceInH"),
|
||||
"frameEnd": instance.data.get("sourceOutH"),
|
||||
"tags": ["_cut-smaller", "delete"]
|
||||
})
|
||||
|
||||
instance.data["representations"].append(representation)
|
||||
|
|
@ -133,7 +141,7 @@ class CollectReviews(api.InstancePlugin):
|
|||
self.log.debug("__ thumb_path: {}".format(thumb_path))
|
||||
|
||||
thumb_frame = instance.data["sourceIn"] + ((instance.data["sourceOut"] - instance.data["sourceIn"])/2)
|
||||
|
||||
self.log.debug("__ thumb_frame: {}".format(thumb_frame))
|
||||
thumbnail = item.thumbnail(thumb_frame).save(
|
||||
thumb_path,
|
||||
format='png'
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ import pype
|
|||
class ExtractReviewCutUpVideo(pype.api.Extractor):
|
||||
"""Cut up clips from long video file"""
|
||||
|
||||
order = api.ExtractorOrder
|
||||
# order = api.CollectorOrder + 0.1023
|
||||
# order = api.ExtractorOrder
|
||||
order = api.CollectorOrder + 0.1023
|
||||
label = "Extract Review CutUp Video"
|
||||
hosts = ["nukestudio"]
|
||||
families = ["review"]
|
||||
|
|
@ -22,7 +22,16 @@ class ExtractReviewCutUpVideo(pype.api.Extractor):
|
|||
# get representation and loop them
|
||||
representations = inst_data["representations"]
|
||||
|
||||
# resolution data
|
||||
resolution_width = inst_data["resolutionWidth"]
|
||||
resolution_height = inst_data["resolutionHeight"]
|
||||
pixel_aspect = inst_data["pixelAspect"]
|
||||
|
||||
# frame range data
|
||||
media_duration = inst_data["mediaDuration"]
|
||||
|
||||
ffmpeg_path = pype.lib.get_ffmpeg_tool_path("ffmpeg")
|
||||
ffprobe_path = pype.lib.get_ffmpeg_tool_path("ffprobe")
|
||||
|
||||
# filter out mov and img sequences
|
||||
representations_new = representations[:]
|
||||
|
|
@ -32,7 +41,9 @@ class ExtractReviewCutUpVideo(pype.api.Extractor):
|
|||
|
||||
tags = repre.get("tags", [])
|
||||
|
||||
if "cut-up" not in tags:
|
||||
if not next(
|
||||
(t for t in tags
|
||||
if t in ["_cut-bigger", "_cut-smaller"]), None):
|
||||
continue
|
||||
|
||||
self.log.debug("__ repre: {}".format(repre))
|
||||
|
|
@ -49,21 +60,77 @@ class ExtractReviewCutUpVideo(pype.api.Extractor):
|
|||
full_input_path = os.path.join(
|
||||
staging_dir, file)
|
||||
|
||||
full_output_dir = os.path.join(
|
||||
staging_dir, "cuts")
|
||||
|
||||
os.path.isdir(full_output_dir) or os.makedirs(full_output_dir)
|
||||
|
||||
full_output_path = os.path.join(
|
||||
staging_dir, new_file_name)
|
||||
full_output_dir, new_file_name)
|
||||
|
||||
self.log.debug("__ full_input_path: {}".format(full_input_path))
|
||||
self.log.debug("__ full_output_path: {}".format(full_output_path))
|
||||
|
||||
# check if audio stream is in input video file
|
||||
ffprob_cmd = (
|
||||
"{ffprobe_path} -i {full_input_path} -show_streams "
|
||||
"-select_streams a -loglevel error"
|
||||
).format(**locals())
|
||||
self.log.debug("ffprob_cmd: {}".format(ffprob_cmd))
|
||||
audio_check_output = pype.api.subprocess(ffprob_cmd)
|
||||
self.log.debug("audio_check_output: {}".format(audio_check_output))
|
||||
|
||||
# translate frame to sec
|
||||
start_sec = float(frame_start) / fps
|
||||
duration_sec = float(frame_end - frame_start + 1) / fps
|
||||
|
||||
input_args.append("-y")
|
||||
|
||||
if start_sec < 0:
|
||||
audio_empty = ""
|
||||
audio_output = ""
|
||||
audio_layer = ""
|
||||
v_inp_idx = 0
|
||||
black_duration = abs(start_sec)
|
||||
start_sec = 0
|
||||
duration_sec = float(frame_end - (
|
||||
frame_start + (black_duration * fps)) + 1) / fps
|
||||
|
||||
if audio_check_output:
|
||||
# adding input for empty audio
|
||||
input_args.append("-f lavfi -i anullsrc")
|
||||
audio_empty = (
|
||||
"[0]atrim=duration={black_duration}[ga0];"
|
||||
).format(**locals())
|
||||
audio_output = ":a=1"
|
||||
audio_layer = "[ga0]"
|
||||
v_inp_idx = 1
|
||||
|
||||
# adding input for video black frame
|
||||
input_args.append((
|
||||
"-f lavfi -i \"color=c=black:"
|
||||
"s={resolution_width}x{resolution_height}:r={fps}\""
|
||||
).format(**locals()))
|
||||
|
||||
# concutting black frame togather
|
||||
output_args.append((
|
||||
"-filter_complex \""
|
||||
"{audio_empty}"
|
||||
"[{v_inp_idx}]trim=duration={black_duration}[gv0];"
|
||||
"[gv0]{audio_layer}[1:v]"
|
||||
"concat=n=2:v=1{audio_output}\""
|
||||
).format(**locals()))
|
||||
|
||||
input_args.append("-ss {:0.2f}".format(start_sec))
|
||||
input_args.append("-t {:0.2f}".format(duration_sec))
|
||||
input_args.append("-i {}".format(full_input_path))
|
||||
|
||||
start_sec = float(frame_start) / fps
|
||||
input_args.append("-ss {:0.2f}".format(start_sec))
|
||||
# check if not missing frames at the end
|
||||
self.log.debug("media_duration: {}".format(media_duration))
|
||||
self.log.debug("frame_end: {}".format(frame_end))
|
||||
|
||||
output_args.append("-c copy")
|
||||
duration_sec = float(frame_end - frame_start + 1) / fps
|
||||
output_args.append("-t {:0.2f}".format(duration_sec))
|
||||
# make sure it is having no frame to frame comprassion
|
||||
output_args.append("-intra")
|
||||
|
||||
# output filename
|
||||
output_args.append(full_output_path)
|
||||
|
|
@ -90,7 +157,7 @@ class ExtractReviewCutUpVideo(pype.api.Extractor):
|
|||
"step": 1,
|
||||
"fps": fps,
|
||||
"name": "cut_up_preview",
|
||||
"tags": ["cut-up", "review", "delete"] + self.tags_addition,
|
||||
"tags": ["review", "delete"] + self.tags_addition,
|
||||
"ext": ext,
|
||||
"anatomy_template": "publish"
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue