Skip to content
This repository has been archived by the owner on Sep 20, 2024. It is now read-only.

nks cut reference videos #23

Merged
merged 35 commits into from
May 20, 2020
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
0e61a2d
feat(nks): colecting timecodes with otio
Dec 4, 2019
89e5e72
feat(nks): adding media/clip duration to collect frame ranges
Dec 4, 2019
cf01f44
feat(nks): collect review identify if mediaSource needs to be trimed
Dec 4, 2019
128719a
feat(nks): improving calculation of fps
Dec 4, 2019
eff28c1
Merge branch 'develop' into bugfix/ffmpeg_path_burnin_fix
Jan 22, 2020
f394b67
Merge branch 'feature/ffmpeg-devide-long-videos' into feature/PYPE-65…
Jan 22, 2020
aa3bfa6
Merge branch 'feature/nuke_studio_publish_review_cut_ffmpeg' into fea…
Jan 22, 2020
7884097
Merge branch 'develop' into feature/PYPE-654-nks-cut-reference-videos
Mar 19, 2020
bda292a
feat(global): review workflow accepting nks host
Mar 20, 2020
b149388
feat(nks): adding plugin for cutting video parts
Mar 20, 2020
55b3b41
feat(nks): adjusting collect review for cutting
Mar 20, 2020
18f6acc
clean(nks): old way of representation data
Mar 20, 2020
ac9a20c
fix(nks): improving data
Mar 20, 2020
31a7c44
fix(nks): duration method was wrong
Mar 20, 2020
b503870
fix(global): original repre tags are included to preset tags
Mar 20, 2020
06fbbd6
Merge branch 'develop' into feature/PYPE-654-nks-cut-reference-videos
jakubjezek001 May 6, 2020
eba14f8
clean(nks): Hound recomendations
jakubjezek001 May 6, 2020
fdbb6a3
fix(nks): duplicity in hierarchy tag and not matching names clips
jakubjezek001 May 7, 2020
7ac7600
Merge branch 'bugfix/129-nks_coupe_small_fixes' into feature/PYPE-654…
jakubjezek001 May 7, 2020
d4899b6
feat(nks): adding empty black frames at handle start if missing
jakubjezek001 May 11, 2020
a270c55
fix(nks): collect timecodes not used
jakubjezek001 May 12, 2020
7d689cf
feat(nks): reediting shorter or longer clips with empty frames
jakubjezek001 May 12, 2020
8f3f3a4
feat(nks): PR comments
jakubjezek001 May 12, 2020
4342db7
feat(nks): adding comment making more clear the process
jakubjezek001 May 12, 2020
0d7ed78
feat(nks): resolving PR comment
jakubjezek001 May 12, 2020
eb28198
Merge branch 'develop' into feature/PYPE-654-nks-cut-reference-videos
jakubjezek001 May 13, 2020
77d3611
feat(nks): processing PR comments - better readability
jakubjezek001 May 13, 2020
aa0ae99
fix(nks): plugin should be in extract order.. previous was for testing
jakubjezek001 May 13, 2020
cb12a83
feat(nks): only copy codec if source should be shortened
jakubjezek001 May 13, 2020
1581536
fix(global): integrate didn't understand new Anatomy
jakubjezek001 May 13, 2020
f1dd4fc
fix(global): integrate swap order of padding request from anatomy
jakubjezek001 May 13, 2020
59c5f36
fix(nks): frame start was not correctly calculated
jakubjezek001 May 13, 2020
cb42c78
fix(nks): cutting videos added to own folder `cuts`
jakubjezek001 May 13, 2020
5bfafb2
fix(nks): don't add copy codec if -filter_complex added into cmd
jakubjezek001 May 15, 2020
0c5b7b7
Merge branch 'develop' into feature/PYPE-654-nks-cut-reference-videos
jakubjezek001 May 15, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pype/plugins/global/publish/extract_burnin.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class ExtractBurnin(pype.api.Extractor):
label = "Extract burnins"
order = pyblish.api.ExtractorOrder + 0.03
families = ["review", "burnin"]
hosts = ["nuke", "maya", "shell", "premiere"]
hosts = ["nuke", "maya", "shell", "nukestudio", "premiere"]
optional = True

def process(self, instance):
Expand Down Expand Up @@ -193,7 +193,7 @@ def process(self, instance):
self.log.debug("Output: {}".format(output))

repre_update = {
"anatomy_template": "render",
"anatomy_template": repre.get("anatomy_template", "render"),
"files": movieFileBurnin,
"name": repre["name"],
"tags": [x for x in repre["tags"] if x != "delete"]
Expand Down
13 changes: 10 additions & 3 deletions pype/plugins/global/publish/extract_review.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ class ExtractReview(pyblish.api.InstancePlugin):
label = "Extract Review"
order = pyblish.api.ExtractorOrder + 0.02
families = ["review"]
hosts = ["nuke", "maya", "shell", "premiere"]
hosts = ["nuke", "maya", "shell", "nukestudio", "premiere"]

outputs = {}
ext_filter = []
to_width = 1920
to_height = 1080

def process(self, instance):

def process(self, instance):
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'ExtractReview.process' is too complex (40)
too many blank lines (2)

jakubjezek001 marked this conversation as resolved.
Show resolved Hide resolved
output_profiles = self.outputs or {}

inst_data = instance.data
Expand Down Expand Up @@ -82,6 +82,12 @@ def process(self, instance):
repre_new = repre.copy()
ext = profile.get("ext", None)
p_tags = profile.get('tags', [])

# append repre tags into profile tags
for t in tags:
if t not in p_tags:
p_tags.append(t)
iLLiCiTiT marked this conversation as resolved.
Show resolved Hide resolved

self.log.info("p_tags: `{}`".format(p_tags))

# adding control for presets to be sequence
Expand Down Expand Up @@ -175,7 +181,8 @@ def process(self, instance):
frame_start_handle = frame_start - handle_start
frame_end_handle = frame_end + handle_end
if isinstance(repre["files"], list):
if frame_start_handle != repre.get("detectedStart", frame_start_handle):
if frame_start_handle != repre.get(
"detectedStart", frame_start_handle):
frame_start_handle = repre.get("detectedStart")

# exclude handle if no handles defined
Expand Down
3 changes: 1 addition & 2 deletions pype/plugins/nukestudio/publish/collect_clips.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,7 @@ def process(self, context):
"effects": effects,
"sourceIn": int(item.sourceIn()),
"sourceOut": int(item.sourceOut()),
"mediaDuration": (int(item.sourceOut()) -
int(item.sourceIn())) + 1,
"mediaDuration": source.duration(),
"clipIn": int(item.timelineIn()),
"clipOut": int(item.timelineOut()),
"clipDuration": (
Expand Down
21 changes: 12 additions & 9 deletions pype/plugins/nukestudio/publish/collect_frame_ranges.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,18 @@ def process(self, instance):
frame_start = timeline_in

frame_end = frame_start + (timeline_out - timeline_in)

data.update(
{
"sourceInH": source_in_h,
"sourceOutH": source_out_h,
"frameStart": frame_start,
"frameEnd": frame_end,
"clipInH": timeline_in_h,
"clipOutH": timeline_out_h
source = instance.data.get("source")

data.update({
"sourceFirst": source_in_h,
"sourceInH": source_in_h,
"sourceOutH": source_out_h,
"frameStart": frame_start,
"frameEnd": frame_end,
"clipInH": timeline_in_h,
"clipOutH": timeline_out_h,
"clipDurationH": instance.data.get(
"clipDuration") + handle_start + handle_end
}
)
self.log.debug("__ data: {}".format(data))
Expand Down
12 changes: 11 additions & 1 deletion pype/plugins/nukestudio/publish/collect_framerate.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from pyblish import api


class CollectFramerate(api.ContextPlugin):
"""Collect framerate from selected sequence."""

Expand All @@ -9,4 +10,13 @@ class CollectFramerate(api.ContextPlugin):

def process(self, context):
sequence = context.data["activeSequence"]
context.data["fps"] = sequence.framerate().toFloat()
context.data["fps"] = self.get_rate(sequence)

def get_rate(self, sequence):
num, den = sequence.framerate().toRational()
rate = float(num) / float(den)

if rate.is_integer():
return rate

return round(rate, 3)
3 changes: 1 addition & 2 deletions pype/plugins/nukestudio/publish/collect_plates.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,7 @@ def process(self, instance):
"frameEnd": instance.data["sourceOut"] - instance.data["sourceIn"] + 1,
'step': 1,
'fps': instance.context.data["fps"],
'preview': True,
'thumbnail': False,
'tags': ["preview"],
'name': "preview",
'ext': "mov",
}
Expand Down
22 changes: 16 additions & 6 deletions pype/plugins/nukestudio/publish/collect_reviews.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,6 @@ def process(self, instance):
file_dir = os.path.dirname(file_path)
file = os.path.basename(file_path)
ext = os.path.splitext(file)[-1][1:]
handleStart = rev_inst.data.get("handleStart")
handleEnd = rev_inst.data.get("handleEnd")

# change label
instance.data["label"] = "{0} - {1} - ({2}) - review".format(
Expand All @@ -94,15 +92,27 @@ def process(self, instance):
"stagingDir": file_dir,
"frameStart": rev_inst.data.get("sourceIn"),
"frameEnd": rev_inst.data.get("sourceOut"),
"frameStartFtrack": rev_inst.data.get("sourceIn") - handleStart,
"frameEndFtrack": rev_inst.data.get("sourceOut") + handleEnd,
"frameStartFtrack": rev_inst.data.get("sourceInH"),
"frameEndFtrack": rev_inst.data.get("sourceOutH"),
"step": 1,
"fps": rev_inst.data.get("fps"),
"preview": True,
"thumbnail": False,
"name": "preview",
"tags": ["preview"],
"ext": ext
}

media_duration = instance.data.get("mediaDuration")
clip_duration_h = instance.data.get("clipDurationH")

if 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-up", "delete"]
})

instance.data["representations"].append(representation)

self.log.debug("Added representation: {}".format(representation))
Expand Down
88 changes: 88 additions & 0 deletions pype/plugins/nukestudio/publish/collect_timecodes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import pyblish.api
import opentimelineio.opentime as otio_ot


class CollectClipTimecodes(pyblish.api.InstancePlugin):
"""Collect time with OpenTimelineIO: source_h(In,Out)[timecode, sec], timeline(In,Out)[timecode, sec]"""

order = pyblish.api.CollectorOrder + 0.101
label = "Collect Timecodes"
hosts = ["nukestudio"]

def process(self, instance):

data = dict()
self.log.debug("__ instance.data: {}".format(instance.data))
# Timeline data.
handle_start = instance.data["handleStart"]
handle_end = instance.data["handleEnd"]

source_in_h = instance.data("sourceInH",
instance.data("sourceIn") - handle_start)
source_out_h = instance.data("sourceOutH",
instance.data("sourceOut") + handle_end)

timeline_in = instance.data["clipIn"]
timeline_out = instance.data["clipOut"]

# set frame start with tag or take it from timeline
frame_start = instance.data.get("startingFrame")

if not frame_start:
frame_start = timeline_in

source = instance.data.get("source")

otio_data = dict()
self.log.debug("__ source: `{}`".format(source))

rate_fps = instance.context.data["fps"]

otio_in_h_ratio = otio_ot.RationalTime(
value=(source.timecodeStart() + (
source_in_h + (source_out_h - source_in_h))),
rate=rate_fps)

otio_out_h_ratio = otio_ot.RationalTime(
value=(source.timecodeStart() + source_in_h),
rate=rate_fps)

otio_timeline_in_ratio = otio_ot.RationalTime(
value=int(
instance.data.get("timelineTimecodeStart", 0)) + timeline_in,
rate=rate_fps)

otio_timeline_out_ratio = otio_ot.RationalTime(
value=int(
instance.data.get("timelineTimecodeStart", 0)) + timeline_out,
rate=rate_fps)

otio_data.update({

"otioClipInHTimecode": otio_ot.to_timecode(otio_in_h_ratio),

"otioClipOutHTimecode": otio_ot.to_timecode(otio_out_h_ratio),

"otioClipInHSec": otio_ot.to_seconds(otio_in_h_ratio),

"otioClipOutHSec": otio_ot.to_seconds(otio_out_h_ratio),

"otioTimelineInTimecode": otio_ot.to_timecode(
otio_timeline_in_ratio),

"otioTimelineOutTimecode": otio_ot.to_timecode(
otio_timeline_out_ratio),

"otioTimelineInSec": otio_ot.to_seconds(otio_timeline_in_ratio),

"otioTimelineOutSec": otio_ot.to_seconds(otio_timeline_out_ratio)
})

data.update({
"otioData": otio_data,
"sourceTimecodeIn": otio_ot.to_timecode(otio_in_h_ratio),
"sourceTimecodeOut": otio_ot.to_timecode(otio_out_h_ratio),
}
)
instance.data.update(data)
self.log.debug("data: {}".format(instance.data))
107 changes: 107 additions & 0 deletions pype/plugins/nukestudio/publish/extract_review_cutup_video.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import os
from pyblish import api
import pype


class ExtractReviewCutUpVideo(pype.api.Extractor):
"""Cut up clips from long video file"""

order = api.ExtractorOrder
# order = api.CollectorOrder + 0.1023
label = "Extract Review CutUp Video"
hosts = ["nukestudio"]
families = ["review"]

# presets
tags_addition = []

def process(self, instance):
inst_data = instance.data
asset = inst_data['asset']

# get representation and loop them
representations = inst_data["representations"]

ffmpeg_path = pype.lib.get_ffmpeg_tool_path("ffmpeg")

# filter out mov and img sequences
representations_new = representations[:]
for repre in representations:
input_args = list()
output_args = list()

tags = repre.get("tags", [])

if "cut-up" not in tags:
continue

self.log.debug("__ repre: {}".format(repre))

file = repre.get("files")
staging_dir = repre.get("stagingDir")
frame_start = repre.get("frameStart")
frame_end = repre.get("frameEnd")
fps = repre.get("fps")
ext = repre.get("ext")

new_file_name = "{}_{}".format(asset, file)

full_input_path = os.path.join(
staging_dir, file)

full_output_path = os.path.join(
staging_dir, new_file_name)

self.log.debug("__ full_input_path: {}".format(full_input_path))
self.log.debug("__ full_output_path: {}".format(full_output_path))

input_args.append("-y")
input_args.append("-i {}".format(full_input_path))

start_sec = float(frame_start) / fps
input_args.append("-ss {:0.2f}".format(start_sec))

output_args.append("-c copy")
duration_sec = float(frame_end - frame_start + 1) / fps
output_args.append("-t {:0.2f}".format(duration_sec))

# output filename
output_args.append(full_output_path)

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))

repre_new = {
"files": new_file_name,
"stagingDir": staging_dir,
"frameStart": frame_start,
"frameEnd": frame_end,
"frameStartFtrack": frame_start,
"frameEndFtrack": frame_end,
"step": 1,
"fps": fps,
"name": "cut_up_preview",
"tags": ["cut-up", "review", "delete"] + self.tags_addition,
"ext": ext,
"anatomy_template": "publish"
}

representations_new.append(repre_new)

for repre in representations_new:
if ("delete" in repre.get("tags", [])) and (
"cut_up_preview" not in repre["name"]):
representations_new.remove(repre)

self.log.debug(
"new representations: {}".format(representations_new))
instance.data["representations"] = representations_new