Merge branch 'develop' into feature/add_pyblish_debug_stepper_to_exprimental_tools

This commit is contained in:
Jakub Trllo 2024-10-09 10:51:47 +02:00 committed by GitHub
commit 4aea1c9170
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
42 changed files with 7955 additions and 490 deletions

View file

@ -1,6 +1,6 @@
name: Bug Report
description: File a bug report
title: 'Your issue title here'
title: Your issue title here
labels:
- 'type: bug'
body:
@ -36,6 +36,16 @@ body:
description: What version are you running? Look to AYON Tray
options:
- 1.0.0
- 0.4.4
- 0.4.3
- 0.4.2
- 0.4.1
- 0.4.0
- 0.3.2
- 0.3.1
- 0.3.0
- 0.2.1
- 0.2.0
validations:
required: true
- type: dropdown

View file

@ -28,7 +28,8 @@ class AddLastWorkfileToLaunchArgs(PreLaunchHook):
"substancepainter",
"aftereffects",
"wrap",
"openrv"
"openrv",
"cinema4d"
}
launch_types = {LaunchTypes.local}

View file

@ -4,6 +4,7 @@ import collections
import uuid
import json
import copy
import warnings
from abc import ABCMeta, abstractmethod
import clique
@ -90,6 +91,30 @@ class AbstractAttrDefMeta(ABCMeta):
return obj
def _convert_reversed_attr(
main_value, depr_value, main_label, depr_label, default
):
if main_value is not None and depr_value is not None:
if main_value == depr_value:
print(
f"Got invalid '{main_label}' and '{depr_label}' arguments."
f" Using '{main_label}' value."
)
elif depr_value is not None:
warnings.warn(
(
"DEPRECATION WARNING: Using deprecated argument"
f" '{depr_label}' please use '{main_label}' instead."
),
DeprecationWarning,
stacklevel=4,
)
main_value = not depr_value
elif main_value is None:
main_value = default
return main_value
class AbstractAttrDef(metaclass=AbstractAttrDefMeta):
"""Abstraction of attribute definition.
@ -106,12 +131,14 @@ class AbstractAttrDef(metaclass=AbstractAttrDefMeta):
Args:
key (str): Under which key will be attribute value stored.
default (Any): Default value of an attribute.
label (str): Attribute label.
tooltip (str): Attribute tooltip.
is_label_horizontal (bool): UI specific argument. Specify if label is
next to value input or ahead.
hidden (bool): Will be item hidden (for UI purposes).
disabled (bool): Item will be visible but disabled (for UI purposes).
label (Optional[str]): Attribute label.
tooltip (Optional[str]): Attribute tooltip.
is_label_horizontal (Optional[bool]): UI specific argument. Specify
if label is next to value input or ahead.
visible (Optional[bool]): Item is shown to user (for UI purposes).
enabled (Optional[bool]): Item is enabled (for UI purposes).
hidden (Optional[bool]): DEPRECATED: Use 'visible' instead.
disabled (Optional[bool]): DEPRECATED: Use 'enabled' instead.
"""
type_attributes = []
@ -125,22 +152,28 @@ class AbstractAttrDef(metaclass=AbstractAttrDefMeta):
label=None,
tooltip=None,
is_label_horizontal=None,
hidden=False,
disabled=False
visible=None,
enabled=None,
hidden=None,
disabled=None,
):
if is_label_horizontal is None:
is_label_horizontal = True
if hidden is None:
hidden = False
enabled = _convert_reversed_attr(
enabled, disabled, "enabled", "disabled", True
)
visible = _convert_reversed_attr(
visible, hidden, "visible", "hidden", True
)
self.key = key
self.label = label
self.tooltip = tooltip
self.default = default
self.is_label_horizontal = is_label_horizontal
self.hidden = hidden
self.disabled = disabled
self.visible = visible
self.enabled = enabled
self._id = uuid.uuid4().hex
self.__init__class__ = AbstractAttrDef
@ -149,14 +182,30 @@ class AbstractAttrDef(metaclass=AbstractAttrDefMeta):
def id(self):
return self._id
@property
def hidden(self):
return not self.visible
@hidden.setter
def hidden(self, value):
self.visible = not value
@property
def disabled(self):
return not self.enabled
@disabled.setter
def disabled(self, value):
self.enabled = not value
def __eq__(self, other):
if not isinstance(other, self.__class__):
return False
return (
self.key == other.key
and self.hidden == other.hidden
and self.default == other.default
and self.disabled == other.disabled
and self.visible == other.visible
and self.enabled == other.enabled
)
def __ne__(self, other):
@ -198,8 +247,8 @@ class AbstractAttrDef(metaclass=AbstractAttrDefMeta):
"tooltip": self.tooltip,
"default": self.default,
"is_label_horizontal": self.is_label_horizontal,
"hidden": self.hidden,
"disabled": self.disabled
"visible": self.visible,
"enabled": self.enabled
}
for attr in self.type_attributes:
data[attr] = getattr(self, attr)
@ -279,8 +328,8 @@ class HiddenDef(AbstractAttrDef):
def __init__(self, key, default=None, **kwargs):
kwargs["default"] = default
kwargs["hidden"] = True
super(HiddenDef, self).__init__(key, **kwargs)
kwargs["visible"] = False
super().__init__(key, **kwargs)
def convert_value(self, value):
return value

View file

@ -1152,9 +1152,7 @@ def convert_colorspace(
input_arg, input_path,
# Tell oiiotool which channels should be put to top stack
# (and output)
"--ch", channels_arg,
# Use first subimage
"--subimage", "0"
"--ch", channels_arg
])
if all([target_colorspace, view, display]):
@ -1168,12 +1166,12 @@ def convert_colorspace(
oiio_cmd.extend(additional_command_args)
if target_colorspace:
oiio_cmd.extend(["--colorconvert",
oiio_cmd.extend(["--colorconvert:subimages=0",
source_colorspace,
target_colorspace])
if view and display:
oiio_cmd.extend(["--iscolorspace", source_colorspace])
oiio_cmd.extend(["--ociodisplay", display, view])
oiio_cmd.extend(["--ociodisplay:subimages=0", display, view])
oiio_cmd.extend(["-o", output_path])

View file

@ -699,6 +699,34 @@ def get_ocio_config_views(config_path):
)
def _get_config_path_from_profile_data(
profile, profile_type, template_data
):
"""Get config path from profile data.
Args:
profile (dict[str, Any]): Profile data.
profile_type (str): Profile type.
template_data (dict[str, Any]): Template data.
Returns:
dict[str, str]: Config data with path and template.
"""
template = profile[profile_type]
result = StringTemplate.format_strict_template(
template, template_data
)
normalized_path = str(result.normalized())
if not os.path.exists(normalized_path):
log.warning(f"Path was not found '{normalized_path}'.")
return None
return {
"path": normalized_path,
"template": template
}
def _get_global_config_data(
project_name,
host_name,
@ -717,7 +745,7 @@ def _get_global_config_data(
2. Custom path to ocio config.
3. Path to 'ocioconfig' representation on product. Name of product can be
defined in settings. Product name can be regex but exact match is
always preferred.
always preferred. Fallback can be defined in case no product is found.
None is returned when no profile is found, when path
@ -755,30 +783,36 @@ def _get_global_config_data(
profile_type = profile["type"]
if profile_type in ("builtin_path", "custom_path"):
template = profile[profile_type]
result = StringTemplate.format_strict_template(
template, template_data
)
normalized_path = str(result.normalized())
if not os.path.exists(normalized_path):
log.warning(f"Path was not found '{normalized_path}'.")
return None
return {
"path": normalized_path,
"template": template
}
return _get_config_path_from_profile_data(
profile, profile_type, template_data)
# TODO decide if this is the right name for representation
repre_name = "ocioconfig"
published_product_data = profile["published_product"]
product_name = published_product_data["product_name"]
fallback_data = published_product_data["fallback"]
if product_name == "":
log.error(
"Colorspace OCIO config path cannot be set. "
"Profile is set to published product but `Product name` is empty."
)
return None
folder_info = template_data.get("folder")
if not folder_info:
log.warning("Folder info is missing.")
return None
log.info("Using fallback data for ocio config path.")
# in case no product was found we need to use fallback
fallback_type = fallback_data["fallback_type"]
return _get_config_path_from_profile_data(
fallback_data, fallback_type, template_data
)
folder_path = folder_info["path"]
product_name = profile["product_name"]
if folder_id is None:
folder_entity = ayon_api.get_folder_by_path(
project_name, folder_path, fields={"id"}
@ -797,12 +831,13 @@ def _get_global_config_data(
fields={"id", "name"}
)
}
if not product_entities_by_name:
log.debug(
f"No product entities were found for folder '{folder_path}' with"
f" product name filter '{product_name}'."
# in case no product was found we need to use fallback
fallback_type = fallback_data["type"]
return _get_config_path_from_profile_data(
fallback_data, fallback_type, template_data
)
return None
# Try to use exact match first, otherwise use first available product
product_entity = product_entities_by_name.get(product_name)
@ -837,6 +872,7 @@ def _get_global_config_data(
path = get_representation_path_with_anatomy(repre_entity, anatomy)
template = repre_entity["attrib"]["template"]
return {
"path": path,
"template": template,

View file

@ -132,7 +132,10 @@ def install_host(host):
def modified_emit(obj, record):
"""Method replacing `emit` in Pyblish's MessageHandler."""
record.msg = record.getMessage()
try:
record.msg = record.getMessage()
except Exception:
record.msg = str(record.msg)
obj.records.append(record)
MessageHandler.emit = modified_emit

View file

@ -88,7 +88,7 @@ def trim_media_range(media_range, source_range):
"""
rw_media_start = _ot.RationalTime(
media_range.start_time.value + source_range.start_time.value,
source_range.start_time.value,
media_range.start_time.rate
)
rw_media_duration = _ot.RationalTime(
@ -173,11 +173,145 @@ def _sequence_resize(source, length):
yield (1 - ratio) * source[int(low)] + ratio * source[int(high)]
def is_clip_from_media_sequence(otio_clip):
"""
Args:
otio_clip (otio.schema.Clip): The OTIO clip to check.
Returns:
bool. Is the provided clip from an input media sequence ?
"""
media_ref = otio_clip.media_reference
metadata = media_ref.metadata
# OpenTimelineIO 0.13 and newer
is_input_sequence = (
hasattr(otio.schema, "ImageSequenceReference") and
isinstance(media_ref, otio.schema.ImageSequenceReference)
)
# OpenTimelineIO 0.12 and older
is_input_sequence_legacy = bool(metadata.get("padding"))
return is_input_sequence or is_input_sequence_legacy
def remap_range_on_file_sequence(otio_clip, in_out_range):
"""
Args:
otio_clip (otio.schema.Clip): The OTIO clip to check.
in_out_range (tuple[float, float]): The in-out range to remap.
Returns:
tuple(int, int): The remapped range as discrete frame number.
Raises:
ValueError. When the otio_clip or provided range is invalid.
"""
if not is_clip_from_media_sequence(otio_clip):
raise ValueError(f"Cannot map on non-file sequence clip {otio_clip}.")
try:
media_in_trimmed, media_out_trimmed = in_out_range
except ValueError as error:
raise ValueError("Invalid in_out_range provided.") from error
media_ref = otio_clip.media_reference
available_range = otio_clip.available_range()
source_range = otio_clip.source_range
available_range_rate = available_range.start_time.rate
media_in = available_range.start_time.value
# Temporary.
# Some AYON custom OTIO exporter were implemented with relative
# source range for image sequence. Following code maintain
# backward-compatibility by adjusting media_in
# while we are updating those.
if (
is_clip_from_media_sequence(otio_clip)
and otio_clip.available_range().start_time.to_frames() == media_ref.start_frame
and source_range.start_time.to_frames() < media_ref.start_frame
):
media_in = 0
frame_in = otio.opentime.RationalTime.from_frames(
media_in_trimmed - media_in + media_ref.start_frame,
rate=available_range_rate,
).to_frames()
frame_out = otio.opentime.RationalTime.from_frames(
media_out_trimmed - media_in + media_ref.start_frame,
rate=available_range_rate,
).to_frames()
return frame_in, frame_out
def get_media_range_with_retimes(otio_clip, handle_start, handle_end):
source_range = otio_clip.source_range
available_range = otio_clip.available_range()
media_in = available_range.start_time.value
media_out = available_range.end_time_inclusive().value
available_range_rate = available_range.start_time.rate
# If media source is an image sequence, returned
# mediaIn/mediaOut have to correspond
# to frame numbers from source sequence.
media_ref = otio_clip.media_reference
is_input_sequence = is_clip_from_media_sequence(otio_clip)
# Temporary.
# Some AYON custom OTIO exporter were implemented with relative
# source range for image sequence. Following code maintain
# backward-compatibility by adjusting available range
# while we are updating those.
if (
is_input_sequence
and available_range.start_time.to_frames() == media_ref.start_frame
and source_range.start_time.to_frames() < media_ref.start_frame
):
available_range = _ot.TimeRange(
_ot.RationalTime(0, rate=available_range_rate),
available_range.duration,
)
# Conform source range bounds to available range rate
# .e.g. embedded TC of (3600 sec/ 1h), duration 100 frames
#
# available |----------------------------------------| 24fps
# 86400 86500
#
#
# 90010 90060
# src |-----|______duration 2s___|----| 25fps
# 90000
#
#
# 86409.6 86466.8
# conformed |-------|_____duration _2.38s____|-------| 24fps
# 86400
#
# Note that 24fps is slower than 25fps hence extended duration
# to preserve media range
# Compute new source range based on available rate.
# Backward-compatibility for Hiero OTIO exporter.
# NTSC compatibility might introduce floating rates, when these are
# not exactly the same (23.976 vs 23.976024627685547)
# this will cause precision issue in computation.
# Currently round to 2 decimals for comparison,
# but this should always rescale after that.
rounded_av_rate = round(available_range_rate, 2)
rounded_src_rate = round(source_range.start_time.rate, 2)
if rounded_av_rate != rounded_src_rate:
conformed_src_in = source_range.start_time.rescaled_to(available_range_rate)
conformed_src_duration = source_range.duration.rescaled_to(available_range_rate)
conformed_source_range = otio.opentime.TimeRange(
start_time=conformed_src_in,
duration=conformed_src_duration
)
else:
conformed_source_range = source_range
# modifiers
time_scalar = 1.
@ -224,38 +358,51 @@ def get_media_range_with_retimes(otio_clip, handle_start, handle_end):
offset_in *= time_scalar
offset_out *= time_scalar
# filip offset if reversed speed
if time_scalar < 0:
_offset_in = offset_out
_offset_out = offset_in
offset_in = _offset_in
offset_out = _offset_out
# scale handles
handle_start *= abs(time_scalar)
handle_end *= abs(time_scalar)
# filip handles if reversed speed
# flip offset and handles if reversed speed
if time_scalar < 0:
_handle_start = handle_end
_handle_end = handle_start
handle_start = _handle_start
handle_end = _handle_end
offset_in, offset_out = offset_out, offset_in
handle_start, handle_end = handle_end, handle_start
source_in = source_range.start_time.value
# compute retimed range
media_in_trimmed = conformed_source_range.start_time.value + offset_in
media_out_trimmed = media_in_trimmed + (
(
conformed_source_range.duration.value
* abs(time_scalar)
+ offset_out
) - 1
)
media_in_trimmed = (
media_in + source_in + offset_in)
media_out_trimmed = (
media_in + source_in + (
((source_range.duration.value - 1) * abs(
time_scalar)) + offset_out))
media_in = available_range.start_time.value
media_out = available_range.end_time_inclusive().value
# calculate available handles
# If media source is an image sequence, returned
# mediaIn/mediaOut have to correspond
# to frame numbers from source sequence.
if is_input_sequence:
# preserve discrete frame numbers
media_in_trimmed, media_out_trimmed = remap_range_on_file_sequence(
otio_clip,
(media_in_trimmed, media_out_trimmed)
)
media_in = media_ref.start_frame
media_out = media_in + available_range.duration.to_frames() - 1
# adjust available handles if needed
if (media_in_trimmed - media_in) < handle_start:
handle_start = (media_in_trimmed - media_in)
handle_start = max(0, media_in_trimmed - media_in)
if (media_out - media_out_trimmed) < handle_end:
handle_end = (media_out - media_out_trimmed)
handle_end = max(0, media_out - media_out_trimmed)
# FFmpeg extraction ignores embedded timecode
# so substract to get a (mediaIn-mediaOut) range from 0.
if not is_input_sequence:
media_in_trimmed -= media_in
media_out_trimmed -= media_in
# create version data
version_data = {
@ -263,16 +410,16 @@ def get_media_range_with_retimes(otio_clip, handle_start, handle_end):
"retime": True,
"speed": time_scalar,
"timewarps": time_warp_nodes,
"handleStart": int(round(handle_start)),
"handleEnd": int(round(handle_end))
"handleStart": int(handle_start),
"handleEnd": int(handle_end)
}
}
returning_dict = {
"mediaIn": media_in_trimmed,
"mediaOut": media_out_trimmed,
"handleStart": int(round(handle_start)),
"handleEnd": int(round(handle_end)),
"handleStart": int(handle_start),
"handleEnd": int(handle_end),
"speed": time_scalar
}

View file

@ -242,6 +242,26 @@ class LoaderPlugin(list):
if hasattr(self, "_fname"):
return self._fname
@classmethod
def get_representation_name_aliases(cls, representation_name: str):
"""Return representation names to which switching is allowed from
the input representation name, like an alias replacement of the input
`representation_name`.
For example, to allow an automated switch on update from representation
`ma` to `mb` or `abc`, then when `representation_name` is `ma` return:
["mb", "abc"]
The order of the names in the returned representation names is
important, because the first one existing under the new version will
be chosen.
Returns:
List[str]: Representation names switching to is allowed on update
if the input representation name is not found on the new version.
"""
return []
class ProductLoaderPlugin(LoaderPlugin):
"""Load product into host application

View file

@ -505,21 +505,6 @@ def update_container(container, version=-1):
project_name, product_entity["folderId"]
)
repre_name = current_representation["name"]
new_representation = ayon_api.get_representation_by_name(
project_name, repre_name, new_version["id"]
)
if new_representation is None:
raise ValueError(
"Representation '{}' wasn't found on requested version".format(
repre_name
)
)
path = get_representation_path(new_representation)
if not path or not os.path.exists(path):
raise ValueError("Path {} doesn't exist".format(path))
# Run update on the Loader for this container
Loader = _get_container_loader(container)
if not Loader:
@ -527,6 +512,39 @@ def update_container(container, version=-1):
"Can't update container because loader '{}' was not found."
.format(container.get("loader"))
)
repre_name = current_representation["name"]
new_representation = ayon_api.get_representation_by_name(
project_name, repre_name, new_version["id"]
)
if new_representation is None:
# The representation name is not found in the new version.
# Allow updating to a 'matching' representation if the loader
# has defined compatible update conversions
repre_name_aliases = Loader.get_representation_name_aliases(repre_name)
if repre_name_aliases:
representations = ayon_api.get_representations(
project_name,
representation_names=repre_name_aliases,
version_ids=[new_version["id"]])
representations_by_name = {
repre["name"]: repre for repre in representations
}
for name in repre_name_aliases:
if name in representations_by_name:
new_representation = representations_by_name[name]
break
if new_representation is None:
raise ValueError(
"Representation '{}' wasn't found on requested version".format(
repre_name
)
)
path = get_representation_path(new_representation)
if not path or not os.path.exists(path):
raise ValueError("Path {} doesn't exist".format(path))
project_entity = ayon_api.get_project(project_name)
context = {
"project": project_entity,

View file

@ -506,55 +506,61 @@ class AbstractTemplateBuilder(ABC):
keep_placeholders (bool): Add flag to placeholder data for
hosts to decide if they want to remove
placeholder after it is used.
create_first_version (bool): create first version of a workfile
workfile_creation_enabled (bool): If True, it might create
first version but ignore
process if version is created
create_first_version (bool): Create first version of a workfile.
When set to True, this option initiates the saving of the
workfile for an initial version. It will skip saving if
a version already exists.
workfile_creation_enabled (bool): Whether the call is part of
creating a new workfile.
When True, we only build if the current file is not
an existing saved workfile but a "new" file. Basically when
enabled we assume the user tries to load it only into a
"New File" (unsaved empty workfile).
When False, the default value, we assume we explicitly want to
build the template in our current scene regardless of current
scene state.
"""
if any(
value is None
for value in [
template_path,
keep_placeholders,
create_first_version,
]
):
template_preset = self.get_template_preset()
if template_path is None:
template_path = template_preset["path"]
if keep_placeholders is None:
keep_placeholders = template_preset["keep_placeholder"]
if create_first_version is None:
create_first_version = template_preset["create_first_version"]
# More accurate variable name
# - logic related to workfile creation should be moved out in future
explicit_build_requested = not workfile_creation_enabled
# check if first version is created
created_version_workfile = False
if create_first_version:
created_version_workfile = self.create_first_workfile_version()
# if first version is created, import template
# and populate placeholders
# Get default values if not provided
if (
create_first_version
and workfile_creation_enabled
and created_version_workfile
template_path is None
or keep_placeholders is None
or create_first_version is None
):
preset = self.get_template_preset()
template_path: str = template_path or preset["path"]
if keep_placeholders is None:
keep_placeholders: bool = preset["keep_placeholder"]
if create_first_version is None:
create_first_version: bool = preset["create_first_version"]
# Build the template if we are explicitly requesting it or if it's
# an unsaved "new file".
is_new_file = not self.host.get_current_workfile()
if is_new_file or explicit_build_requested:
self.log.info(f"Building the workfile template: {template_path}")
self.import_template(template_path)
self.populate_scene_placeholders(
level_limit, keep_placeholders)
# save workfile after template is populated
self.save_workfile(created_version_workfile)
# ignore process if first workfile is enabled
# but a version is already created
if workfile_creation_enabled:
# Do not consider saving a first workfile version, if this is not set
# to be a "workfile creation" or `create_first_version` is disabled.
if explicit_build_requested or not create_first_version:
return
self.import_template(template_path)
self.populate_scene_placeholders(
level_limit, keep_placeholders)
# If there is no existing workfile, save the first version
workfile_path = self.get_workfile_path()
if not os.path.exists(workfile_path):
self.log.info("Saving first workfile: %s", workfile_path)
self.save_workfile(workfile_path)
else:
self.log.info(
"A workfile already exists. Skipping save of workfile as "
"initial version.")
def rebuild_template(self):
"""Go through existing placeholders in scene and update them.
@ -608,29 +614,16 @@ class AbstractTemplateBuilder(ABC):
pass
def create_first_workfile_version(self):
"""
Create first version of workfile.
def get_workfile_path(self):
"""Return last known workfile path or the first workfile path create.
Should load the content of template into scene so
'populate_scene_placeholders' can be started.
Args:
template_path (str): Fullpath for current task and
host's template file.
Return:
str: Last workfile path, or first version to create if none exist.
"""
# AYON_LAST_WORKFILE will be set to the last existing workfile OR
# if none exist it will be set to the first version.
last_workfile_path = os.environ.get("AYON_LAST_WORKFILE")
self.log.info("__ last_workfile_path: {}".format(last_workfile_path))
if os.path.exists(last_workfile_path):
# ignore in case workfile existence
self.log.info("Workfile already exists, skipping creation.")
return False
# Create first version
self.log.info("Creating first version of workfile.")
self.save_workfile(last_workfile_path)
# Confirm creation of first version
return last_workfile_path
def save_workfile(self, workfile_path):

View file

@ -57,11 +57,12 @@ class ExtractOTIOReview(publish.Extractor):
# Not all hosts can import these modules.
import opentimelineio as otio
from ayon_core.pipeline.editorial import (
otio_range_to_frame_range,
make_sequence_collection
make_sequence_collection,
remap_range_on_file_sequence,
is_clip_from_media_sequence
)
# TODO refactore from using instance variable
# TODO refactor from using instance variable
self.temp_file_head = self._get_folder_name_based_prefix(instance)
# TODO: convert resulting image sequence to mp4
@ -73,8 +74,8 @@ class ExtractOTIOReview(publish.Extractor):
otio_review_clips = instance.data["otioReviewClips"]
# add plugin wide attributes
self.representation_files = list()
self.used_frames = list()
self.representation_files = []
self.used_frames = []
self.workfile_start = int(instance.data.get(
"workfileFrameStart", 1001)) - handle_start
self.padding = len(str(self.workfile_start))
@ -99,93 +100,110 @@ class ExtractOTIOReview(publish.Extractor):
for index, r_otio_cl in enumerate(otio_review_clips):
# QUESTION: what if transition on clip?
# check if resolution is the same
width = self.to_width
height = self.to_height
otio_media = r_otio_cl.media_reference
media_metadata = otio_media.metadata
# get from media reference metadata source
# TODO 'openpype' prefix should be removed (added 24/09/03)
# NOTE it looks like it is set only in hiero integration
for key in {"ayon.source.width", "openpype.source.width"}:
value = media_metadata.get(key)
if value is not None:
width = int(value)
break
for key in {"ayon.source.height", "openpype.source.height"}:
value = media_metadata.get(key)
if value is not None:
height = int(value)
break
# compare and reset
if width != self.to_width:
self.to_width = width
if height != self.to_height:
self.to_height = height
self.log.debug("> self.to_width x self.to_height: {} x {}".format(
self.to_width, self.to_height
))
# get frame range values
# Clip: compute process range from available media range.
src_range = r_otio_cl.source_range
start = src_range.start_time.value
duration = src_range.duration.value
available_range = None
self.actual_fps = src_range.duration.rate
# add available range only if not gap
if isinstance(r_otio_cl, otio.schema.Clip):
# check if resolution is the same as source
media_ref = r_otio_cl.media_reference
media_metadata = media_ref.metadata
# get from media reference metadata source
# TODO 'openpype' prefix should be removed (added 24/09/03)
# NOTE it looks like it is set only in hiero integration
res_data = {"width": self.to_width, "height": self.to_height}
for key in res_data:
for meta_prefix in ("ayon.source.", "openpype.source."):
meta_key = f"{meta_prefix}.{key}"
value = media_metadata.get(meta_key)
if value is not None:
res_data[key] = value
break
self.to_width, self.to_height = res_data["width"], res_data["height"]
self.log.debug("> self.to_width x self.to_height: {} x {}".format(
self.to_width, self.to_height
))
available_range = r_otio_cl.available_range()
processing_range = None
self.actual_fps = available_range.duration.rate
start = src_range.start_time.rescaled_to(self.actual_fps)
duration = src_range.duration.rescaled_to(self.actual_fps)
# Temporary.
# Some AYON custom OTIO exporter were implemented with relative
# source range for image sequence. Following code maintain
# backward-compatibility by adjusting available range
# while we are updating those.
if (
is_clip_from_media_sequence(r_otio_cl)
and available_range.start_time.to_frames() == media_ref.start_frame
and src_range.start_time.to_frames() < media_ref.start_frame
):
available_range = otio.opentime.TimeRange(
otio.opentime.RationalTime(0, rate=self.actual_fps),
available_range.duration,
)
# Gap: no media, generate range based on source range
else:
available_range = processing_range = None
self.actual_fps = src_range.duration.rate
start = src_range.start_time
duration = src_range.duration
# Create handle offsets.
clip_handle_start = otio.opentime.RationalTime(
handle_start,
rate=self.actual_fps,
)
clip_handle_end = otio.opentime.RationalTime(
handle_end,
rate=self.actual_fps,
)
# reframing handles conditions
if (len(otio_review_clips) > 1) and (index == 0):
# more clips | first clip reframing with handle
start -= handle_start
duration += handle_start
start -= clip_handle_start
duration += clip_handle_start
elif len(otio_review_clips) > 1 \
and (index == len(otio_review_clips) - 1):
# more clips | last clip reframing with handle
duration += handle_end
duration += clip_handle_end
elif len(otio_review_clips) == 1:
# one clip | add both handles
start -= handle_start
duration += (handle_start + handle_end)
start -= clip_handle_start
duration += (clip_handle_start + clip_handle_end)
if available_range:
available_range = self._trim_available_range(
available_range, start, duration, self.actual_fps)
processing_range = self._trim_available_range(
available_range, start, duration)
# process all track items of the track
if isinstance(r_otio_cl, otio.schema.Clip):
# process Clip
media_ref = r_otio_cl.media_reference
metadata = media_ref.metadata
is_sequence = None
# check in two way if it is sequence
if hasattr(otio.schema, "ImageSequenceReference"):
# for OpenTimelineIO 0.13 and newer
if isinstance(media_ref,
otio.schema.ImageSequenceReference):
is_sequence = True
else:
# for OpenTimelineIO 0.12 and older
if metadata.get("padding"):
is_sequence = True
is_sequence = is_clip_from_media_sequence(r_otio_cl)
# File sequence way
if is_sequence:
# file sequence way
# Remap processing range to input file sequence.
processing_range_as_frames = (
processing_range.start_time.to_frames(),
processing_range.end_time_inclusive().to_frames()
)
first, last = remap_range_on_file_sequence(
r_otio_cl,
processing_range_as_frames,
)
input_fps = processing_range.start_time.rate
if hasattr(media_ref, "target_url_base"):
dirname = media_ref.target_url_base
head = media_ref.name_prefix
tail = media_ref.name_suffix
first, last = otio_range_to_frame_range(
available_range)
collection = clique.Collection(
head=head,
tail=tail,
@ -194,8 +212,8 @@ class ExtractOTIOReview(publish.Extractor):
collection.indexes.update(
[i for i in range(first, (last + 1))])
# render segment
self._render_seqment(
sequence=[dirname, collection])
self._render_segment(
sequence=[dirname, collection, input_fps])
# generate used frames
self._generate_used_frames(
len(collection.indexes))
@ -204,30 +222,44 @@ class ExtractOTIOReview(publish.Extractor):
# `ImageSequenceReference`
path = media_ref.target_url
collection_data = make_sequence_collection(
path, available_range, metadata)
path, processing_range, metadata)
dir_path, collection = collection_data
# render segment
self._render_seqment(
sequence=[dir_path, collection])
self._render_segment(
sequence=[dir_path, collection, input_fps])
# generate used frames
self._generate_used_frames(
len(collection.indexes))
# Single video way.
# Extraction via FFmpeg.
else:
# single video file way
path = media_ref.target_url
# Set extract range from 0 (FFmpeg ignores embedded timecode).
extract_range = otio.opentime.TimeRange(
otio.opentime.RationalTime(
(
processing_range.start_time.value
- available_range.start_time.value
),
rate=available_range.start_time.rate,
),
duration=processing_range.duration,
)
# render video file to sequence
self._render_seqment(
video=[path, available_range])
self._render_segment(
video=[path, extract_range])
# generate used frames
self._generate_used_frames(
available_range.duration.value)
processing_range.duration.value)
# QUESTION: what if nested track composition is in place?
else:
# at last process a Gap
self._render_seqment(gap=duration)
self._render_segment(gap=duration.to_frames())
# generate used frames
self._generate_used_frames(duration)
self._generate_used_frames(duration.to_frames())
# creating and registering representation
representation = self._create_representation(start, duration)
@ -276,7 +308,7 @@ class ExtractOTIOReview(publish.Extractor):
})
return representation_data
def _trim_available_range(self, avl_range, start, duration, fps):
def _trim_available_range(self, avl_range, start, duration):
"""
Trim available media range to source range.
@ -285,69 +317,87 @@ class ExtractOTIOReview(publish.Extractor):
Args:
avl_range (otio.time.TimeRange): media available time range
start (int): start frame
duration (int): duration frames
fps (float): frame rate
start (otio.time.RationalTime): start
duration (otio.time.RationalTime): duration
Returns:
otio.time.TimeRange: trimmed available range
"""
# Not all hosts can import these modules.
import opentimelineio as otio
from ayon_core.pipeline.editorial import (
trim_media_range,
range_from_frames
)
avl_start = int(avl_range.start_time.value)
src_start = int(avl_start + start)
avl_durtation = int(avl_range.duration.value)
def _round_to_frame(rational_time):
""" Handle rounding duration to frame.
"""
# OpentimelineIO >= 0.16.0
try:
return rational_time.round().to_frames()
self.need_offset = bool(avl_start != 0 and src_start != 0)
# OpentimelineIO < 0.16.0
except AttributeError:
return otio.opentime.RationalTime(
round(rational_time.value),
rate=rational_time.rate,
).to_frames()
# if media start is les then clip requires
if src_start < avl_start:
# calculate gap
gap_duration = avl_start - src_start
avl_start = avl_range.start_time
# An additional gap is required before the available
# range to conform source start point and head handles.
if start < avl_start:
gap_duration = avl_start - start
start = avl_start
duration -= gap_duration
gap_duration = _round_to_frame(gap_duration)
# create gap data to disk
self._render_seqment(gap=gap_duration)
self._render_segment(gap=gap_duration)
# generate used frames
self._generate_used_frames(gap_duration)
# fix start and end to correct values
start = 0
# An additional gap is required after the available
# range to conform to source end point + tail handles
# (media duration is shorter then clip requirement).
end_point = start + duration
avl_end_point = avl_range.end_time_exclusive()
if end_point > avl_end_point:
gap_duration = end_point - avl_end_point
duration -= gap_duration
# if media duration is shorter then clip requirement
if duration > avl_durtation:
# calculate gap
gap_start = int(src_start + avl_durtation)
gap_end = int(src_start + duration)
gap_duration = gap_end - gap_start
gap_duration = _round_to_frame(gap_duration)
# create gap data to disk
self._render_seqment(gap=gap_duration, end_offset=avl_durtation)
self._render_segment(
gap=gap_duration,
end_offset=duration.to_frames()
)
# generate used frames
self._generate_used_frames(gap_duration, end_offset=avl_durtation)
# fix duration lenght
duration = avl_durtation
self._generate_used_frames(
gap_duration,
end_offset=duration.to_frames()
)
# return correct trimmed range
return trim_media_range(
avl_range, range_from_frames(start, duration, fps)
avl_range,
otio.opentime.TimeRange(
start,
duration
)
)
def _render_seqment(self, sequence=None,
def _render_segment(self, sequence=None,
video=None, gap=None, end_offset=None):
"""
Render seqment into image sequence frames.
Render segment into image sequence frames.
Using ffmpeg to convert compatible video and image source
to defined image sequence format.
Args:
sequence (list): input dir path string, collection object in list
sequence (list): input dir path string, collection object, fps in list
video (list)[optional]: video_path string, otio_range in list
gap (int)[optional]: gap duration
end_offset (int)[optional]: offset gap frame start in frames
@ -369,7 +419,7 @@ class ExtractOTIOReview(publish.Extractor):
input_extension = None
if sequence:
input_dir, collection = sequence
input_dir, collection, sequence_fps = sequence
in_frame_start = min(collection.indexes)
# converting image sequence to image sequence
@ -377,9 +427,28 @@ class ExtractOTIOReview(publish.Extractor):
input_path = os.path.join(input_dir, input_file)
input_extension = os.path.splitext(input_path)[-1]
# form command for rendering gap files
"""
Form Command for Rendering Sequence Files
To explicitly set the input frame range and preserve the frame
range, avoid silent dropped frames caused by input mismatch
with FFmpeg's default rate of 25.0 fps. For more info,
refer to the FFmpeg image2 demuxer.
Implicit:
- Input: 100 frames (24fps from metadata)
- Demuxer: video 25fps
- Output: 98 frames, dropped 2
Explicit with "-framerate":
- Input: 100 frames (24fps from metadata)
- Demuxer: video 24fps
- Output: 100 frames, no dropped frames
"""
command.extend([
"-start_number", str(in_frame_start),
"-framerate", str(sequence_fps),
"-i", input_path
])
@ -454,16 +523,11 @@ class ExtractOTIOReview(publish.Extractor):
padding = "{{:0{}d}}".format(self.padding)
# create frame offset
offset = 0
if self.need_offset:
offset = 1
if end_offset:
new_frames = list()
start_frame = self.used_frames[-1]
for index in range((end_offset + offset),
(int(end_offset + duration) + offset)):
for index in range(end_offset,
(int(end_offset + duration))):
seq_number = padding.format(start_frame + index)
self.log.debug(
"index: `{}` | seq_number: `{}`".format(index, seq_number))
@ -519,4 +583,3 @@ class ExtractOTIOReview(publish.Extractor):
self.log.debug(f"file_prefix::{file_prefix}")
return file_prefix

View file

@ -74,9 +74,6 @@ class ExtractOTIOTrimmingVideo(publish.Extractor):
otio_range (opentime.TimeRange): range to trim to
"""
# Not all hosts can import this module.
from ayon_core.pipeline.editorial import frames_to_seconds
# create path to destination
output_path = self._get_ffmpeg_output(input_file_path)
@ -84,11 +81,8 @@ class ExtractOTIOTrimmingVideo(publish.Extractor):
command = get_ffmpeg_tool_args("ffmpeg")
video_path = input_file_path
frame_start = otio_range.start_time.value
input_fps = otio_range.start_time.rate
frame_duration = otio_range.duration.value - 1
sec_start = frames_to_seconds(frame_start, input_fps)
sec_duration = frames_to_seconds(frame_duration, input_fps)
sec_start = otio_range.start_time.to_seconds()
sec_duration = otio_range.duration.to_seconds()
# form command for rendering gap files
command.extend([

View file

@ -28,10 +28,10 @@ from .files_widget import FilesWidget
def create_widget_for_attr_def(attr_def, parent=None):
widget = _create_widget_for_attr_def(attr_def, parent)
if attr_def.hidden:
if not attr_def.visible:
widget.setVisible(False)
if attr_def.disabled:
if not attr_def.enabled:
widget.setEnabled(False)
return widget
@ -135,7 +135,7 @@ class AttributeDefinitionsWidget(QtWidgets.QWidget):
widget = create_widget_for_attr_def(attr_def, self)
self._widgets.append(widget)
if attr_def.hidden:
if not attr_def.visible:
continue
expand_cols = 2

View file

@ -1,14 +1,17 @@
import uuid
import copy
import inspect
import logging
import traceback
import collections
from contextlib import contextmanager
from functools import partial
from typing import Optional, Dict, List, Union, Any, Iterable
import arrow
import pyblish.plugin
from ayon_core.lib import env_value_to_bool
from ayon_core.pipeline import (
PublishValidationError,
KnownPublishError,
@ -26,6 +29,25 @@ PUBLISH_EVENT_SOURCE = "publisher.publish.model"
PLUGIN_ORDER_OFFSET = 0.5
class MessageHandler(logging.Handler):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._records = []
def clear_records(self):
self._records = []
def emit(self, record):
try:
record.msg = record.getMessage()
except Exception:
record.msg = str(record.msg)
self._records.append(record)
def get_records(self):
return self._records
class PublishErrorInfo:
def __init__(
self,
@ -850,6 +872,10 @@ class PublishModel:
def __init__(self, controller: AbstractPublisherBackend):
self._controller = controller
self._log_to_console: bool = env_value_to_bool(
"AYON_PUBLISHER_PRINT_LOGS", default=False
)
# Publishing should stop at validation stage
self._publish_up_validation: bool = False
self._publish_comment_is_set: bool = False
@ -897,8 +923,16 @@ class PublishModel:
self._default_iterator()
)
self._log_handler: MessageHandler = MessageHandler()
def reset(self):
# Allow to change behavior during process lifetime
self._log_to_console = env_value_to_bool(
"AYON_PUBLISHER_PRINT_LOGS", default=False
)
create_context = self._controller.get_create_context()
self._publish_up_validation = False
self._publish_comment_is_set = False
self._publish_has_started = False
@ -1266,14 +1300,49 @@ class PublishModel:
self._set_progress(self._publish_max_progress)
yield partial(self.stop_publish)
@contextmanager
def _log_manager(self, plugin: pyblish.api.Plugin):
root = logging.getLogger()
if not self._log_to_console:
plugin.log.propagate = False
plugin.log.addHandler(self._log_handler)
root.addHandler(self._log_handler)
try:
if self._log_to_console:
yield None
else:
yield self._log_handler
finally:
if not self._log_to_console:
plugin.log.propagate = True
plugin.log.removeHandler(self._log_handler)
root.removeHandler(self._log_handler)
self._log_handler.clear_records()
def _process_and_continue(
self,
plugin: pyblish.api.Plugin,
instance: pyblish.api.Instance
):
result = pyblish.plugin.process(
plugin, self._publish_context, instance
)
with self._log_manager(plugin) as log_handler:
result = pyblish.plugin.process(
plugin, self._publish_context, instance
)
if log_handler is not None:
records = log_handler.get_records()
exception = result.get("error")
if exception is not None and records:
last_record = records[-1]
if (
last_record.name == "pyblish.plugin"
and last_record.levelno == logging.ERROR
):
# Remove last record made by pyblish
# - `log.exception(formatted_traceback)`
records.pop(-1)
result["records"] = records
exception = result.get("error")
if exception:

View file

@ -1446,7 +1446,7 @@ class CreatorAttrsWidget(QtWidgets.QWidget):
self._attr_def_id_to_instances[attr_def.id] = attr_instances
self._attr_def_id_to_attr_def[attr_def.id] = attr_def
if attr_def.hidden:
if not attr_def.visible:
continue
expand_cols = 2
@ -1585,7 +1585,7 @@ class PublishPluginAttrsWidget(QtWidgets.QWidget):
widget = create_widget_for_attr_def(
attr_def, content_widget
)
hidden_widget = attr_def.hidden
hidden_widget = not attr_def.visible
# Hide unknown values of publish plugins
# - The keys in most of cases does not represent what would
# label represent

View file

@ -777,7 +777,7 @@ class ProjectPushItemProcess:
task_info = copy.deepcopy(task_info)
task_info["name"] = dst_task_name
# Fill rest of task information based on task type
task_type_name = task_info["type"]
task_type_name = task_info["taskType"]
task_types_by_name = {
task_type["name"]: task_type
for task_type in self._project_entity["taskTypes"]
@ -821,7 +821,7 @@ class ProjectPushItemProcess:
task_name = task_type = None
if task_info:
task_name = task_info["name"]
task_type = task_info["type"]
task_type = task_info["taskType"]
product_name = get_product_name(
self._item.dst_project_name,
@ -905,7 +905,7 @@ class ProjectPushItemProcess:
project_name,
self.host_name,
task_name=self._task_info["name"],
task_type=self._task_info["type"],
task_type=self._task_info["taskType"],
product_type=product_type,
product_name=product_entity["name"]
)
@ -959,7 +959,7 @@ class ProjectPushItemProcess:
formatting_data = get_template_data(
self._project_entity,
self._folder_entity,
self._task_info.get("name"),
self._task_info,
self.host_name
)
formatting_data.update({

View file

@ -1,3 +1,3 @@
# -*- coding: utf-8 -*-
"""Package declaring AYON core addon version."""
__version__ = "0.4.5-dev.1"
"""Package declaring AYON addon 'core' version."""
__version__ = "1.0.1+dev"

View file

@ -1,3 +1,5 @@
#!/usr/bin/env python
"""Prepares server package from addon repo to upload to server.
Requires Python 3.9. (Or at least 3.8+).
@ -22,32 +24,39 @@ client side code zipped in `private` subfolder.
import os
import sys
import re
import io
import shutil
import argparse
import platform
import argparse
import logging
import collections
import zipfile
import hashlib
import subprocess
from typing import Optional, Iterable, Pattern, Union, List, Tuple
from typing import Optional
import package
CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
PACKAGE_PATH = os.path.join(CURRENT_DIR, "package.py")
package_content = {}
with open(PACKAGE_PATH, "r") as stream:
exec(stream.read(), package_content)
FileMapping = Tuple[Union[str, io.BytesIO], str]
ADDON_NAME: str = package.name
ADDON_VERSION: str = package.version
ADDON_CLIENT_DIR: Union[str, None] = getattr(package, "client_dir", None)
ADDON_VERSION = package_content["version"]
ADDON_NAME = package_content["name"]
ADDON_CLIENT_DIR = package_content["client_dir"]
CLIENT_VERSION_CONTENT = '''# -*- coding: utf-8 -*-
"""Package declaring AYON core addon version."""
__version__ = "{}"
CURRENT_ROOT: str = os.path.dirname(os.path.abspath(__file__))
SERVER_ROOT: str = os.path.join(CURRENT_ROOT, "server")
FRONTEND_ROOT: str = os.path.join(CURRENT_ROOT, "frontend")
FRONTEND_DIST_ROOT: str = os.path.join(FRONTEND_ROOT, "dist")
DST_DIST_DIR: str = os.path.join("frontend", "dist")
PRIVATE_ROOT: str = os.path.join(CURRENT_ROOT, "private")
PUBLIC_ROOT: str = os.path.join(CURRENT_ROOT, "public")
CLIENT_ROOT: str = os.path.join(CURRENT_ROOT, "client")
VERSION_PY_CONTENT = f'''# -*- coding: utf-8 -*-
"""Package declaring AYON addon '{ADDON_NAME}' version."""
__version__ = "{ADDON_VERSION}"
'''
# Patterns of directories to be skipped for server part of addon
IGNORE_DIR_PATTERNS = [
IGNORE_DIR_PATTERNS: List[Pattern] = [
re.compile(pattern)
for pattern in {
# Skip directories starting with '.'
@ -58,7 +67,7 @@ IGNORE_DIR_PATTERNS = [
]
# Patterns of files to be skipped for server part of addon
IGNORE_FILE_PATTERNS = [
IGNORE_FILE_PATTERNS: List[Pattern] = [
re.compile(pattern)
for pattern in {
# Skip files starting with '.'
@ -70,15 +79,6 @@ IGNORE_FILE_PATTERNS = [
]
def calculate_file_checksum(filepath, hash_algorithm, chunk_size=10000):
func = getattr(hashlib, hash_algorithm)
hash_obj = func()
with open(filepath, "rb") as f:
for chunk in iter(lambda: f.read(chunk_size), b""):
hash_obj.update(chunk)
return hash_obj.hexdigest()
class ZipFileLongPaths(zipfile.ZipFile):
"""Allows longer paths in zip files.
@ -97,12 +97,28 @@ class ZipFileLongPaths(zipfile.ZipFile):
else:
tpath = "\\\\?\\" + tpath
return super(ZipFileLongPaths, self)._extract_member(
member, tpath, pwd
)
return super()._extract_member(member, tpath, pwd)
def safe_copy_file(src_path, dst_path):
def _get_yarn_executable() -> Union[str, None]:
cmd = "which"
if platform.system().lower() == "windows":
cmd = "where"
for line in subprocess.check_output(
[cmd, "yarn"], encoding="utf-8"
).splitlines():
if not line or not os.path.exists(line):
continue
try:
subprocess.call([line, "--version"])
return line
except OSError:
continue
return None
def safe_copy_file(src_path: str, dst_path: str):
"""Copy file and make sure destination directory exists.
Ignore if destination already contains directories from source.
@ -115,210 +131,335 @@ def safe_copy_file(src_path, dst_path):
if src_path == dst_path:
return
dst_dir = os.path.dirname(dst_path)
try:
os.makedirs(dst_dir)
except Exception:
pass
dst_dir: str = os.path.dirname(dst_path)
os.makedirs(dst_dir, exist_ok=True)
shutil.copy2(src_path, dst_path)
def _value_match_regexes(value, regexes):
for regex in regexes:
if regex.search(value):
return True
return False
def _value_match_regexes(value: str, regexes: Iterable[Pattern]) -> bool:
return any(
regex.search(value)
for regex in regexes
)
def find_files_in_subdir(
src_path,
ignore_file_patterns=None,
ignore_dir_patterns=None
):
src_path: str,
ignore_file_patterns: Optional[List[Pattern]] = None,
ignore_dir_patterns: Optional[List[Pattern]] = None
) -> List[Tuple[str, str]]:
"""Find all files to copy in subdirectories of given path.
All files that match any of the patterns in 'ignore_file_patterns' will
be skipped and any directories that match any of the patterns in
'ignore_dir_patterns' will be skipped with all subfiles.
Args:
src_path (str): Path to directory to search in.
ignore_file_patterns (Optional[list[Pattern]]): List of regexes
to match files to ignore.
ignore_dir_patterns (Optional[list[Pattern]]): List of regexes
to match directories to ignore.
Returns:
list[tuple[str, str]]: List of tuples with path to file and parent
directories relative to 'src_path'.
"""
if ignore_file_patterns is None:
ignore_file_patterns = IGNORE_FILE_PATTERNS
if ignore_dir_patterns is None:
ignore_dir_patterns = IGNORE_DIR_PATTERNS
output = []
output: List[Tuple[str, str]] = []
if not os.path.exists(src_path):
return output
hierarchy_queue = collections.deque()
hierarchy_queue: collections.deque = collections.deque()
hierarchy_queue.append((src_path, []))
while hierarchy_queue:
item = hierarchy_queue.popleft()
item: Tuple[str, str] = hierarchy_queue.popleft()
dirpath, parents = item
for name in os.listdir(dirpath):
path = os.path.join(dirpath, name)
path: str = os.path.join(dirpath, name)
if os.path.isfile(path):
if not _value_match_regexes(name, ignore_file_patterns):
items = list(parents)
items: List[str] = list(parents)
items.append(name)
output.append((path, os.path.sep.join(items)))
continue
if not _value_match_regexes(name, ignore_dir_patterns):
items = list(parents)
items: List[str] = list(parents)
items.append(name)
hierarchy_queue.append((path, items))
return output
def copy_server_content(addon_output_dir, current_dir, log):
def update_client_version(logger):
"""Update version in client code if version.py is present."""
if not ADDON_CLIENT_DIR:
return
version_path: str = os.path.join(
CLIENT_ROOT, ADDON_CLIENT_DIR, "version.py"
)
if not os.path.exists(version_path):
logger.debug("Did not find version.py in client directory")
return
logger.info("Updating client version")
with open(version_path, "w") as stream:
stream.write(VERSION_PY_CONTENT)
def update_pyproject_toml(logger):
filepath = os.path.join(CURRENT_ROOT, "pyproject.toml")
new_lines = []
with open(filepath, "r") as stream:
version_found = False
for line in stream.readlines():
if not version_found and line.startswith("version ="):
line = f'version = "{ADDON_VERSION}"\n'
version_found = True
new_lines.append(line)
with open(filepath, "w") as stream:
stream.write("".join(new_lines))
def build_frontend():
yarn_executable = _get_yarn_executable()
if yarn_executable is None:
raise RuntimeError("Yarn executable was not found.")
subprocess.run([yarn_executable, "install"], cwd=FRONTEND_ROOT)
subprocess.run([yarn_executable, "build"], cwd=FRONTEND_ROOT)
if not os.path.exists(FRONTEND_DIST_ROOT):
raise RuntimeError(
"Frontend build failed. Did not find 'dist' folder."
)
def get_client_files_mapping() -> List[Tuple[str, str]]:
"""Mapping of source client code files to destination paths.
Example output:
[
(
"C:/addons/MyAddon/version.py",
"my_addon/version.py"
),
(
"C:/addons/MyAddon/client/my_addon/__init__.py",
"my_addon/__init__.py"
)
]
Returns:
list[tuple[str, str]]: List of path mappings to copy. The destination
path is relative to expected output directory.
"""
# Add client code content to zip
client_code_dir: str = os.path.join(CLIENT_ROOT, ADDON_CLIENT_DIR)
mapping = [
(path, os.path.join(ADDON_CLIENT_DIR, sub_path))
for path, sub_path in find_files_in_subdir(client_code_dir)
]
license_path = os.path.join(CURRENT_ROOT, "LICENSE")
if os.path.exists(license_path):
mapping.append((license_path, f"{ADDON_CLIENT_DIR}/LICENSE"))
return mapping
def get_client_zip_content(log) -> io.BytesIO:
log.info("Preparing client code zip")
files_mapping: List[Tuple[str, str]] = get_client_files_mapping()
stream = io.BytesIO()
with ZipFileLongPaths(stream, "w", zipfile.ZIP_DEFLATED) as zipf:
for src_path, subpath in files_mapping:
zipf.write(src_path, subpath)
stream.seek(0)
return stream
def get_base_files_mapping() -> List[FileMapping]:
filepaths_to_copy: List[FileMapping] = [
(
os.path.join(CURRENT_ROOT, "package.py"),
"package.py"
)
]
# Add license file to package if exists
license_path = os.path.join(CURRENT_ROOT, "LICENSE")
if os.path.exists(license_path):
filepaths_to_copy.append((license_path, "LICENSE"))
# Go through server, private and public directories and find all files
for dirpath in (SERVER_ROOT, PRIVATE_ROOT, PUBLIC_ROOT):
if not os.path.exists(dirpath):
continue
dirname = os.path.basename(dirpath)
for src_file, subpath in find_files_in_subdir(dirpath):
dst_subpath = os.path.join(dirname, subpath)
filepaths_to_copy.append((src_file, dst_subpath))
if os.path.exists(FRONTEND_DIST_ROOT):
for src_file, subpath in find_files_in_subdir(FRONTEND_DIST_ROOT):
dst_subpath = os.path.join(DST_DIST_DIR, subpath)
filepaths_to_copy.append((src_file, dst_subpath))
pyproject_toml = os.path.join(CLIENT_ROOT, "pyproject.toml")
if os.path.exists(pyproject_toml):
filepaths_to_copy.append(
(pyproject_toml, "private/pyproject.toml")
)
return filepaths_to_copy
def copy_client_code(output_dir: str, log: logging.Logger):
"""Copies server side folders to 'addon_package_dir'
Args:
addon_output_dir (str): package dir in addon repo dir
current_dir (str): addon repo dir
output_dir (str): Output directory path.
log (logging.Logger)
"""
log.info(f"Copying client for {ADDON_NAME}-{ADDON_VERSION}")
log.info("Copying server content")
full_output_path = os.path.join(
output_dir, f"{ADDON_NAME}_{ADDON_VERSION}"
)
if os.path.exists(full_output_path):
shutil.rmtree(full_output_path)
os.makedirs(full_output_path, exist_ok=True)
filepaths_to_copy = []
server_dirpath = os.path.join(current_dir, "server")
for item in find_files_in_subdir(server_dirpath):
src_path, dst_subpath = item
dst_path = os.path.join(addon_output_dir, "server", dst_subpath)
filepaths_to_copy.append((src_path, dst_path))
# Copy files
for src_path, dst_path in filepaths_to_copy:
for src_path, dst_subpath in get_client_files_mapping():
dst_path = os.path.join(full_output_path, dst_subpath)
safe_copy_file(src_path, dst_path)
def _update_client_version(client_addon_dir):
"""Write version.py file to 'client' directory.
Make sure the version in client dir is the same as in package.py.
Args:
client_addon_dir (str): Directory path of client addon.
"""
dst_version_path = os.path.join(client_addon_dir, "version.py")
with open(dst_version_path, "w") as stream:
stream.write(CLIENT_VERSION_CONTENT.format(ADDON_VERSION))
log.info("Client copy finished")
def zip_client_side(addon_package_dir, current_dir, log):
"""Copy and zip `client` content into 'addon_package_dir'.
Args:
addon_package_dir (str): Output package directory path.
current_dir (str): Directory path of addon source.
log (logging.Logger): Logger object.
"""
client_dir = os.path.join(current_dir, "client")
client_addon_dir = os.path.join(client_dir, ADDON_CLIENT_DIR)
if not os.path.isdir(client_addon_dir):
raise ValueError(
f"Failed to find client directory '{client_addon_dir}'"
)
log.info("Preparing client code zip")
private_dir = os.path.join(addon_package_dir, "private")
if not os.path.exists(private_dir):
os.makedirs(private_dir)
_update_client_version(client_addon_dir)
zip_filepath = os.path.join(os.path.join(private_dir, "client.zip"))
with ZipFileLongPaths(zip_filepath, "w", zipfile.ZIP_DEFLATED) as zipf:
# Add client code content to zip
for path, sub_path in find_files_in_subdir(client_addon_dir):
sub_path = os.path.join(ADDON_CLIENT_DIR, sub_path)
zipf.write(path, sub_path)
shutil.copy(os.path.join(client_dir, "pyproject.toml"), private_dir)
def create_server_package(
def copy_addon_package(
output_dir: str,
addon_output_dir: str,
files_mapping: List[FileMapping],
log: logging.Logger
):
"""Create server package zip file.
The zip file can be installed to a server using UI or rest api endpoints.
"""Copy client code to output directory.
Args:
output_dir (str): Directory path to output zip file.
addon_output_dir (str): Directory path to addon output directory.
output_dir (str): Directory path to output client code.
files_mapping (List[FileMapping]): List of tuples with source file
and destination subpath.
log (logging.Logger): Logger object.
"""
log.info("Creating server package")
"""
log.info(f"Copying package for {ADDON_NAME}-{ADDON_VERSION}")
# Add addon name and version to output directory
addon_output_dir: str = os.path.join(
output_dir, ADDON_NAME, ADDON_VERSION
)
if os.path.isdir(addon_output_dir):
log.info(f"Purging {addon_output_dir}")
shutil.rmtree(addon_output_dir)
os.makedirs(addon_output_dir, exist_ok=True)
# Copy server content
for src_file, dst_subpath in files_mapping:
dst_path: str = os.path.join(addon_output_dir, dst_subpath)
dst_dir: str = os.path.dirname(dst_path)
os.makedirs(dst_dir, exist_ok=True)
if isinstance(src_file, io.BytesIO):
with open(dst_path, "wb") as stream:
stream.write(src_file.getvalue())
else:
safe_copy_file(src_file, dst_path)
log.info("Package copy finished")
def create_addon_package(
output_dir: str,
files_mapping: List[FileMapping],
log: logging.Logger
):
log.info(f"Creating package for {ADDON_NAME}-{ADDON_VERSION}")
os.makedirs(output_dir, exist_ok=True)
output_path = os.path.join(
output_dir, f"{ADDON_NAME}-{ADDON_VERSION}.zip"
)
with ZipFileLongPaths(output_path, "w", zipfile.ZIP_DEFLATED) as zipf:
# Move addon content to zip into 'addon' directory
addon_output_dir_offset = len(addon_output_dir) + 1
for root, _, filenames in os.walk(addon_output_dir):
if not filenames:
continue
# Copy server content
for src_file, dst_subpath in files_mapping:
if isinstance(src_file, io.BytesIO):
zipf.writestr(dst_subpath, src_file.getvalue())
else:
zipf.write(src_file, dst_subpath)
dst_root = None
if root != addon_output_dir:
dst_root = root[addon_output_dir_offset:]
for filename in filenames:
src_path = os.path.join(root, filename)
dst_path = filename
if dst_root:
dst_path = os.path.join(dst_root, dst_path)
zipf.write(src_path, dst_path)
log.info(f"Output package can be found: {output_path}")
log.info("Package created")
def main(
output_dir: Optional[str]=None,
skip_zip: bool=False,
keep_sources: bool=False,
clear_output_dir: bool=False
output_dir: Optional[str] = None,
skip_zip: Optional[bool] = False,
only_client: Optional[bool] = False
):
log = logging.getLogger("create_package")
log.info("Start creating package")
log: logging.Logger = logging.getLogger("create_package")
log.info("Package creation started")
current_dir = os.path.dirname(os.path.abspath(__file__))
if not output_dir:
output_dir = os.path.join(current_dir, "package")
output_dir = os.path.join(CURRENT_ROOT, "package")
has_client_code = bool(ADDON_CLIENT_DIR)
if has_client_code:
client_dir: str = os.path.join(CLIENT_ROOT, ADDON_CLIENT_DIR)
if not os.path.exists(client_dir):
raise RuntimeError(
f"Client directory was not found '{client_dir}'."
" Please check 'client_dir' in 'package.py'."
)
update_client_version(log)
new_created_version_dir = os.path.join(
output_dir, ADDON_NAME, ADDON_VERSION
)
update_pyproject_toml(log)
if os.path.isdir(new_created_version_dir) and clear_output_dir:
log.info(f"Purging {new_created_version_dir}")
shutil.rmtree(output_dir)
if only_client:
if not has_client_code:
raise RuntimeError("Client code is not available. Skipping")
copy_client_code(output_dir, log)
return
log.info(f"Preparing package for {ADDON_NAME}-{ADDON_VERSION}")
addon_output_root = os.path.join(output_dir, ADDON_NAME)
addon_output_dir = os.path.join(addon_output_root, ADDON_VERSION)
if not os.path.exists(addon_output_dir):
os.makedirs(addon_output_dir)
if os.path.exists(FRONTEND_ROOT):
build_frontend()
copy_server_content(addon_output_dir, current_dir, log)
safe_copy_file(
PACKAGE_PATH,
os.path.join(addon_output_dir, os.path.basename(PACKAGE_PATH))
)
zip_client_side(addon_output_dir, current_dir, log)
files_mapping: List[FileMapping] = []
files_mapping.extend(get_base_files_mapping())
if has_client_code:
files_mapping.append(
(get_client_zip_content(log), "private/client.zip")
)
# Skip server zipping
if not skip_zip:
create_server_package(output_dir, addon_output_dir, log)
# Remove sources only if zip file is created
if not keep_sources:
log.info("Removing source files for server package")
shutil.rmtree(addon_output_root)
if skip_zip:
copy_addon_package(output_dir, files_mapping, log)
else:
create_addon_package(output_dir, files_mapping, log)
log.info("Package creation finished")
@ -333,23 +474,6 @@ if __name__ == "__main__":
" server folder structure."
)
)
parser.add_argument(
"--keep-sources",
dest="keep_sources",
action="store_true",
help=(
"Keep folder structure when server package is created."
)
)
parser.add_argument(
"-c", "--clear-output-dir",
dest="clear_output_dir",
action="store_true",
help=(
"Clear output directory before package creation."
)
)
parser.add_argument(
"-o", "--output",
dest="output_dir",
@ -359,11 +483,25 @@ if __name__ == "__main__":
" (Will be purged if already exists!)"
)
)
parser.add_argument(
"--only-client",
dest="only_client",
action="store_true",
help=(
"Extract only client code. This is useful for development."
" Requires '-o', '--output' argument to be filled."
)
)
parser.add_argument(
"--debug",
dest="debug",
action="store_true",
help="Debug log messages."
)
args = parser.parse_args(sys.argv[1:])
main(
args.output_dir,
args.skip_zip,
args.keep_sources,
args.clear_output_dir
)
level = logging.INFO
if args.debug:
level = logging.DEBUG
logging.basicConfig(level=level)
main(args.output_dir, args.skip_zip, args.only_client)

View file

@ -1,6 +1,6 @@
name = "core"
title = "Core"
version = "0.4.5-dev.1"
version = "1.0.1+dev"
client_dir = "ayon_core"

View file

@ -5,7 +5,7 @@
[tool.poetry]
name = "ayon-core"
version = "0.4.3-dev.1"
version = "1.0.1+dev"
description = ""
authors = ["Ynput Team <team@ynput.io>"]
readme = "README.md"

View file

@ -4,6 +4,29 @@ from typing import Any
from .publish_plugins import DEFAULT_PUBLISH_VALUES
def _convert_imageio_configs_0_4_5(overrides):
"""Imageio config settings did change to profiles since 0.4.5."""
imageio_overrides = overrides.get("imageio") or {}
# make sure settings are already converted to profiles
ocio_config_profiles = imageio_overrides.get("ocio_config_profiles")
if not ocio_config_profiles:
return
for profile in ocio_config_profiles:
if profile.get("type") != "product_name":
continue
profile["type"] = "published_product"
profile["published_product"] = {
"product_name": profile.pop("product_name"),
"fallback": {
"type": "builtin_path",
"builtin_path": "{BUILTIN_OCIO_ROOT}/aces_1.2/config.ocio",
},
}
def _convert_imageio_configs_0_3_1(overrides):
"""Imageio config settings did change to profiles since 0.3.1. ."""
imageio_overrides = overrides.get("imageio") or {}
@ -76,7 +99,8 @@ def _convert_oiio_transcode_0_4_5(publish_overrides):
if "ExtractOIIOTranscode" not in publish_overrides:
return
transcode_profiles = publish_overrides["ExtractOIIOTranscode"].get("profiles")
transcode_profiles = publish_overrides["ExtractOIIOTranscode"].get(
"profiles")
if not transcode_profiles:
return
@ -85,7 +109,7 @@ def _convert_oiio_transcode_0_4_5(publish_overrides):
if outputs is None:
return
for output in outputs :
for output in outputs:
# Already new settings
if "display_view" in output:
break
@ -102,7 +126,7 @@ def _convert_oiio_transcode_0_4_5(publish_overrides):
}
def _conver_publish_plugins(overrides):
def _convert_publish_plugins(overrides):
if "publish" not in overrides:
return
_convert_validate_version_0_3_3(overrides["publish"])
@ -114,5 +138,6 @@ def convert_settings_overrides(
overrides: dict[str, Any],
) -> dict[str, Any]:
_convert_imageio_configs_0_3_1(overrides)
_conver_publish_plugins(overrides)
_convert_imageio_configs_0_4_5(overrides)
_convert_publish_plugins(overrides)
return overrides

View file

@ -58,7 +58,14 @@ def _ocio_config_profile_types():
return [
{"value": "builtin_path", "label": "AYON built-in OCIO config"},
{"value": "custom_path", "label": "Path to OCIO config"},
{"value": "product_name", "label": "Published product"},
{"value": "published_product", "label": "Published product"},
]
def _fallback_ocio_config_profile_types():
return [
{"value": "builtin_path", "label": "AYON built-in OCIO config"},
{"value": "custom_path", "label": "Path to OCIO config"},
]
@ -76,6 +83,49 @@ def _ocio_built_in_paths():
]
class FallbackProductModel(BaseSettingsModel):
_layout = "expanded"
fallback_type: str = SettingsField(
title="Fallback config type",
enum_resolver=_fallback_ocio_config_profile_types,
conditionalEnum=True,
default="builtin_path",
description=(
"Type of config which needs to be used in case published "
"product is not found."
),
)
builtin_path: str = SettingsField(
"ACES 1.2",
title="Built-in OCIO config",
enum_resolver=_ocio_built_in_paths,
description=(
"AYON ocio addon distributed OCIO config. "
"Activated addon in bundle is required: 'ayon_ocio' >= 1.1.1"
),
)
custom_path: str = SettingsField(
"",
title="OCIO config path",
description="Path to OCIO config. Anatomy formatting is supported.",
)
class PublishedProductModel(BaseSettingsModel):
_layout = "expanded"
product_name: str = SettingsField(
"",
title="Product name",
description=(
"Context related published product name to get OCIO config from. "
"Partial match is supported via use of regex expression."
),
)
fallback: FallbackProductModel = SettingsField(
default_factory=FallbackProductModel,
)
class CoreImageIOConfigProfilesModel(BaseSettingsModel):
_layout = "expanded"
host_names: list[str] = SettingsField(
@ -102,19 +152,19 @@ class CoreImageIOConfigProfilesModel(BaseSettingsModel):
"ACES 1.2",
title="Built-in OCIO config",
enum_resolver=_ocio_built_in_paths,
description=(
"AYON ocio addon distributed OCIO config. "
"Activated addon in bundle is required: 'ayon_ocio' >= 1.1.1"
),
)
custom_path: str = SettingsField(
"",
title="OCIO config path",
description="Path to OCIO config. Anatomy formatting is supported.",
)
product_name: str = SettingsField(
"",
title="Product name",
description=(
"Published product name to get OCIO config from. "
"Partial match is supported."
),
published_product: PublishedProductModel = SettingsField(
default_factory=PublishedProductModel,
title="Published product",
)
@ -294,7 +344,14 @@ DEFAULT_VALUES = {
"type": "builtin_path",
"builtin_path": "{BUILTIN_OCIO_ROOT}/aces_1.2/config.ocio",
"custom_path": "",
"product_name": "",
"published_product": {
"product_name": "",
"fallback": {
"fallback_type": "builtin_path",
"builtin_path": "ACES 1.2",
"custom_path": ""
}
}
}
],
"file_rules": {

View file

@ -0,0 +1,255 @@
{
"OTIO_SCHEMA": "Clip.2",
"metadata": {
"active": true,
"applieswhole": 1,
"asset": "sh020",
"audio": true,
"families": [
"clip"
],
"family": "plate",
"handleEnd": 8,
"handleStart": 0,
"heroTrack": true,
"hierarchy": "shots/sq001",
"hierarchyData": {
"episode": "ep01",
"folder": "shots",
"sequence": "sq001",
"shot": "sh020",
"track": "reference"
},
"hiero_source_type": "TrackItem",
"id": "pyblish.avalon.instance",
"label": "openpypeData",
"note": "OpenPype data container",
"parents": [
{
"entity_name": "shots",
"entity_type": "folder"
},
{
"entity_name": "sq001",
"entity_type": "sequence"
}
],
"publish": true,
"reviewTrack": null,
"sourceResolution": false,
"subset": "plateP01",
"variant": "Main",
"workfileFrameStart": 1001
},
"name": "sh020",
"source_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 23.976024627685547,
"value": 51.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 23.976024627685547,
"value": 0.0
}
},
"effects": [],
"markers": [
{
"OTIO_SCHEMA": "Marker.2",
"metadata": {
"active": true,
"applieswhole": 1,
"asset": "sh020",
"audio": true,
"families": [
"clip"
],
"family": "plate",
"handleEnd": 8,
"handleStart": 0,
"heroTrack": true,
"hierarchy": "shots/sq001",
"hierarchyData": {
"episode": "ep01",
"folder": "shots",
"sequence": "sq001",
"shot": "sh020",
"track": "reference"
},
"hiero_source_type": "TrackItem",
"id": "pyblish.avalon.instance",
"label": "openpypeData",
"note": "OpenPype data container",
"parents": [
{
"entity_name": "shots",
"entity_type": "folder"
},
{
"entity_name": "sq001",
"entity_type": "sequence"
}
],
"publish": true,
"reviewTrack": null,
"sourceResolution": false,
"subset": "plateP01",
"variant": "Main",
"workfileFrameStart": 1001
},
"name": "openpypeData",
"color": "RED",
"marked_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 23.976024627685547,
"value": 0.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 23.976024627685547,
"value": 0.0
}
}
},
{
"OTIO_SCHEMA": "Marker.2",
"metadata": {
"applieswhole": 1,
"family": "task",
"hiero_source_type": "TrackItem",
"label": "comp",
"note": "Compositing",
"type": "Compositing"
},
"name": "comp",
"color": "RED",
"marked_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 23.976024627685547,
"value": 0.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 23.976024627685547,
"value": 0.0
}
}
}
],
"enabled": true,
"media_references": {
"DEFAULT_MEDIA": {
"OTIO_SCHEMA": "ImageSequenceReference.1",
"metadata": {
"clip.properties.blendfunc": "0",
"clip.properties.colourspacename": "default",
"clip.properties.domainroot": "",
"clip.properties.enabled": "1",
"clip.properties.expanded": "1",
"clip.properties.opacity": "1",
"clip.properties.valuesource": "",
"foundry.source.audio": "",
"foundry.source.bitmapsize": "0",
"foundry.source.bitsperchannel": "0",
"foundry.source.channelformat": "integer",
"foundry.source.colourtransform": "ACES - ACES2065-1",
"foundry.source.duration": "59",
"foundry.source.filename": "MER_sq001_sh020_P01.%04d.exr 997-1055",
"foundry.source.filesize": "",
"foundry.source.fragments": "59",
"foundry.source.framerate": "23.98",
"foundry.source.fullpath": "",
"foundry.source.height": "1080",
"foundry.source.layers": "colour",
"foundry.source.path": "C:/projects/AY01_VFX_demo/resources/plates/MER_sq001_sh020_P01/MER_sq001_sh020_P01.%04d.exr 997-1055",
"foundry.source.pixelAspect": "1",
"foundry.source.pixelAspectRatio": "",
"foundry.source.pixelformat": "RGBA (Float16) Open Color IO space: 11",
"foundry.source.reelID": "",
"foundry.source.resolution": "",
"foundry.source.samplerate": "Invalid",
"foundry.source.shortfilename": "MER_sq001_sh020_P01.%04d.exr 997-1055",
"foundry.source.shot": "",
"foundry.source.shotDate": "",
"foundry.source.startTC": "",
"foundry.source.starttime": "997",
"foundry.source.timecode": "172800",
"foundry.source.umid": "1bf7437a-b446-440c-07c5-7cae7acf4f5e",
"foundry.source.umidOriginator": "foundry.source.umid",
"foundry.source.width": "1920",
"foundry.timeline.autodiskcachemode": "Manual",
"foundry.timeline.colorSpace": "ACES - ACES2065-1",
"foundry.timeline.duration": "59",
"foundry.timeline.framerate": "23.98",
"foundry.timeline.outputformat": "",
"foundry.timeline.poster": "0",
"foundry.timeline.posterLayer": "colour",
"foundry.timeline.readParams": "AAAAAQAAAAAAAAAFAAAACmNvbG9yc3BhY2UAAAAFaW50MzIAAAAMAAAAC2VkZ2VfcGl4ZWxzAAAABWludDMyAAAAAAAAABFpZ25vcmVfcGFydF9uYW1lcwAAAARib29sAAAAAAhub3ByZWZpeAAAAARib29sAAAAAB5vZmZzZXRfbmVnYXRpdmVfZGlzcGxheV93aW5kb3cAAAAEYm9vbAE=",
"foundry.timeline.samplerate": "Invalid",
"isSequence": true,
"media.exr.channels": "B:{1 0 1 1},G:{1 0 1 1},R:{1 0 1 1}",
"media.exr.compression": "8",
"media.exr.compressionName": "DWAA",
"media.exr.dataWindow": "0,0,1919,1079",
"media.exr.displayWindow": "0,0,1919,1079",
"media.exr.dwaCompressionLevel": "90",
"media.exr.lineOrder": "0",
"media.exr.pixelAspectRatio": "1",
"media.exr.screenWindowCenter": "0,0",
"media.exr.screenWindowWidth": "1",
"media.exr.type": "scanlineimage",
"media.exr.version": "1",
"media.input.bitsperchannel": "16-bit half float",
"media.input.ctime": "2022-04-21 11:56:03",
"media.input.filename": "C:/projects/AY01_VFX_demo/resources/plates/MER_sq001_sh020_P01/MER_sq001_sh020_P01.0997.exr",
"media.input.filereader": "exr",
"media.input.filesize": "1235182",
"media.input.frame": "1",
"media.input.frame_rate": "23.976",
"media.input.height": "1080",
"media.input.mtime": "2022-03-06 10:14:41",
"media.input.timecode": "02:00:00:00",
"media.input.width": "1920",
"media.nuke.full_layer_names": "0",
"media.nuke.node_hash": "ffffffffffffffff",
"media.nuke.version": "12.2v3",
"openpype.source.colourtransform": "ACES - ACES2065-1",
"openpype.source.height": 1080,
"openpype.source.pixelAspect": 1.0,
"openpype.source.width": 1920,
"padding": 4
},
"name": "",
"available_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 23.976,
"value": 59.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 23.976,
"value": 997.0
}
},
"available_image_bounds": null,
"target_url_base": "C:/projects/AY01_VFX_demo/resources/plates/MER_sq001_sh020_P01\\",
"name_prefix": "MER_sq001_sh020_P01.",
"name_suffix": ".exr",
"start_frame": 997,
"frame_step": 1,
"rate": 23.976,
"frame_zero_padding": 4,
"missing_frame_policy": "error"
}
},
"active_media_reference_key": "DEFAULT_MEDIA"
}

View file

@ -0,0 +1,363 @@
{
"OTIO_SCHEMA": "Clip.2",
"metadata": {
"Resolve_OTIO": {}
},
"name": "output.[1000-1100].exr",
"source_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 74.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 91046.625
}
},
"effects": [
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Transform",
"Enabled": true,
"Name": "Transform",
"Parameters": [],
"Type": 2
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Cropping",
"Enabled": true,
"Name": "Cropping",
"Parameters": [],
"Type": 3
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Dynamic Zoom",
"Enabled": false,
"Name": "Dynamic Zoom",
"Parameters": [
{
"Default Parameter Value": [
0.0,
0.0
],
"Key Frames": {
"-6": {
"Value": [
0.0,
0.0
],
"Variant Type": "POINTF"
},
"994": {
"Value": [
0.0,
0.0
],
"Variant Type": "POINTF"
}
},
"Parameter ID": "dynamicZoomCenter",
"Parameter Value": [
0.0,
0.0
],
"Variant Type": "POINTF"
},
{
"Default Parameter Value": 1.0,
"Key Frames": {
"-6": {
"Value": 0.8,
"Variant Type": "Double"
},
"994": {
"Value": 1.0,
"Variant Type": "Double"
}
},
"Parameter ID": "dynamicZoomScale",
"Parameter Value": 1.0,
"Variant Type": "Double",
"maxValue": 100.0,
"minValue": 0.01
}
],
"Type": 59
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Composite",
"Enabled": true,
"Name": "Composite",
"Parameters": [],
"Type": 1
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Lens Correction",
"Enabled": true,
"Name": "Lens Correction",
"Parameters": [],
"Type": 43
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Retime and Scaling",
"Enabled": true,
"Name": "Retime and Scaling",
"Parameters": [],
"Type": 22
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Video Faders",
"Enabled": true,
"Name": "Video Faders",
"Parameters": [],
"Type": 36
}
},
"name": "",
"effect_name": "Resolve Effect"
}
],
"markers": [
{
"OTIO_SCHEMA": "Marker.2",
"metadata": {
"Resolve_OTIO": {
"Keywords": [],
"Note": "{\"resolve_sub_products\": {\"io.ayon.creators.resolve.shot\": {\"id\": \"pyblish.avalon.instance\", \"productType\": \"shot\", \"productName\": \"shotMain\", \"active\": true, \"creator_identifier\": \"io.ayon.creators.resolve.shot\", \"variant\": \"Main\", \"folderPath\": \"/shots/sq01/Video_1sq01sh010\", \"task\": \"Generic\", \"clip_variant\": \"<track_name>\", \"clip_index\": \"f2918dd7-a30b-4b7d-8ac1-7d5f400058bf\", \"clip_source_resolution\": {\"width\": \"956\", \"height\": \"720\", \"pixelAspect\": 1.0}, \"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"sq01\", \"track\": \"{_track_}\", \"shot\": \"sh###\", \"hierarchy\": \"shots/sq01\", \"sourceResolution\": false, \"workfileFrameStart\": 1001, \"handleStart\": 10, \"handleEnd\": 10, \"parents\": [{\"folder_type\": \"folder\", \"entity_name\": \"shots\"}, {\"folder_type\": \"sequence\", \"entity_name\": \"sq01\"}], \"hierarchyData\": {\"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"sq01\", \"track\": \"Video_1\", \"shot\": \"sh010\"}, \"heroTrack\": true, \"uuid\": \"ade94deb-f104-47dc-b8e9-04943f900914\", \"reviewTrack\": null, \"label\": \"/shots/sq01/Video_1sq01sh010 shot\", \"has_promised_context\": true, \"newHierarchyIntegration\": true, \"newAssetPublishing\": true, \"instance_id\": \"5109899f-d744-4ed3-8547-8585ef9b703b\", \"creator_attributes\": {\"folderPath\": \"/shots/sq01/Video_1sq01sh010\", \"workfileFrameStart\": 1001, \"handleStart\": 10, \"handleEnd\": 10, \"frameStart\": 1001, \"frameEnd\": 1075, \"clipIn\": 655, \"clipOut\": 729, \"clipDuration\": 74, \"sourceIn\": 6, \"sourceOut\": 80, \"fps\": \"from_selection\"}, \"publish_attributes\": {\"CollectSlackFamilies\": {\"additional_message\": \"\"}}}, \"io.ayon.creators.resolve.plate\": {\"id\": \"pyblish.avalon.instance\", \"productType\": \"plate\", \"productName\": \"plateVideo_1\", \"active\": true, \"creator_identifier\": \"io.ayon.creators.resolve.plate\", \"variant\": \"Video_1\", \"folderPath\": \"/shots/sq01/Video_1sq01sh010\", \"task\": \"Generic\", \"clip_variant\": \"<track_name>\", \"clip_index\": \"f2918dd7-a30b-4b7d-8ac1-7d5f400058bf\", \"clip_source_resolution\": {\"width\": \"956\", \"height\": \"720\", \"pixelAspect\": 1.0}, \"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"sq01\", \"track\": \"{_track_}\", \"shot\": \"sh###\", \"hierarchy\": \"shots/sq01\", \"sourceResolution\": false, \"workfileFrameStart\": 1001, \"handleStart\": 10, \"handleEnd\": 10, \"parents\": [{\"folder_type\": \"folder\", \"entity_name\": \"shots\"}, {\"folder_type\": \"sequence\", \"entity_name\": \"sq01\"}], \"hierarchyData\": {\"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"sq01\", \"track\": \"Video_1\", \"shot\": \"sh010\"}, \"heroTrack\": true, \"uuid\": \"ade94deb-f104-47dc-b8e9-04943f900914\", \"reviewTrack\": null, \"parent_instance_id\": \"5109899f-d744-4ed3-8547-8585ef9b703b\", \"label\": \"/shots/sq01/Video_1sq01sh010 plate\", \"has_promised_context\": true, \"newHierarchyIntegration\": true, \"newAssetPublishing\": true, \"instance_id\": \"85c729e9-0503-4c3a-8d7f-be0920f047d8\", \"creator_attributes\": {\"parentInstance\": \"/shots/sq01/Video_1sq01sh010 shot\", \"vSyncOn\": false, \"vSyncTrack\": \"Video 1\"}, \"publish_attributes\": {\"CollectSlackFamilies\": {\"additional_message\": \"\"}}}}, \"clip_index\": \"f2918dd7-a30b-4b7d-8ac1-7d5f400058bf\", \"publish\": true}"
},
"clip_index": "f2918dd7-a30b-4b7d-8ac1-7d5f400058bf",
"publish": true,
"resolve_sub_products": {
"io.ayon.creators.resolve.plate": {
"active": true,
"clip_index": "f2918dd7-a30b-4b7d-8ac1-7d5f400058bf",
"clip_source_resolution": {
"height": "720",
"pixelAspect": 1.0,
"width": "956"
},
"clip_variant": "<track_name>",
"creator_attributes": {
"parentInstance": "/shots/sq01/Video_1sq01sh010 shot",
"vSyncOn": false,
"vSyncTrack": "Video 1"
},
"creator_identifier": "io.ayon.creators.resolve.plate",
"episode": "ep01",
"folder": "shots",
"folderPath": "/shots/sq01/Video_1sq01sh010",
"handleEnd": 10,
"handleStart": 10,
"has_promised_context": true,
"heroTrack": true,
"hierarchy": "shots/sq01",
"hierarchyData": {
"episode": "ep01",
"folder": "shots",
"sequence": "sq01",
"shot": "sh010",
"track": "Video_1"
},
"id": "pyblish.avalon.instance",
"instance_id": "85c729e9-0503-4c3a-8d7f-be0920f047d8",
"label": "/shots/sq01/Video_1sq01sh010 plate",
"newAssetPublishing": true,
"newHierarchyIntegration": true,
"parent_instance_id": "5109899f-d744-4ed3-8547-8585ef9b703b",
"parents": [
{
"entity_name": "shots",
"folder_type": "folder"
},
{
"entity_name": "sq01",
"folder_type": "sequence"
}
],
"productName": "plateVideo_1",
"productType": "plate",
"publish_attributes": {
"CollectSlackFamilies": {
"additional_message": ""
}
},
"reviewTrack": null,
"sequence": "sq01",
"shot": "sh###",
"sourceResolution": false,
"task": "Generic",
"track": "{_track_}",
"uuid": "ade94deb-f104-47dc-b8e9-04943f900914",
"variant": "Video_1",
"workfileFrameStart": 1001
},
"io.ayon.creators.resolve.shot": {
"active": true,
"clip_index": "f2918dd7-a30b-4b7d-8ac1-7d5f400058bf",
"clip_source_resolution": {
"height": "720",
"pixelAspect": 1.0,
"width": "956"
},
"clip_variant": "<track_name>",
"creator_attributes": {
"clipDuration": 74,
"clipIn": 655,
"clipOut": 729,
"folderPath": "/shots/sq01/Video_1sq01sh010",
"fps": "from_selection",
"frameEnd": 1075,
"frameStart": 1001,
"handleEnd": 10,
"handleStart": 10,
"sourceIn": 6,
"sourceOut": 80,
"workfileFrameStart": 1001
},
"creator_identifier": "io.ayon.creators.resolve.shot",
"episode": "ep01",
"folder": "shots",
"folderPath": "/shots/sq01/Video_1sq01sh010",
"handleEnd": 10,
"handleStart": 10,
"has_promised_context": true,
"heroTrack": true,
"hierarchy": "shots/sq01",
"hierarchyData": {
"episode": "ep01",
"folder": "shots",
"sequence": "sq01",
"shot": "sh010",
"track": "Video_1"
},
"id": "pyblish.avalon.instance",
"instance_id": "5109899f-d744-4ed3-8547-8585ef9b703b",
"label": "/shots/sq01/Video_1sq01sh010 shot",
"newAssetPublishing": true,
"newHierarchyIntegration": true,
"parents": [
{
"entity_name": "shots",
"folder_type": "folder"
},
{
"entity_name": "sq01",
"folder_type": "sequence"
}
],
"productName": "shotMain",
"productType": "shot",
"publish_attributes": {
"CollectSlackFamilies": {
"additional_message": ""
}
},
"reviewTrack": null,
"sequence": "sq01",
"shot": "sh###",
"sourceResolution": false,
"task": "Generic",
"track": "{_track_}",
"uuid": "ade94deb-f104-47dc-b8e9-04943f900914",
"variant": "Main",
"workfileFrameStart": 1001
}
}
},
"name": "AyonData",
"color": "GREEN",
"marked_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 1.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 91083.625
}
},
"comment": ""
}
],
"enabled": true,
"media_references": {
"DEFAULT_MEDIA": {
"OTIO_SCHEMA": "ImageSequenceReference.1",
"metadata": {},
"name": "output.[1000-1100].exr",
"available_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 101.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 87399.0
}
},
"available_image_bounds": null,
"target_url_base": "C:\\Users\\robin\\OneDrive\\Bureau\\dev_ayon\\samples\\exr_embedded_tc",
"name_prefix": "output.",
"name_suffix": ".exr",
"start_frame": 1000,
"frame_step": 1,
"rate": 24.0,
"frame_zero_padding": 4,
"missing_frame_policy": "error"
}
},
"active_media_reference_key": "DEFAULT_MEDIA"
}

View file

@ -0,0 +1,363 @@
{
"OTIO_SCHEMA": "Clip.2",
"metadata": {
"Resolve_OTIO": {}
},
"name": "output.[1000-1100].exr",
"source_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 101.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 87399.0
}
},
"effects": [
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Transform",
"Enabled": true,
"Name": "Transform",
"Parameters": [],
"Type": 2
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Cropping",
"Enabled": true,
"Name": "Cropping",
"Parameters": [],
"Type": 3
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Dynamic Zoom",
"Enabled": false,
"Name": "Dynamic Zoom",
"Parameters": [
{
"Default Parameter Value": [
0.0,
0.0
],
"Key Frames": {
"0": {
"Value": [
0.0,
0.0
],
"Variant Type": "POINTF"
},
"1000": {
"Value": [
0.0,
0.0
],
"Variant Type": "POINTF"
}
},
"Parameter ID": "dynamicZoomCenter",
"Parameter Value": [
0.0,
0.0
],
"Variant Type": "POINTF"
},
{
"Default Parameter Value": 1.0,
"Key Frames": {
"0": {
"Value": 0.8,
"Variant Type": "Double"
},
"1000": {
"Value": 1.0,
"Variant Type": "Double"
}
},
"Parameter ID": "dynamicZoomScale",
"Parameter Value": 1.0,
"Variant Type": "Double",
"maxValue": 100.0,
"minValue": 0.01
}
],
"Type": 59
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Composite",
"Enabled": true,
"Name": "Composite",
"Parameters": [],
"Type": 1
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Lens Correction",
"Enabled": true,
"Name": "Lens Correction",
"Parameters": [],
"Type": 43
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Retime and Scaling",
"Enabled": true,
"Name": "Retime and Scaling",
"Parameters": [],
"Type": 22
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Video Faders",
"Enabled": true,
"Name": "Video Faders",
"Parameters": [],
"Type": 36
}
},
"name": "",
"effect_name": "Resolve Effect"
}
],
"markers": [
{
"OTIO_SCHEMA": "Marker.2",
"metadata": {
"Resolve_OTIO": {
"Keywords": [],
"Note": "{\"resolve_sub_products\": {\"io.ayon.creators.resolve.shot\": {\"id\": \"pyblish.avalon.instance\", \"productType\": \"shot\", \"productName\": \"shotMain\", \"active\": true, \"creator_identifier\": \"io.ayon.creators.resolve.shot\", \"variant\": \"Main\", \"folderPath\": \"/shots/seq_img_tc_handles_out/sh010\", \"task\": \"Generic\", \"clip_variant\": \"<track_name>\", \"clip_index\": \"adca7e5b-b53c-48ab-8469-abe4db3c276a\", \"clip_source_resolution\": {\"width\": \"956\", \"height\": \"720\", \"pixelAspect\": 1.0}, \"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"seq_img_tc_handles_out\", \"track\": \"{_track_}\", \"shot\": \"sh###\", \"hierarchy\": \"shots/seq_img_tc_handles_out\", \"sourceResolution\": true, \"workfileFrameStart\": 1001, \"handleStart\": 10, \"handleEnd\": 10, \"parents\": [{\"folder_type\": \"folder\", \"entity_name\": \"shots\"}, {\"folder_type\": \"sequence\", \"entity_name\": \"seq_img_tc_handles_out\"}], \"hierarchyData\": {\"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"seq_img_tc_handles_out\", \"track\": \"Video1\", \"shot\": \"sh010\"}, \"heroTrack\": true, \"uuid\": \"fca94ed7-1e74-4ddc-8d56-05696e8c472a\", \"reviewTrack\": \"Video1\", \"label\": \"/shots/seq_img_tc_handles_out/sh010 shot\", \"has_promised_context\": true, \"newHierarchyIntegration\": true, \"newAssetPublishing\": true, \"instance_id\": \"6c2baba3-183c-41f0-b9a9-596d315fd162\", \"creator_attributes\": {\"folderPath\": \"/shots/seq_img_tc_handles_out/sh010\", \"workfileFrameStart\": 1001, \"handleStart\": 10, \"handleEnd\": 10, \"frameStart\": 1001, \"frameEnd\": 1102, \"clipIn\": 86524, \"clipOut\": 86625, \"clipDuration\": 101, \"sourceIn\": 0, \"sourceOut\": 101, \"fps\": \"from_selection\"}, \"publish_attributes\": {\"CollectSlackFamilies\": {\"additional_message\": \"\"}}}, \"io.ayon.creators.resolve.plate\": {\"id\": \"pyblish.avalon.instance\", \"productType\": \"plate\", \"productName\": \"plateVideo1\", \"active\": true, \"creator_identifier\": \"io.ayon.creators.resolve.plate\", \"variant\": \"Video1\", \"folderPath\": \"/shots/seq_img_tc_handles_out/sh010\", \"task\": \"Generic\", \"clip_variant\": \"<track_name>\", \"clip_index\": \"adca7e5b-b53c-48ab-8469-abe4db3c276a\", \"clip_source_resolution\": {\"width\": \"956\", \"height\": \"720\", \"pixelAspect\": 1.0}, \"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"seq_img_tc_handles_out\", \"track\": \"{_track_}\", \"shot\": \"sh###\", \"hierarchy\": \"shots/seq_img_tc_handles_out\", \"sourceResolution\": true, \"workfileFrameStart\": 1001, \"handleStart\": 10, \"handleEnd\": 10, \"parents\": [{\"folder_type\": \"folder\", \"entity_name\": \"shots\"}, {\"folder_type\": \"sequence\", \"entity_name\": \"seq_img_tc_handles_out\"}], \"hierarchyData\": {\"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"seq_img_tc_handles_out\", \"track\": \"Video1\", \"shot\": \"sh010\"}, \"heroTrack\": true, \"uuid\": \"fca94ed7-1e74-4ddc-8d56-05696e8c472a\", \"reviewTrack\": \"Video1\", \"parent_instance_id\": \"6c2baba3-183c-41f0-b9a9-596d315fd162\", \"label\": \"/shots/seq_img_tc_handles_out/sh010 plate\", \"has_promised_context\": true, \"newHierarchyIntegration\": true, \"newAssetPublishing\": true, \"instance_id\": \"8b1f1e6f-699a-4481-b9be-92d819bc4096\", \"creator_attributes\": {\"parentInstance\": \"/shots/seq_img_tc_handles_out/sh010 shot\", \"vSyncOn\": true, \"vSyncTrack\": \"Video1\"}, \"publish_attributes\": {\"CollectSlackFamilies\": {\"additional_message\": \"\"}}}}, \"clip_index\": \"adca7e5b-b53c-48ab-8469-abe4db3c276a\", \"publish\": true}"
},
"clip_index": "adca7e5b-b53c-48ab-8469-abe4db3c276a",
"publish": true,
"resolve_sub_products": {
"io.ayon.creators.resolve.plate": {
"active": true,
"clip_index": "adca7e5b-b53c-48ab-8469-abe4db3c276a",
"clip_source_resolution": {
"height": "720",
"pixelAspect": 1.0,
"width": "956"
},
"clip_variant": "<track_name>",
"creator_attributes": {
"parentInstance": "/shots/seq_img_tc_handles_out/sh010 shot",
"vSyncOn": true,
"vSyncTrack": "Video1"
},
"creator_identifier": "io.ayon.creators.resolve.plate",
"episode": "ep01",
"folder": "shots",
"folderPath": "/shots/seq_img_tc_handles_out/sh010",
"handleEnd": 10,
"handleStart": 10,
"has_promised_context": true,
"heroTrack": true,
"hierarchy": "shots/seq_img_tc_handles_out",
"hierarchyData": {
"episode": "ep01",
"folder": "shots",
"sequence": "seq_img_tc_handles_out",
"shot": "sh010",
"track": "Video1"
},
"id": "pyblish.avalon.instance",
"instance_id": "8b1f1e6f-699a-4481-b9be-92d819bc4096",
"label": "/shots/seq_img_tc_handles_out/sh010 plate",
"newAssetPublishing": true,
"newHierarchyIntegration": true,
"parent_instance_id": "6c2baba3-183c-41f0-b9a9-596d315fd162",
"parents": [
{
"entity_name": "shots",
"folder_type": "folder"
},
{
"entity_name": "seq_img_tc_handles_out",
"folder_type": "sequence"
}
],
"productName": "plateVideo1",
"productType": "plate",
"publish_attributes": {
"CollectSlackFamilies": {
"additional_message": ""
}
},
"reviewTrack": "Video1",
"sequence": "seq_img_tc_handles_out",
"shot": "sh###",
"sourceResolution": true,
"task": "Generic",
"track": "{_track_}",
"uuid": "fca94ed7-1e74-4ddc-8d56-05696e8c472a",
"variant": "Video1",
"workfileFrameStart": 1001
},
"io.ayon.creators.resolve.shot": {
"active": true,
"clip_index": "adca7e5b-b53c-48ab-8469-abe4db3c276a",
"clip_source_resolution": {
"height": "720",
"pixelAspect": 1.0,
"width": "956"
},
"clip_variant": "<track_name>",
"creator_attributes": {
"clipDuration": 101,
"clipIn": 86524,
"clipOut": 86625,
"folderPath": "/shots/seq_img_tc_handles_out/sh010",
"fps": "from_selection",
"frameEnd": 1102,
"frameStart": 1001,
"handleEnd": 10,
"handleStart": 10,
"sourceIn": 0,
"sourceOut": 101,
"workfileFrameStart": 1001
},
"creator_identifier": "io.ayon.creators.resolve.shot",
"episode": "ep01",
"folder": "shots",
"folderPath": "/shots/seq_img_tc_handles_out/sh010",
"handleEnd": 10,
"handleStart": 10,
"has_promised_context": true,
"heroTrack": true,
"hierarchy": "shots/seq_img_tc_handles_out",
"hierarchyData": {
"episode": "ep01",
"folder": "shots",
"sequence": "seq_img_tc_handles_out",
"shot": "sh010",
"track": "Video1"
},
"id": "pyblish.avalon.instance",
"instance_id": "6c2baba3-183c-41f0-b9a9-596d315fd162",
"label": "/shots/seq_img_tc_handles_out/sh010 shot",
"newAssetPublishing": true,
"newHierarchyIntegration": true,
"parents": [
{
"entity_name": "shots",
"folder_type": "folder"
},
{
"entity_name": "seq_img_tc_handles_out",
"folder_type": "sequence"
}
],
"productName": "shotMain",
"productType": "shot",
"publish_attributes": {
"CollectSlackFamilies": {
"additional_message": ""
}
},
"reviewTrack": "Video1",
"sequence": "seq_img_tc_handles_out",
"shot": "sh###",
"sourceResolution": true,
"task": "Generic",
"track": "{_track_}",
"uuid": "fca94ed7-1e74-4ddc-8d56-05696e8c472a",
"variant": "Main",
"workfileFrameStart": 1001
}
}
},
"name": "AyonData",
"color": "GREEN",
"marked_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 1.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 87449.0
}
},
"comment": ""
}
],
"enabled": true,
"media_references": {
"DEFAULT_MEDIA": {
"OTIO_SCHEMA": "ImageSequenceReference.1",
"metadata": {},
"name": "output.[1000-1100].exr",
"available_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 101.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 87399.0
}
},
"available_image_bounds": null,
"target_url_base": "C:\\exr_embedded_tc",
"name_prefix": "output.",
"name_suffix": ".exr",
"start_frame": 1000,
"frame_step": 1,
"rate": 24.0,
"frame_zero_padding": 4,
"missing_frame_policy": "error"
}
},
"active_media_reference_key": "DEFAULT_MEDIA"
}

View file

@ -0,0 +1,363 @@
{
"OTIO_SCHEMA": "Clip.2",
"metadata": {
"Resolve_OTIO": {}
},
"name": "output.[1000-1100].tif",
"source_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 101.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 0.0
}
},
"effects": [
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Transform",
"Enabled": true,
"Name": "Transform",
"Parameters": [],
"Type": 2
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Cropping",
"Enabled": true,
"Name": "Cropping",
"Parameters": [],
"Type": 3
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Dynamic Zoom",
"Enabled": false,
"Name": "Dynamic Zoom",
"Parameters": [
{
"Default Parameter Value": [
0.0,
0.0
],
"Key Frames": {
"0": {
"Value": [
0.0,
0.0
],
"Variant Type": "POINTF"
},
"1000": {
"Value": [
0.0,
0.0
],
"Variant Type": "POINTF"
}
},
"Parameter ID": "dynamicZoomCenter",
"Parameter Value": [
0.0,
0.0
],
"Variant Type": "POINTF"
},
{
"Default Parameter Value": 1.0,
"Key Frames": {
"0": {
"Value": 0.8,
"Variant Type": "Double"
},
"1000": {
"Value": 1.0,
"Variant Type": "Double"
}
},
"Parameter ID": "dynamicZoomScale",
"Parameter Value": 1.0,
"Variant Type": "Double",
"maxValue": 100.0,
"minValue": 0.01
}
],
"Type": 59
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Composite",
"Enabled": true,
"Name": "Composite",
"Parameters": [],
"Type": 1
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Lens Correction",
"Enabled": true,
"Name": "Lens Correction",
"Parameters": [],
"Type": 43
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Retime and Scaling",
"Enabled": true,
"Name": "Retime and Scaling",
"Parameters": [],
"Type": 22
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Video Faders",
"Enabled": true,
"Name": "Video Faders",
"Parameters": [],
"Type": 36
}
},
"name": "",
"effect_name": "Resolve Effect"
}
],
"markers": [
{
"OTIO_SCHEMA": "Marker.2",
"metadata": {
"Resolve_OTIO": {
"Keywords": [],
"Note": "{\"resolve_sub_products\": {\"io.ayon.creators.resolve.shot\": {\"id\": \"pyblish.avalon.instance\", \"productType\": \"shot\", \"productName\": \"shotMain\", \"active\": true, \"creator_identifier\": \"io.ayon.creators.resolve.shot\", \"variant\": \"Main\", \"folderPath\": \"/shots/sq01/Video_1sq01sh010\", \"task\": \"Generic\", \"clip_variant\": \"<track_name>\", \"clip_index\": \"cfea9be4-3ecd-4253-a0a9-1a2bc9a4a184\", \"clip_source_resolution\": {\"width\": \"1920\", \"height\": \"1080\", \"pixelAspect\": 1.0}, \"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"sq01\", \"track\": \"{_track_}\", \"shot\": \"sh###\", \"hierarchy\": \"shots/sq01\", \"sourceResolution\": false, \"workfileFrameStart\": 1001, \"handleStart\": 10, \"handleEnd\": 10, \"parents\": [{\"folder_type\": \"folder\", \"entity_name\": \"shots\"}, {\"folder_type\": \"sequence\", \"entity_name\": \"sq01\"}], \"hierarchyData\": {\"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"sq01\", \"track\": \"Video_1\", \"shot\": \"sh010\"}, \"heroTrack\": true, \"uuid\": \"647b2ba6-6fca-4219-b163-cd321df9652f\", \"reviewTrack\": null, \"label\": \"/shots/sq01/Video_1sq01sh010 shot\", \"has_promised_context\": true, \"newHierarchyIntegration\": true, \"newAssetPublishing\": true, \"instance_id\": \"2ab8f149-e32c-40f5-a6cb-ad1ca567ccc1\", \"creator_attributes\": {\"folderPath\": \"/shots/sq01/Video_1sq01sh010\", \"workfileFrameStart\": 1001, \"handleStart\": 10, \"handleEnd\": 10, \"frameStart\": 1001, \"frameEnd\": 1102, \"clipIn\": 509, \"clipOut\": 610, \"clipDuration\": 101, \"sourceIn\": 0, \"sourceOut\": 101, \"fps\": \"from_selection\"}, \"publish_attributes\": {\"CollectSlackFamilies\": {\"additional_message\": \"\"}}}, \"io.ayon.creators.resolve.plate\": {\"id\": \"pyblish.avalon.instance\", \"productType\": \"plate\", \"productName\": \"plateVideo_1\", \"active\": true, \"creator_identifier\": \"io.ayon.creators.resolve.plate\", \"variant\": \"Video_1\", \"folderPath\": \"/shots/sq01/Video_1sq01sh010\", \"task\": \"Generic\", \"clip_variant\": \"<track_name>\", \"clip_index\": \"cfea9be4-3ecd-4253-a0a9-1a2bc9a4a184\", \"clip_source_resolution\": {\"width\": \"1920\", \"height\": \"1080\", \"pixelAspect\": 1.0}, \"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"sq01\", \"track\": \"{_track_}\", \"shot\": \"sh###\", \"hierarchy\": \"shots/sq01\", \"sourceResolution\": false, \"workfileFrameStart\": 1001, \"handleStart\": 10, \"handleEnd\": 10, \"parents\": [{\"folder_type\": \"folder\", \"entity_name\": \"shots\"}, {\"folder_type\": \"sequence\", \"entity_name\": \"sq01\"}], \"hierarchyData\": {\"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"sq01\", \"track\": \"Video_1\", \"shot\": \"sh010\"}, \"heroTrack\": true, \"uuid\": \"647b2ba6-6fca-4219-b163-cd321df9652f\", \"reviewTrack\": null, \"parent_instance_id\": \"2ab8f149-e32c-40f5-a6cb-ad1ca567ccc1\", \"label\": \"/shots/sq01/Video_1sq01sh010 plate\", \"has_promised_context\": true, \"newHierarchyIntegration\": true, \"newAssetPublishing\": true, \"instance_id\": \"9f866936-966b-4a73-8e61-1a5b6e648a3f\", \"creator_attributes\": {\"parentInstance\": \"/shots/sq01/Video_1sq01sh010 shot\", \"vSyncOn\": false, \"vSyncTrack\": \"Video 1\"}, \"publish_attributes\": {\"CollectSlackFamilies\": {\"additional_message\": \"\"}}}}, \"clip_index\": \"cfea9be4-3ecd-4253-a0a9-1a2bc9a4a184\", \"publish\": true}"
},
"clip_index": "cfea9be4-3ecd-4253-a0a9-1a2bc9a4a184",
"publish": true,
"resolve_sub_products": {
"io.ayon.creators.resolve.plate": {
"active": true,
"clip_index": "cfea9be4-3ecd-4253-a0a9-1a2bc9a4a184",
"clip_source_resolution": {
"height": "1080",
"pixelAspect": 1.0,
"width": "1920"
},
"clip_variant": "<track_name>",
"creator_attributes": {
"parentInstance": "/shots/sq01/Video_1sq01sh010 shot",
"vSyncOn": false,
"vSyncTrack": "Video 1"
},
"creator_identifier": "io.ayon.creators.resolve.plate",
"episode": "ep01",
"folder": "shots",
"folderPath": "/shots/sq01/Video_1sq01sh010",
"handleEnd": 10,
"handleStart": 10,
"has_promised_context": true,
"heroTrack": true,
"hierarchy": "shots/sq01",
"hierarchyData": {
"episode": "ep01",
"folder": "shots",
"sequence": "sq01",
"shot": "sh010",
"track": "Video_1"
},
"id": "pyblish.avalon.instance",
"instance_id": "9f866936-966b-4a73-8e61-1a5b6e648a3f",
"label": "/shots/sq01/Video_1sq01sh010 plate",
"newAssetPublishing": true,
"newHierarchyIntegration": true,
"parent_instance_id": "2ab8f149-e32c-40f5-a6cb-ad1ca567ccc1",
"parents": [
{
"entity_name": "shots",
"folder_type": "folder"
},
{
"entity_name": "sq01",
"folder_type": "sequence"
}
],
"productName": "plateVideo_1",
"productType": "plate",
"publish_attributes": {
"CollectSlackFamilies": {
"additional_message": ""
}
},
"reviewTrack": null,
"sequence": "sq01",
"shot": "sh###",
"sourceResolution": false,
"task": "Generic",
"track": "{_track_}",
"uuid": "647b2ba6-6fca-4219-b163-cd321df9652f",
"variant": "Video_1",
"workfileFrameStart": 1001
},
"io.ayon.creators.resolve.shot": {
"active": true,
"clip_index": "cfea9be4-3ecd-4253-a0a9-1a2bc9a4a184",
"clip_source_resolution": {
"height": "1080",
"pixelAspect": 1.0,
"width": "1920"
},
"clip_variant": "<track_name>",
"creator_attributes": {
"clipDuration": 101,
"clipIn": 509,
"clipOut": 610,
"folderPath": "/shots/sq01/Video_1sq01sh010",
"fps": "from_selection",
"frameEnd": 1102,
"frameStart": 1001,
"handleEnd": 10,
"handleStart": 10,
"sourceIn": 0,
"sourceOut": 101,
"workfileFrameStart": 1001
},
"creator_identifier": "io.ayon.creators.resolve.shot",
"episode": "ep01",
"folder": "shots",
"folderPath": "/shots/sq01/Video_1sq01sh010",
"handleEnd": 10,
"handleStart": 10,
"has_promised_context": true,
"heroTrack": true,
"hierarchy": "shots/sq01",
"hierarchyData": {
"episode": "ep01",
"folder": "shots",
"sequence": "sq01",
"shot": "sh010",
"track": "Video_1"
},
"id": "pyblish.avalon.instance",
"instance_id": "2ab8f149-e32c-40f5-a6cb-ad1ca567ccc1",
"label": "/shots/sq01/Video_1sq01sh010 shot",
"newAssetPublishing": true,
"newHierarchyIntegration": true,
"parents": [
{
"entity_name": "shots",
"folder_type": "folder"
},
{
"entity_name": "sq01",
"folder_type": "sequence"
}
],
"productName": "shotMain",
"productType": "shot",
"publish_attributes": {
"CollectSlackFamilies": {
"additional_message": ""
}
},
"reviewTrack": null,
"sequence": "sq01",
"shot": "sh###",
"sourceResolution": false,
"task": "Generic",
"track": "{_track_}",
"uuid": "647b2ba6-6fca-4219-b163-cd321df9652f",
"variant": "Main",
"workfileFrameStart": 1001
}
}
},
"name": "AyonData",
"color": "GREEN",
"marked_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 1.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 50.0
}
},
"comment": ""
}
],
"enabled": true,
"media_references": {
"DEFAULT_MEDIA": {
"OTIO_SCHEMA": "ImageSequenceReference.1",
"metadata": {},
"name": "output.[1000-1100].tif",
"available_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 101.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 0.0
}
},
"available_image_bounds": null,
"target_url_base": "C:\\Users\\robin\\OneDrive\\Bureau\\dev_ayon\\samples",
"name_prefix": "output.",
"name_suffix": ".tif",
"start_frame": 1000,
"frame_step": 1,
"rate": 25.0,
"frame_zero_padding": 4,
"missing_frame_policy": "error"
}
},
"active_media_reference_key": "DEFAULT_MEDIA"
}

View file

@ -0,0 +1,363 @@
{
"OTIO_SCHEMA": "Clip.2",
"metadata": {
"Resolve_OTIO": {}
},
"name": "output.[1000-1100].tif",
"source_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 91.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 5.0
}
},
"effects": [
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Transform",
"Enabled": true,
"Name": "Transform",
"Parameters": [],
"Type": 2
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Cropping",
"Enabled": true,
"Name": "Cropping",
"Parameters": [],
"Type": 3
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Dynamic Zoom",
"Enabled": false,
"Name": "Dynamic Zoom",
"Parameters": [
{
"Default Parameter Value": [
0.0,
0.0
],
"Key Frames": {
"-5": {
"Value": [
0.0,
0.0
],
"Variant Type": "POINTF"
},
"955": {
"Value": [
0.0,
0.0
],
"Variant Type": "POINTF"
}
},
"Parameter ID": "dynamicZoomCenter",
"Parameter Value": [
0.0,
0.0
],
"Variant Type": "POINTF"
},
{
"Default Parameter Value": 1.0,
"Key Frames": {
"-5": {
"Value": 0.8,
"Variant Type": "Double"
},
"955": {
"Value": 1.0,
"Variant Type": "Double"
}
},
"Parameter ID": "dynamicZoomScale",
"Parameter Value": 1.0,
"Variant Type": "Double",
"maxValue": 100.0,
"minValue": 0.01
}
],
"Type": 59
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Composite",
"Enabled": true,
"Name": "Composite",
"Parameters": [],
"Type": 1
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Lens Correction",
"Enabled": true,
"Name": "Lens Correction",
"Parameters": [],
"Type": 43
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Retime and Scaling",
"Enabled": true,
"Name": "Retime and Scaling",
"Parameters": [],
"Type": 22
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Video Faders",
"Enabled": true,
"Name": "Video Faders",
"Parameters": [],
"Type": 36
}
},
"name": "",
"effect_name": "Resolve Effect"
}
],
"markers": [
{
"OTIO_SCHEMA": "Marker.2",
"metadata": {
"Resolve_OTIO": {
"Keywords": [],
"Note": "{\"resolve_sub_products\": {\"io.ayon.creators.resolve.shot\": {\"id\": \"pyblish.avalon.instance\", \"productType\": \"shot\", \"productName\": \"shotMain\", \"active\": true, \"creator_identifier\": \"io.ayon.creators.resolve.shot\", \"variant\": \"Main\", \"folderPath\": \"/shots/seq_img_notc_blackhandles/sh010\", \"task\": \"Generic\", \"clip_variant\": \"<track_name>\", \"clip_index\": \"a82520bd-f231-4a23-9cb7-8823141232db\", \"clip_source_resolution\": {\"width\": \"1920\", \"height\": \"1080\", \"pixelAspect\": 1.0}, \"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"seq_img_notc_blackhandles\", \"track\": \"{_track_}\", \"shot\": \"sh###\", \"hierarchy\": \"shots/seq_img_notc_blackhandles\", \"sourceResolution\": false, \"workfileFrameStart\": 1001, \"handleStart\": 10, \"handleEnd\": 10, \"parents\": [{\"folder_type\": \"folder\", \"entity_name\": \"shots\"}, {\"folder_type\": \"sequence\", \"entity_name\": \"seq_img_notc_blackhandles\"}], \"hierarchyData\": {\"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"seq_img_notc_blackhandles\", \"track\": \"Video1\", \"shot\": \"sh010\"}, \"heroTrack\": true, \"uuid\": \"5d6be326-f1d0-4416-b6aa-780d05a8dd6d\", \"reviewTrack\": \"Video1\", \"label\": \"/shots/seq_img_notc_blackhandles/sh010 shot\", \"has_promised_context\": true, \"newHierarchyIntegration\": true, \"newAssetPublishing\": true, \"instance_id\": \"e196263f-c584-40b4-bc27-018051a3bc92\", \"creator_attributes\": {\"folderPath\": \"/shots/seq_img_notc_blackhandles/sh010\", \"workfileFrameStart\": 1001, \"handleStart\": 10, \"handleEnd\": 10, \"frameStart\": 1001, \"frameEnd\": 1092, \"clipIn\": 86511, \"clipOut\": 86602, \"clipDuration\": 91, \"sourceIn\": 5, \"sourceOut\": 96, \"fps\": \"from_selection\"}, \"publish_attributes\": {\"CollectSlackFamilies\": {\"additional_message\": \"\"}}}, \"io.ayon.creators.resolve.plate\": {\"id\": \"pyblish.avalon.instance\", \"productType\": \"plate\", \"productName\": \"plateVideo1\", \"active\": true, \"creator_identifier\": \"io.ayon.creators.resolve.plate\", \"variant\": \"Video1\", \"folderPath\": \"/shots/seq_img_notc_blackhandles/sh010\", \"task\": \"Generic\", \"clip_variant\": \"<track_name>\", \"clip_index\": \"a82520bd-f231-4a23-9cb7-8823141232db\", \"clip_source_resolution\": {\"width\": \"1920\", \"height\": \"1080\", \"pixelAspect\": 1.0}, \"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"seq_img_notc_blackhandles\", \"track\": \"{_track_}\", \"shot\": \"sh###\", \"hierarchy\": \"shots/seq_img_notc_blackhandles\", \"sourceResolution\": false, \"workfileFrameStart\": 1001, \"handleStart\": 10, \"handleEnd\": 10, \"parents\": [{\"folder_type\": \"folder\", \"entity_name\": \"shots\"}, {\"folder_type\": \"sequence\", \"entity_name\": \"seq_img_notc_blackhandles\"}], \"hierarchyData\": {\"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"seq_img_notc_blackhandles\", \"track\": \"Video1\", \"shot\": \"sh010\"}, \"heroTrack\": true, \"uuid\": \"5d6be326-f1d0-4416-b6aa-780d05a8dd6d\", \"reviewTrack\": \"Video1\", \"parent_instance_id\": \"e196263f-c584-40b4-bc27-018051a3bc92\", \"label\": \"/shots/seq_img_notc_blackhandles/sh010 plate\", \"has_promised_context\": true, \"newHierarchyIntegration\": true, \"newAssetPublishing\": true, \"instance_id\": \"ced7e9b8-721a-4377-a827-15fbf7f2831a\", \"creator_attributes\": {\"parentInstance\": \"/shots/seq_img_notc_blackhandles/sh010 shot\", \"vSyncOn\": true, \"vSyncTrack\": \"Video1\"}, \"publish_attributes\": {\"CollectSlackFamilies\": {\"additional_message\": \"\"}}}}, \"clip_index\": \"a82520bd-f231-4a23-9cb7-8823141232db\", \"publish\": true}"
},
"clip_index": "a82520bd-f231-4a23-9cb7-8823141232db",
"publish": true,
"resolve_sub_products": {
"io.ayon.creators.resolve.plate": {
"active": true,
"clip_index": "a82520bd-f231-4a23-9cb7-8823141232db",
"clip_source_resolution": {
"height": "1080",
"pixelAspect": 1.0,
"width": "1920"
},
"clip_variant": "<track_name>",
"creator_attributes": {
"parentInstance": "/shots/seq_img_notc_blackhandles/sh010 shot",
"vSyncOn": true,
"vSyncTrack": "Video1"
},
"creator_identifier": "io.ayon.creators.resolve.plate",
"episode": "ep01",
"folder": "shots",
"folderPath": "/shots/seq_img_notc_blackhandles/sh010",
"handleEnd": 10,
"handleStart": 10,
"has_promised_context": true,
"heroTrack": true,
"hierarchy": "shots/seq_img_notc_blackhandles",
"hierarchyData": {
"episode": "ep01",
"folder": "shots",
"sequence": "seq_img_notc_blackhandles",
"shot": "sh010",
"track": "Video1"
},
"id": "pyblish.avalon.instance",
"instance_id": "ced7e9b8-721a-4377-a827-15fbf7f2831a",
"label": "/shots/seq_img_notc_blackhandles/sh010 plate",
"newAssetPublishing": true,
"newHierarchyIntegration": true,
"parent_instance_id": "e196263f-c584-40b4-bc27-018051a3bc92",
"parents": [
{
"entity_name": "shots",
"folder_type": "folder"
},
{
"entity_name": "seq_img_notc_blackhandles",
"folder_type": "sequence"
}
],
"productName": "plateVideo1",
"productType": "plate",
"publish_attributes": {
"CollectSlackFamilies": {
"additional_message": ""
}
},
"reviewTrack": "Video1",
"sequence": "seq_img_notc_blackhandles",
"shot": "sh###",
"sourceResolution": false,
"task": "Generic",
"track": "{_track_}",
"uuid": "5d6be326-f1d0-4416-b6aa-780d05a8dd6d",
"variant": "Video1",
"workfileFrameStart": 1001
},
"io.ayon.creators.resolve.shot": {
"active": true,
"clip_index": "a82520bd-f231-4a23-9cb7-8823141232db",
"clip_source_resolution": {
"height": "1080",
"pixelAspect": 1.0,
"width": "1920"
},
"clip_variant": "<track_name>",
"creator_attributes": {
"clipDuration": 91,
"clipIn": 86511,
"clipOut": 86602,
"folderPath": "/shots/seq_img_notc_blackhandles/sh010",
"fps": "from_selection",
"frameEnd": 1092,
"frameStart": 1001,
"handleEnd": 10,
"handleStart": 10,
"sourceIn": 5,
"sourceOut": 96,
"workfileFrameStart": 1001
},
"creator_identifier": "io.ayon.creators.resolve.shot",
"episode": "ep01",
"folder": "shots",
"folderPath": "/shots/seq_img_notc_blackhandles/sh010",
"handleEnd": 10,
"handleStart": 10,
"has_promised_context": true,
"heroTrack": true,
"hierarchy": "shots/seq_img_notc_blackhandles",
"hierarchyData": {
"episode": "ep01",
"folder": "shots",
"sequence": "seq_img_notc_blackhandles",
"shot": "sh010",
"track": "Video1"
},
"id": "pyblish.avalon.instance",
"instance_id": "e196263f-c584-40b4-bc27-018051a3bc92",
"label": "/shots/seq_img_notc_blackhandles/sh010 shot",
"newAssetPublishing": true,
"newHierarchyIntegration": true,
"parents": [
{
"entity_name": "shots",
"folder_type": "folder"
},
{
"entity_name": "seq_img_notc_blackhandles",
"folder_type": "sequence"
}
],
"productName": "shotMain",
"productType": "shot",
"publish_attributes": {
"CollectSlackFamilies": {
"additional_message": ""
}
},
"reviewTrack": "Video1",
"sequence": "seq_img_notc_blackhandles",
"shot": "sh###",
"sourceResolution": false,
"task": "Generic",
"track": "{_track_}",
"uuid": "5d6be326-f1d0-4416-b6aa-780d05a8dd6d",
"variant": "Main",
"workfileFrameStart": 1001
}
}
},
"name": "AyonData",
"color": "GREEN",
"marked_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 1.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 50.0
}
},
"comment": ""
}
],
"enabled": true,
"media_references": {
"DEFAULT_MEDIA": {
"OTIO_SCHEMA": "ImageSequenceReference.1",
"metadata": {},
"name": "output.[1000-1100].tif",
"available_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 101.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 0.0
}
},
"available_image_bounds": null,
"target_url_base": "C:\\tif_seq",
"name_prefix": "output.",
"name_suffix": ".tif",
"start_frame": 1000,
"frame_step": 1,
"rate": 25.0,
"frame_zero_padding": 4,
"missing_frame_policy": "error"
}
},
"active_media_reference_key": "DEFAULT_MEDIA"
}

View file

@ -0,0 +1,363 @@
{
"OTIO_SCHEMA": "Clip.2",
"metadata": {
"Resolve_OTIO": {}
},
"name": "output.[1000-1100].tif",
"source_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 39.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 34.0
}
},
"effects": [
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Transform",
"Enabled": true,
"Name": "Transform",
"Parameters": [],
"Type": 2
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Cropping",
"Enabled": true,
"Name": "Cropping",
"Parameters": [],
"Type": 3
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Dynamic Zoom",
"Enabled": false,
"Name": "Dynamic Zoom",
"Parameters": [
{
"Default Parameter Value": [
0.0,
0.0
],
"Key Frames": {
"-34": {
"Value": [
0.0,
0.0
],
"Variant Type": "POINTF"
},
"966": {
"Value": [
0.0,
0.0
],
"Variant Type": "POINTF"
}
},
"Parameter ID": "dynamicZoomCenter",
"Parameter Value": [
0.0,
0.0
],
"Variant Type": "POINTF"
},
{
"Default Parameter Value": 1.0,
"Key Frames": {
"-34": {
"Value": 0.8,
"Variant Type": "Double"
},
"966": {
"Value": 1.0,
"Variant Type": "Double"
}
},
"Parameter ID": "dynamicZoomScale",
"Parameter Value": 1.0,
"Variant Type": "Double",
"maxValue": 100.0,
"minValue": 0.01
}
],
"Type": 59
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Composite",
"Enabled": true,
"Name": "Composite",
"Parameters": [],
"Type": 1
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Lens Correction",
"Enabled": true,
"Name": "Lens Correction",
"Parameters": [],
"Type": 43
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Retime and Scaling",
"Enabled": true,
"Name": "Retime and Scaling",
"Parameters": [],
"Type": 22
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Video Faders",
"Enabled": true,
"Name": "Video Faders",
"Parameters": [],
"Type": 36
}
},
"name": "",
"effect_name": "Resolve Effect"
}
],
"markers": [
{
"OTIO_SCHEMA": "Marker.2",
"metadata": {
"Resolve_OTIO": {
"Keywords": [],
"Note": "{\"resolve_sub_products\": {\"io.ayon.creators.resolve.shot\": {\"id\": \"pyblish.avalon.instance\", \"productType\": \"shot\", \"productName\": \"shotMain\", \"active\": true, \"creator_identifier\": \"io.ayon.creators.resolve.shot\", \"variant\": \"Main\", \"folderPath\": \"/shots/sq01/Video_1sq01sh010\", \"task\": \"Generic\", \"clip_variant\": \"<track_name>\", \"clip_index\": \"cfea9be4-3ecd-4253-a0a9-1a2bc9a4a184\", \"clip_source_resolution\": {\"width\": \"1920\", \"height\": \"1080\", \"pixelAspect\": 1.0}, \"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"sq01\", \"track\": \"{_track_}\", \"shot\": \"sh###\", \"hierarchy\": \"shots/sq01\", \"sourceResolution\": false, \"workfileFrameStart\": 1001, \"handleStart\": 10, \"handleEnd\": 10, \"parents\": [{\"folder_type\": \"folder\", \"entity_name\": \"shots\"}, {\"folder_type\": \"sequence\", \"entity_name\": \"sq01\"}], \"hierarchyData\": {\"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"sq01\", \"track\": \"Video_1\", \"shot\": \"sh010\"}, \"heroTrack\": true, \"uuid\": \"5ca7b240-ec4c-49d1-841d-a96c33a08b1b\", \"reviewTrack\": null, \"label\": \"/shots/sq01/Video_1sq01sh010 shot\", \"has_promised_context\": true, \"newHierarchyIntegration\": true, \"newAssetPublishing\": true, \"instance_id\": \"5b526964-5805-4412-af09-2da696c4978b\", \"creator_attributes\": {\"folderPath\": \"/shots/sq01/Video_1sq01sh010\", \"workfileFrameStart\": 1001, \"handleStart\": 10, \"handleEnd\": 10, \"frameStart\": 1001, \"frameEnd\": 1040, \"clipIn\": 543, \"clipOut\": 582, \"clipDuration\": 39, \"sourceIn\": 34, \"sourceOut\": 73, \"fps\": \"from_selection\"}, \"publish_attributes\": {\"CollectSlackFamilies\": {\"additional_message\": \"\"}}}, \"io.ayon.creators.resolve.plate\": {\"id\": \"pyblish.avalon.instance\", \"productType\": \"plate\", \"productName\": \"plateVideo_1\", \"active\": true, \"creator_identifier\": \"io.ayon.creators.resolve.plate\", \"variant\": \"Video_1\", \"folderPath\": \"/shots/sq01/Video_1sq01sh010\", \"task\": \"Generic\", \"clip_variant\": \"<track_name>\", \"clip_index\": \"cfea9be4-3ecd-4253-a0a9-1a2bc9a4a184\", \"clip_source_resolution\": {\"width\": \"1920\", \"height\": \"1080\", \"pixelAspect\": 1.0}, \"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"sq01\", \"track\": \"{_track_}\", \"shot\": \"sh###\", \"hierarchy\": \"shots/sq01\", \"sourceResolution\": false, \"workfileFrameStart\": 1001, \"handleStart\": 10, \"handleEnd\": 10, \"parents\": [{\"folder_type\": \"folder\", \"entity_name\": \"shots\"}, {\"folder_type\": \"sequence\", \"entity_name\": \"sq01\"}], \"hierarchyData\": {\"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"sq01\", \"track\": \"Video_1\", \"shot\": \"sh010\"}, \"heroTrack\": true, \"uuid\": \"5ca7b240-ec4c-49d1-841d-a96c33a08b1b\", \"reviewTrack\": null, \"parent_instance_id\": \"5b526964-5805-4412-af09-2da696c4978b\", \"label\": \"/shots/sq01/Video_1sq01sh010 plate\", \"has_promised_context\": true, \"newHierarchyIntegration\": true, \"newAssetPublishing\": true, \"instance_id\": \"992ab293-943b-4894-8a7f-c42b54b4d582\", \"creator_attributes\": {\"parentInstance\": \"/shots/sq01/Video_1sq01sh010 shot\", \"vSyncOn\": false, \"vSyncTrack\": \"Video 1\"}, \"publish_attributes\": {\"CollectSlackFamilies\": {\"additional_message\": \"\"}}}}, \"clip_index\": \"cfea9be4-3ecd-4253-a0a9-1a2bc9a4a184\", \"publish\": true}"
},
"clip_index": "cfea9be4-3ecd-4253-a0a9-1a2bc9a4a184",
"publish": true,
"resolve_sub_products": {
"io.ayon.creators.resolve.plate": {
"active": true,
"clip_index": "cfea9be4-3ecd-4253-a0a9-1a2bc9a4a184",
"clip_source_resolution": {
"height": "1080",
"pixelAspect": 1.0,
"width": "1920"
},
"clip_variant": "<track_name>",
"creator_attributes": {
"parentInstance": "/shots/sq01/Video_1sq01sh010 shot",
"vSyncOn": false,
"vSyncTrack": "Video 1"
},
"creator_identifier": "io.ayon.creators.resolve.plate",
"episode": "ep01",
"folder": "shots",
"folderPath": "/shots/sq01/Video_1sq01sh010",
"handleEnd": 10,
"handleStart": 10,
"has_promised_context": true,
"heroTrack": true,
"hierarchy": "shots/sq01",
"hierarchyData": {
"episode": "ep01",
"folder": "shots",
"sequence": "sq01",
"shot": "sh010",
"track": "Video_1"
},
"id": "pyblish.avalon.instance",
"instance_id": "992ab293-943b-4894-8a7f-c42b54b4d582",
"label": "/shots/sq01/Video_1sq01sh010 plate",
"newAssetPublishing": true,
"newHierarchyIntegration": true,
"parent_instance_id": "5b526964-5805-4412-af09-2da696c4978b",
"parents": [
{
"entity_name": "shots",
"folder_type": "folder"
},
{
"entity_name": "sq01",
"folder_type": "sequence"
}
],
"productName": "plateVideo_1",
"productType": "plate",
"publish_attributes": {
"CollectSlackFamilies": {
"additional_message": ""
}
},
"reviewTrack": null,
"sequence": "sq01",
"shot": "sh###",
"sourceResolution": false,
"task": "Generic",
"track": "{_track_}",
"uuid": "5ca7b240-ec4c-49d1-841d-a96c33a08b1b",
"variant": "Video_1",
"workfileFrameStart": 1001
},
"io.ayon.creators.resolve.shot": {
"active": true,
"clip_index": "cfea9be4-3ecd-4253-a0a9-1a2bc9a4a184",
"clip_source_resolution": {
"height": "1080",
"pixelAspect": 1.0,
"width": "1920"
},
"clip_variant": "<track_name>",
"creator_attributes": {
"clipDuration": 39,
"clipIn": 543,
"clipOut": 582,
"folderPath": "/shots/sq01/Video_1sq01sh010",
"fps": "from_selection",
"frameEnd": 1040,
"frameStart": 1001,
"handleEnd": 10,
"handleStart": 10,
"sourceIn": 34,
"sourceOut": 73,
"workfileFrameStart": 1001
},
"creator_identifier": "io.ayon.creators.resolve.shot",
"episode": "ep01",
"folder": "shots",
"folderPath": "/shots/sq01/Video_1sq01sh010",
"handleEnd": 10,
"handleStart": 10,
"has_promised_context": true,
"heroTrack": true,
"hierarchy": "shots/sq01",
"hierarchyData": {
"episode": "ep01",
"folder": "shots",
"sequence": "sq01",
"shot": "sh010",
"track": "Video_1"
},
"id": "pyblish.avalon.instance",
"instance_id": "5b526964-5805-4412-af09-2da696c4978b",
"label": "/shots/sq01/Video_1sq01sh010 shot",
"newAssetPublishing": true,
"newHierarchyIntegration": true,
"parents": [
{
"entity_name": "shots",
"folder_type": "folder"
},
{
"entity_name": "sq01",
"folder_type": "sequence"
}
],
"productName": "shotMain",
"productType": "shot",
"publish_attributes": {
"CollectSlackFamilies": {
"additional_message": ""
}
},
"reviewTrack": null,
"sequence": "sq01",
"shot": "sh###",
"sourceResolution": false,
"task": "Generic",
"track": "{_track_}",
"uuid": "5ca7b240-ec4c-49d1-841d-a96c33a08b1b",
"variant": "Main",
"workfileFrameStart": 1001
}
}
},
"name": "AyonData",
"color": "GREEN",
"marked_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 1.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 53.0
}
},
"comment": ""
}
],
"enabled": true,
"media_references": {
"DEFAULT_MEDIA": {
"OTIO_SCHEMA": "ImageSequenceReference.1",
"metadata": {},
"name": "output.[1000-1100].tif",
"available_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 101.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 0.0
}
},
"available_image_bounds": null,
"target_url_base": "C:\\Users\\robin\\OneDrive\\Bureau\\dev_ayon\\samples",
"name_prefix": "output.",
"name_suffix": ".tif",
"start_frame": 1000,
"frame_step": 1,
"rate": 25.0,
"frame_zero_padding": 4,
"missing_frame_policy": "error"
}
},
"active_media_reference_key": "DEFAULT_MEDIA"
}

View file

@ -0,0 +1,216 @@
{
"OTIO_SCHEMA": "Clip.2",
"metadata": {},
"name": "output.[1000-1100].exr",
"source_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 104.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 0.0
}
},
"effects": [],
"markers": [
{
"OTIO_SCHEMA": "Marker.2",
"metadata": {
"clip_index": "18b19490-21ea-4533-9e0c-03f434c66f14",
"publish": true,
"resolve_sub_products": {
"io.ayon.creators.resolve.plate": {
"active": true,
"clip_index": "18b19490-21ea-4533-9e0c-03f434c66f14",
"clip_source_resolution": {
"height": "720",
"pixelAspect": 1.0,
"width": "956"
},
"clip_variant": "<track_name>",
"creator_attributes": {
"parentInstance": "/shots/sq_old_otio/sh010 shot",
"vSyncOn": true,
"vSyncTrack": "Video 1"
},
"creator_identifier": "io.ayon.creators.resolve.plate",
"episode": "ep01",
"folder": "/shots/sq_old_otio/sh010",
"folderPath": "/shots/sq_old_otio/sh010",
"handleEnd": 10,
"handleStart": 10,
"has_promised_context": true,
"heroTrack": true,
"hierarchy": "shots/sq_old_otio",
"hierarchyData": {
"episode": "ep01",
"folder": "shots",
"sequence": "sq_old_otio",
"shot": "sh010",
"track": "Video_1"
},
"id": "pyblish.avalon.instance",
"instance_id": "d27c5f77-7218-44ca-8061-5b6d33f96116",
"label": "/shots/sq_old_otio/sh010 plate",
"newAssetPublishing": true,
"newHierarchyIntegration": true,
"parent_instance_id": "24792946-9ac4-4c8d-922f-80a83dea4be1",
"parents": [
{
"entity_name": "shots",
"folder_type": "folder"
},
{
"entity_name": "sq_old_otio",
"folder_type": "sequence"
}
],
"productName": "plateVideo_1",
"productType": "plate",
"publish_attributes": {
"CollectSlackFamilies": {
"additional_message": ""
}
},
"reviewTrack": "Video 1",
"sequence": "sq_old_otio",
"shot": "sh###",
"sourceResolution": false,
"task": null,
"track": "{_track_}",
"uuid": "dec1a40b-7ce8-43cd-94b8-08a53056a171",
"variant": "Video_1",
"workfileFrameStart": 1001
},
"io.ayon.creators.resolve.shot": {
"active": true,
"clip_index": "18b19490-21ea-4533-9e0c-03f434c66f14",
"clip_source_resolution": {
"height": "720",
"pixelAspect": 1.0,
"width": "956"
},
"clip_variant": "<track_name>",
"creator_attributes": {
"clipDuration": 104,
"clipIn": 90000,
"clipOut": 90104,
"fps": "from_selection",
"frameEnd": 1105,
"frameStart": 1001,
"handleEnd": 10,
"handleStart": 10,
"sourceIn": 0,
"sourceOut": 104,
"workfileFrameStart": 1001
},
"creator_identifier": "io.ayon.creators.resolve.shot",
"episode": "ep01",
"folder": "/shots/sq_old_otio/sh010",
"folderPath": "/shots/sq_old_otio/sh010",
"handleEnd": 10,
"handleStart": 10,
"has_promised_context": true,
"heroTrack": true,
"hierarchy": "shots/sq_old_otio",
"hierarchyData": {
"episode": "ep01",
"folder": "shots",
"sequence": "sq_old_otio",
"shot": "sh010",
"track": "Video_1"
},
"id": "pyblish.avalon.instance",
"instance_id": "24792946-9ac4-4c8d-922f-80a83dea4be1",
"label": "/shots/sq_old_otio/sh010 shot",
"newAssetPublishing": true,
"newHierarchyIntegration": true,
"parents": [
{
"entity_name": "shots",
"folder_type": "folder"
},
{
"entity_name": "sq_old_otio",
"folder_type": "sequence"
}
],
"productName": "shotMain",
"productType": "shot",
"publish_attributes": {
"CollectSlackFamilies": {
"additional_message": ""
}
},
"reviewTrack": "Video 1",
"sequence": "sq_old_otio",
"shot": "sh###",
"sourceResolution": false,
"task": null,
"track": "{_track_}",
"uuid": "dec1a40b-7ce8-43cd-94b8-08a53056a171",
"variant": "Main",
"workfileFrameStart": 1001
}
}
},
"name": "AYONData",
"color": "MINT",
"marked_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 1.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 52.0
}
},
"comment": ""
}
],
"enabled": true,
"media_references": {
"DEFAULT_MEDIA": {
"OTIO_SCHEMA": "ImageSequenceReference.1",
"metadata": {
"height": 720,
"isSequence": true,
"padding": 4,
"pixelAspect": 1.0,
"width": 956
},
"name": "",
"available_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 101.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 1000.0
}
},
"available_image_bounds": null,
"target_url_base": "C:\\legacy\\",
"name_prefix": "output.",
"name_suffix": ".exr",
"start_frame": 1000,
"frame_step": 1,
"rate": 24.0,
"frame_zero_padding": 4,
"missing_frame_policy": "error"
}
},
"active_media_reference_key": "DEFAULT_MEDIA"
}

View file

@ -0,0 +1,358 @@
{
"OTIO_SCHEMA": "Clip.2",
"metadata": {
"Resolve_OTIO": {
"Link Group ID": 1
}
},
"name": "simple_editorial_setup.mp4",
"source_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 171.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 0.0
}
},
"effects": [
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Transform",
"Enabled": true,
"Name": "Transform",
"Parameters": [],
"Type": 2
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Cropping",
"Enabled": true,
"Name": "Cropping",
"Parameters": [],
"Type": 3
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Dynamic Zoom",
"Enabled": false,
"Name": "Dynamic Zoom",
"Parameters": [
{
"Default Parameter Value": [
0.0,
0.0
],
"Key Frames": {
"0": {
"Value": [
0.0,
0.0
],
"Variant Type": "POINTF"
},
"1000": {
"Value": [
0.0,
0.0
],
"Variant Type": "POINTF"
}
},
"Parameter ID": "dynamicZoomCenter",
"Parameter Value": [
0.0,
0.0
],
"Variant Type": "POINTF"
},
{
"Default Parameter Value": 1.0,
"Key Frames": {
"0": {
"Value": 0.8,
"Variant Type": "Double"
},
"1000": {
"Value": 1.0,
"Variant Type": "Double"
}
},
"Parameter ID": "dynamicZoomScale",
"Parameter Value": 1.0,
"Variant Type": "Double",
"maxValue": 100.0,
"minValue": 0.01
}
],
"Type": 59
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Composite",
"Enabled": true,
"Name": "Composite",
"Parameters": [],
"Type": 1
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Lens Correction",
"Enabled": true,
"Name": "Lens Correction",
"Parameters": [],
"Type": 43
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Retime and Scaling",
"Enabled": true,
"Name": "Retime and Scaling",
"Parameters": [],
"Type": 22
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Video Faders",
"Enabled": true,
"Name": "Video Faders",
"Parameters": [],
"Type": 36
}
},
"name": "",
"effect_name": "Resolve Effect"
}
],
"markers": [
{
"OTIO_SCHEMA": "Marker.2",
"metadata": {
"Resolve_OTIO": {
"Keywords": [],
"Note": "{\"resolve_sub_products\": {\"io.ayon.creators.resolve.shot\": {\"id\": \"pyblish.avalon.instance\", \"productType\": \"shot\", \"productName\": \"shotMain\", \"active\": true, \"creator_identifier\": \"io.ayon.creators.resolve.shot\", \"variant\": \"Main\", \"folderPath\": \"/shots/sq01/Video_1sq01sh010\", \"task\": \"Generic\", \"clip_variant\": \"<track_name>\", \"clip_index\": \"cef0267f-bbf4-4959-9f22-d225e03f2532\", \"clip_source_resolution\": {\"width\": \"640\", \"height\": \"360\", \"pixelAspect\": 1.0}, \"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"sq01\", \"track\": \"{_track_}\", \"shot\": \"sh###\", \"hierarchy\": \"shots/sq01\", \"sourceResolution\": false, \"workfileFrameStart\": 1001, \"handleStart\": 10, \"handleEnd\": 10, \"parents\": [{\"folder_type\": \"folder\", \"entity_name\": \"shots\"}, {\"folder_type\": \"sequence\", \"entity_name\": \"sq01\"}], \"hierarchyData\": {\"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"sq01\", \"track\": \"Video_1\", \"shot\": \"sh010\"}, \"heroTrack\": true, \"uuid\": \"3af1b00a-5625-468d-af17-8ed29fa8608a\", \"reviewTrack\": null, \"label\": \"/shots/sq01/Video_1sq01sh010 shot\", \"has_promised_context\": true, \"newHierarchyIntegration\": true, \"newAssetPublishing\": true, \"instance_id\": \"b6e33343-2410-4de4-935e-724bc74301e1\", \"creator_attributes\": {\"folderPath\": \"/shots/sq01/Video_1sq01sh010\", \"workfileFrameStart\": 1001, \"handleStart\": 10, \"handleEnd\": 10, \"frameStart\": 1001, \"frameEnd\": 1172, \"clipIn\": 1097, \"clipOut\": 1268, \"clipDuration\": 171, \"sourceIn\": 0, \"sourceOut\": 171, \"fps\": \"from_selection\"}, \"publish_attributes\": {\"CollectSlackFamilies\": {\"additional_message\": \"\"}}}, \"io.ayon.creators.resolve.plate\": {\"id\": \"pyblish.avalon.instance\", \"productType\": \"plate\", \"productName\": \"plateVideo_1\", \"active\": true, \"creator_identifier\": \"io.ayon.creators.resolve.plate\", \"variant\": \"Video_1\", \"folderPath\": \"/shots/sq01/Video_1sq01sh010\", \"task\": \"Generic\", \"clip_variant\": \"<track_name>\", \"clip_index\": \"cef0267f-bbf4-4959-9f22-d225e03f2532\", \"clip_source_resolution\": {\"width\": \"640\", \"height\": \"360\", \"pixelAspect\": 1.0}, \"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"sq01\", \"track\": \"{_track_}\", \"shot\": \"sh###\", \"hierarchy\": \"shots/sq01\", \"sourceResolution\": false, \"workfileFrameStart\": 1001, \"handleStart\": 10, \"handleEnd\": 10, \"parents\": [{\"folder_type\": \"folder\", \"entity_name\": \"shots\"}, {\"folder_type\": \"sequence\", \"entity_name\": \"sq01\"}], \"hierarchyData\": {\"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"sq01\", \"track\": \"Video_1\", \"shot\": \"sh010\"}, \"heroTrack\": true, \"uuid\": \"3af1b00a-5625-468d-af17-8ed29fa8608a\", \"reviewTrack\": null, \"parent_instance_id\": \"b6e33343-2410-4de4-935e-724bc74301e1\", \"label\": \"/shots/sq01/Video_1sq01sh010 plate\", \"has_promised_context\": true, \"newHierarchyIntegration\": true, \"newAssetPublishing\": true, \"instance_id\": \"ef8fe238-c970-4a16-be67-76f446113c4b\", \"creator_attributes\": {\"parentInstance\": \"/shots/sq01/Video_1sq01sh010 shot\", \"vSyncOn\": false, \"vSyncTrack\": \"Video 1\"}, \"publish_attributes\": {\"CollectSlackFamilies\": {\"additional_message\": \"\"}}}}, \"clip_index\": \"cef0267f-bbf4-4959-9f22-d225e03f2532\", \"publish\": true}"
},
"clip_index": "cef0267f-bbf4-4959-9f22-d225e03f2532",
"publish": true,
"resolve_sub_products": {
"io.ayon.creators.resolve.plate": {
"active": true,
"clip_index": "cef0267f-bbf4-4959-9f22-d225e03f2532",
"clip_source_resolution": {
"height": "360",
"pixelAspect": 1.0,
"width": "640"
},
"clip_variant": "<track_name>",
"creator_attributes": {
"parentInstance": "/shots/sq01/Video_1sq01sh010 shot",
"vSyncOn": false,
"vSyncTrack": "Video 1"
},
"creator_identifier": "io.ayon.creators.resolve.plate",
"episode": "ep01",
"folder": "shots",
"folderPath": "/shots/sq01/Video_1sq01sh010",
"handleEnd": 10,
"handleStart": 10,
"has_promised_context": true,
"heroTrack": true,
"hierarchy": "shots/sq01",
"hierarchyData": {
"episode": "ep01",
"folder": "shots",
"sequence": "sq01",
"shot": "sh010",
"track": "Video_1"
},
"id": "pyblish.avalon.instance",
"instance_id": "ef8fe238-c970-4a16-be67-76f446113c4b",
"label": "/shots/sq01/Video_1sq01sh010 plate",
"newAssetPublishing": true,
"newHierarchyIntegration": true,
"parent_instance_id": "b6e33343-2410-4de4-935e-724bc74301e1",
"parents": [
{
"entity_name": "shots",
"folder_type": "folder"
},
{
"entity_name": "sq01",
"folder_type": "sequence"
}
],
"productName": "plateVideo_1",
"productType": "plate",
"publish_attributes": {
"CollectSlackFamilies": {
"additional_message": ""
}
},
"reviewTrack": null,
"sequence": "sq01",
"shot": "sh###",
"sourceResolution": false,
"task": "Generic",
"track": "{_track_}",
"uuid": "3af1b00a-5625-468d-af17-8ed29fa8608a",
"variant": "Video_1",
"workfileFrameStart": 1001
},
"io.ayon.creators.resolve.shot": {
"active": true,
"clip_index": "cef0267f-bbf4-4959-9f22-d225e03f2532",
"clip_source_resolution": {
"height": "360",
"pixelAspect": 1.0,
"width": "640"
},
"clip_variant": "<track_name>",
"creator_attributes": {
"clipDuration": 171,
"clipIn": 1097,
"clipOut": 1268,
"folderPath": "/shots/sq01/Video_1sq01sh010",
"fps": "from_selection",
"frameEnd": 1172,
"frameStart": 1001,
"handleEnd": 10,
"handleStart": 10,
"sourceIn": 0,
"sourceOut": 171,
"workfileFrameStart": 1001
},
"creator_identifier": "io.ayon.creators.resolve.shot",
"episode": "ep01",
"folder": "shots",
"folderPath": "/shots/sq01/Video_1sq01sh010",
"handleEnd": 10,
"handleStart": 10,
"has_promised_context": true,
"heroTrack": true,
"hierarchy": "shots/sq01",
"hierarchyData": {
"episode": "ep01",
"folder": "shots",
"sequence": "sq01",
"shot": "sh010",
"track": "Video_1"
},
"id": "pyblish.avalon.instance",
"instance_id": "b6e33343-2410-4de4-935e-724bc74301e1",
"label": "/shots/sq01/Video_1sq01sh010 shot",
"newAssetPublishing": true,
"newHierarchyIntegration": true,
"parents": [
{
"entity_name": "shots",
"folder_type": "folder"
},
{
"entity_name": "sq01",
"folder_type": "sequence"
}
],
"productName": "shotMain",
"productType": "shot",
"publish_attributes": {
"CollectSlackFamilies": {
"additional_message": ""
}
},
"reviewTrack": null,
"sequence": "sq01",
"shot": "sh###",
"sourceResolution": false,
"task": "Generic",
"track": "{_track_}",
"uuid": "3af1b00a-5625-468d-af17-8ed29fa8608a",
"variant": "Main",
"workfileFrameStart": 1001
}
}
},
"name": "AyonData",
"color": "GREEN",
"marked_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 1.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 85.0
}
},
"comment": ""
}
],
"enabled": true,
"media_references": {
"DEFAULT_MEDIA": {
"OTIO_SCHEMA": "ExternalReference.1",
"metadata": {},
"name": "simple_editorial_setup.mp4",
"available_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 16450.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 0.0
}
},
"available_image_bounds": null,
"target_url": "C:\\Users\\robin\\OneDrive\\Bureau\\dev_ayon\\data\\simple_editorial_setup.mp4"
}
},
"active_media_reference_key": "DEFAULT_MEDIA"
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,289 @@
{
"OTIO_SCHEMA": "Track.1",
"metadata": {},
"name": "Video 2",
"source_range": null,
"effects": [],
"markers": [],
"enabled": true,
"children": [
{
"OTIO_SCHEMA": "Gap.1",
"metadata": {},
"name": "",
"source_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 2.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 0.0
}
},
"effects": [],
"markers": [],
"enabled": true
},
{
"OTIO_SCHEMA": "Clip.2",
"metadata": {},
"name": "output",
"source_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 88.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 0.0
}
},
"effects": [],
"markers": [],
"enabled": true,
"media_references": {
"DEFAULT_MEDIA": {
"OTIO_SCHEMA": "ImageSequenceReference.1",
"metadata": {
"clip.properties.blendfunc": "0",
"clip.properties.colourspacename": "default ()",
"clip.properties.domainroot": "",
"clip.properties.enabled": "1",
"clip.properties.expanded": "1",
"clip.properties.opacity": "1",
"clip.properties.valuesource": "",
"foundry.source.audio": "",
"foundry.source.bitmapsize": "0",
"foundry.source.bitsperchannel": "0",
"foundry.source.channelformat": "integer",
"foundry.source.colourtransform": "scene_linear",
"foundry.source.duration": "101",
"foundry.source.filename": "output.%04d.exr 1000-1100",
"foundry.source.filesize": "",
"foundry.source.fragments": "101",
"foundry.source.framerate": "24",
"foundry.source.fullpath": "",
"foundry.source.height": "1080",
"foundry.source.layers": "colour",
"foundry.source.pixelAspect": "1",
"foundry.source.pixelAspectRatio": "",
"foundry.source.pixelformat": "RGBA (Float16) Open Color IO space: 7",
"foundry.source.reelID": "",
"foundry.source.resolution": "",
"foundry.source.samplerate": "Invalid",
"foundry.source.shortfilename": "output.%04d.exr 1000-1100",
"foundry.source.shot": "",
"foundry.source.shotDate": "",
"foundry.source.startTC": "",
"foundry.source.starttime": "1000",
"foundry.source.timecode": "87399",
"foundry.source.umid": "bbfe0c90-5b76-424a-6351-4dac36a8dde7",
"foundry.source.umidOriginator": "foundry.source.umid",
"foundry.source.width": "1920",
"foundry.timeline.autodiskcachemode": "Manual",
"foundry.timeline.colorSpace": "scene_linear",
"foundry.timeline.duration": "101",
"foundry.timeline.framerate": "24",
"foundry.timeline.outputformat": "",
"foundry.timeline.poster": "0",
"foundry.timeline.posterLayer": "colour",
"foundry.timeline.readParams": "AAAAAQAAAAAAAAAFAAAACmNvbG9yc3BhY2UAAAAFaW50MzIAAAAAAAAAC2VkZ2VfcGl4ZWxzAAAABWludDMyAAAAAAAAABFpZ25vcmVfcGFydF9uYW1lcwAAAARib29sAAAAAAhub3ByZWZpeAAAAARib29sAAAAAB5vZmZzZXRfbmVnYXRpdmVfZGlzcGxheV93aW5kb3cAAAAEYm9vbAE=",
"foundry.timeline.samplerate": "Invalid",
"isSequence": true,
"media.exr.channels": "B:{1 0 1 1},G:{1 0 1 1},R:{1 0 1 1}",
"media.exr.compression": "2",
"media.exr.compressionName": "Zip (1 scanline)",
"media.exr.dataWindow": "1,1,1918,1078",
"media.exr.displayWindow": "0,0,1919,1079",
"media.exr.lineOrder": "0",
"media.exr.nuke.input.frame_rate": "24",
"media.exr.nuke.input.timecode": "01:00:41:15",
"media.exr.pixelAspectRatio": "1",
"media.exr.screenWindowCenter": "0,0",
"media.exr.screenWindowWidth": "1",
"media.exr.type": "scanlineimage",
"media.exr.version": "1",
"media.input.bitsperchannel": "16-bit half float",
"media.input.ctime": "2024-09-23 08:37:23",
"media.input.filereader": "exr",
"media.input.filesize": "1095868",
"media.input.frame": "1",
"media.input.frame_rate": "24",
"media.input.height": "1080",
"media.input.mtime": "2024-09-23 08:37:23",
"media.input.timecode": "01:00:41:15",
"media.input.width": "1920",
"media.nuke.full_layer_names": "0",
"media.nuke.node_hash": "9b",
"media.nuke.version": "15.1v2",
"openpype.source.colourtransform": "scene_linear",
"openpype.source.height": 1080,
"openpype.source.pixelAspect": 1.0,
"openpype.source.width": 1920,
"padding": 4
},
"name": "",
"available_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 101.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 1000.0
}
},
"available_image_bounds": null,
"target_url_base": "C:\\with_tc",
"name_prefix": "output.",
"name_suffix": ".exr",
"start_frame": 1000,
"frame_step": 1,
"rate": 24.0,
"frame_zero_padding": 4,
"missing_frame_policy": "error"
}
},
"active_media_reference_key": "DEFAULT_MEDIA"
},
{
"OTIO_SCHEMA": "Clip.2",
"metadata": {},
"name": "output",
"source_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 11.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 0.0
}
},
"effects": [],
"markers": [],
"enabled": true,
"media_references": {
"DEFAULT_MEDIA": {
"OTIO_SCHEMA": "ImageSequenceReference.1",
"metadata": {
"clip.properties.blendfunc": "0",
"clip.properties.colourspacename": "default ()",
"clip.properties.domainroot": "",
"clip.properties.enabled": "1",
"clip.properties.expanded": "1",
"clip.properties.opacity": "1",
"clip.properties.valuesource": "",
"foundry.source.audio": "",
"foundry.source.bitmapsize": "0",
"foundry.source.bitsperchannel": "0",
"foundry.source.channelformat": "integer",
"foundry.source.colourtransform": "scene_linear",
"foundry.source.duration": "101",
"foundry.source.filename": "output.%04d.exr 1000-1100",
"foundry.source.filesize": "",
"foundry.source.fragments": "101",
"foundry.source.framerate": "24",
"foundry.source.fullpath": "",
"foundry.source.height": "1080",
"foundry.source.layers": "colour",
"foundry.source.pixelAspect": "1",
"foundry.source.pixelAspectRatio": "",
"foundry.source.pixelformat": "RGBA (Float16) Open Color IO space: 7",
"foundry.source.reelID": "",
"foundry.source.resolution": "",
"foundry.source.samplerate": "Invalid",
"foundry.source.shortfilename": "output.%04d.exr 1000-1100",
"foundry.source.shot": "",
"foundry.source.shotDate": "",
"foundry.source.startTC": "",
"foundry.source.starttime": "1000",
"foundry.source.timecode": "87399",
"foundry.source.umid": "bbfe0c90-5b76-424a-6351-4dac36a8dde7",
"foundry.source.umidOriginator": "foundry.source.umid",
"foundry.source.width": "1920",
"foundry.timeline.autodiskcachemode": "Manual",
"foundry.timeline.colorSpace": "scene_linear",
"foundry.timeline.duration": "101",
"foundry.timeline.framerate": "24",
"foundry.timeline.outputformat": "",
"foundry.timeline.poster": "0",
"foundry.timeline.posterLayer": "colour",
"foundry.timeline.readParams": "AAAAAQAAAAAAAAAFAAAACmNvbG9yc3BhY2UAAAAFaW50MzIAAAAAAAAAC2VkZ2VfcGl4ZWxzAAAABWludDMyAAAAAAAAABFpZ25vcmVfcGFydF9uYW1lcwAAAARib29sAAAAAAhub3ByZWZpeAAAAARib29sAAAAAB5vZmZzZXRfbmVnYXRpdmVfZGlzcGxheV93aW5kb3cAAAAEYm9vbAE=",
"foundry.timeline.samplerate": "Invalid",
"isSequence": true,
"media.exr.channels": "B:{1 0 1 1},G:{1 0 1 1},R:{1 0 1 1}",
"media.exr.compression": "2",
"media.exr.compressionName": "Zip (1 scanline)",
"media.exr.dataWindow": "1,1,1918,1078",
"media.exr.displayWindow": "0,0,1919,1079",
"media.exr.lineOrder": "0",
"media.exr.nuke.input.frame_rate": "24",
"media.exr.nuke.input.timecode": "01:00:41:15",
"media.exr.pixelAspectRatio": "1",
"media.exr.screenWindowCenter": "0,0",
"media.exr.screenWindowWidth": "1",
"media.exr.type": "scanlineimage",
"media.exr.version": "1",
"media.input.bitsperchannel": "16-bit half float",
"media.input.ctime": "2024-09-23 08:37:23",
"media.input.filereader": "exr",
"media.input.filesize": "1095868",
"media.input.frame": "1",
"media.input.frame_rate": "24",
"media.input.height": "1080",
"media.input.mtime": "2024-09-23 08:37:23",
"media.input.timecode": "01:00:41:15",
"media.input.width": "1920",
"media.nuke.full_layer_names": "0",
"media.nuke.node_hash": "9b",
"media.nuke.version": "15.1v2",
"openpype.source.colourtransform": "scene_linear",
"openpype.source.height": 1080,
"openpype.source.pixelAspect": 1.0,
"openpype.source.width": 1920,
"padding": 4
},
"name": "",
"available_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 101.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 1000.0
}
},
"available_image_bounds": null,
"target_url_base": "C:\\with_tc",
"name_prefix": "output.",
"name_suffix": ".exr",
"start_frame": 1000,
"frame_step": 1,
"rate": 24.0,
"frame_zero_padding": 4,
"missing_frame_policy": "error"
}
},
"active_media_reference_key": "DEFAULT_MEDIA"
}
],
"kind": "Video"
}

View file

@ -0,0 +1,356 @@
{
"OTIO_SCHEMA": "Clip.2",
"metadata": {
"Resolve_OTIO": {}
},
"name": "qt_embedded_tc.mov",
"source_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 44.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 90032.0
}
},
"effects": [
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Transform",
"Enabled": true,
"Name": "Transform",
"Parameters": [],
"Type": 2
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Cropping",
"Enabled": true,
"Name": "Cropping",
"Parameters": [],
"Type": 3
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Dynamic Zoom",
"Enabled": false,
"Name": "Dynamic Zoom",
"Parameters": [
{
"Default Parameter Value": [
0.0,
0.0
],
"Key Frames": {
"-32": {
"Value": [
0.0,
0.0
],
"Variant Type": "POINTF"
},
"1009": {
"Value": [
0.0,
0.0
],
"Variant Type": "POINTF"
}
},
"Parameter ID": "dynamicZoomCenter",
"Parameter Value": [
0.0,
0.0
],
"Variant Type": "POINTF"
},
{
"Default Parameter Value": 1.0,
"Key Frames": {
"-32": {
"Value": 0.8,
"Variant Type": "Double"
},
"1009": {
"Value": 1.0,
"Variant Type": "Double"
}
},
"Parameter ID": "dynamicZoomScale",
"Parameter Value": 1.0,
"Variant Type": "Double",
"maxValue": 100.0,
"minValue": 0.01
}
],
"Type": 59
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Composite",
"Enabled": true,
"Name": "Composite",
"Parameters": [],
"Type": 1
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Lens Correction",
"Enabled": true,
"Name": "Lens Correction",
"Parameters": [],
"Type": 43
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Retime and Scaling",
"Enabled": true,
"Name": "Retime and Scaling",
"Parameters": [],
"Type": 22
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Video Faders",
"Enabled": true,
"Name": "Video Faders",
"Parameters": [],
"Type": 36
}
},
"name": "",
"effect_name": "Resolve Effect"
}
],
"markers": [
{
"OTIO_SCHEMA": "Marker.2",
"metadata": {
"Resolve_OTIO": {
"Keywords": [],
"Note": "{\"resolve_sub_products\": {\"io.ayon.creators.resolve.shot\": {\"id\": \"pyblish.avalon.instance\", \"productType\": \"shot\", \"productName\": \"shotMain\", \"active\": true, \"creator_identifier\": \"io.ayon.creators.resolve.shot\", \"variant\": \"Main\", \"folderPath\": \"/shots/sq01/Video_1sq01sh010\", \"task\": \"Generic\", \"clip_variant\": \"<track_name>\", \"clip_index\": \"297fbf7a-7636-44b5-a308-809098298fae\", \"clip_source_resolution\": {\"width\": \"956\", \"height\": \"720\", \"pixelAspect\": 1.0}, \"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"sq01\", \"track\": \"{_track_}\", \"shot\": \"sh###\", \"hierarchy\": \"shots/sq01\", \"sourceResolution\": false, \"workfileFrameStart\": 1001, \"handleStart\": 10, \"handleEnd\": 10, \"parents\": [{\"folder_type\": \"folder\", \"entity_name\": \"shots\"}, {\"folder_type\": \"sequence\", \"entity_name\": \"sq01\"}], \"hierarchyData\": {\"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"sq01\", \"track\": \"Video_1\", \"shot\": \"sh010\"}, \"heroTrack\": true, \"uuid\": \"3e459c3f-cc87-42c6-95c0-f11435ec8ace\", \"reviewTrack\": null, \"label\": \"/shots/sq01/Video_1sq01sh010 shot\", \"has_promised_context\": true, \"newHierarchyIntegration\": true, \"newAssetPublishing\": true, \"instance_id\": \"acebdee4-5f4a-4ebd-8c22-6ef2725c2070\", \"creator_attributes\": {\"folderPath\": \"/shots/sq01/Video_1sq01sh010\", \"workfileFrameStart\": 1001, \"handleStart\": 10, \"handleEnd\": 10, \"frameStart\": 1001, \"frameEnd\": 1045, \"clipIn\": 509, \"clipOut\": 553, \"clipDuration\": 44, \"sourceIn\": 32, \"sourceOut\": 76, \"fps\": \"from_selection\"}, \"publish_attributes\": {\"CollectSlackFamilies\": {\"additional_message\": \"\"}}}, \"io.ayon.creators.resolve.plate\": {\"id\": \"pyblish.avalon.instance\", \"productType\": \"plate\", \"productName\": \"plateVideo_1\", \"active\": true, \"creator_identifier\": \"io.ayon.creators.resolve.plate\", \"variant\": \"Video_1\", \"folderPath\": \"/shots/sq01/Video_1sq01sh010\", \"task\": \"Generic\", \"clip_variant\": \"<track_name>\", \"clip_index\": \"297fbf7a-7636-44b5-a308-809098298fae\", \"clip_source_resolution\": {\"width\": \"956\", \"height\": \"720\", \"pixelAspect\": 1.0}, \"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"sq01\", \"track\": \"{_track_}\", \"shot\": \"sh###\", \"hierarchy\": \"shots/sq01\", \"sourceResolution\": false, \"workfileFrameStart\": 1001, \"handleStart\": 10, \"handleEnd\": 10, \"parents\": [{\"folder_type\": \"folder\", \"entity_name\": \"shots\"}, {\"folder_type\": \"sequence\", \"entity_name\": \"sq01\"}], \"hierarchyData\": {\"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"sq01\", \"track\": \"Video_1\", \"shot\": \"sh010\"}, \"heroTrack\": true, \"uuid\": \"3e459c3f-cc87-42c6-95c0-f11435ec8ace\", \"reviewTrack\": null, \"parent_instance_id\": \"acebdee4-5f4a-4ebd-8c22-6ef2725c2070\", \"label\": \"/shots/sq01/Video_1sq01sh010 plate\", \"has_promised_context\": true, \"newHierarchyIntegration\": true, \"newAssetPublishing\": true, \"instance_id\": \"ffd09d3c-227c-4be0-8788-dec30daf7f78\", \"creator_attributes\": {\"parentInstance\": \"/shots/sq01/Video_1sq01sh010 shot\", \"vSyncOn\": false, \"vSyncTrack\": \"Video 1\"}, \"publish_attributes\": {\"CollectSlackFamilies\": {\"additional_message\": \"\"}}}}, \"clip_index\": \"297fbf7a-7636-44b5-a308-809098298fae\", \"publish\": true}"
},
"clip_index": "297fbf7a-7636-44b5-a308-809098298fae",
"publish": true,
"resolve_sub_products": {
"io.ayon.creators.resolve.plate": {
"active": true,
"clip_index": "297fbf7a-7636-44b5-a308-809098298fae",
"clip_source_resolution": {
"height": "720",
"pixelAspect": 1.0,
"width": "956"
},
"clip_variant": "<track_name>",
"creator_attributes": {
"parentInstance": "/shots/sq01/Video_1sq01sh010 shot",
"vSyncOn": false,
"vSyncTrack": "Video 1"
},
"creator_identifier": "io.ayon.creators.resolve.plate",
"episode": "ep01",
"folder": "shots",
"folderPath": "/shots/sq01/Video_1sq01sh010",
"handleEnd": 10,
"handleStart": 10,
"has_promised_context": true,
"heroTrack": true,
"hierarchy": "shots/sq01",
"hierarchyData": {
"episode": "ep01",
"folder": "shots",
"sequence": "sq01",
"shot": "sh010",
"track": "Video_1"
},
"id": "pyblish.avalon.instance",
"instance_id": "ffd09d3c-227c-4be0-8788-dec30daf7f78",
"label": "/shots/sq01/Video_1sq01sh010 plate",
"newAssetPublishing": true,
"newHierarchyIntegration": true,
"parent_instance_id": "acebdee4-5f4a-4ebd-8c22-6ef2725c2070",
"parents": [
{
"entity_name": "shots",
"folder_type": "folder"
},
{
"entity_name": "sq01",
"folder_type": "sequence"
}
],
"productName": "plateVideo_1",
"productType": "plate",
"publish_attributes": {
"CollectSlackFamilies": {
"additional_message": ""
}
},
"reviewTrack": null,
"sequence": "sq01",
"shot": "sh###",
"sourceResolution": false,
"task": "Generic",
"track": "{_track_}",
"uuid": "3e459c3f-cc87-42c6-95c0-f11435ec8ace",
"variant": "Video_1",
"workfileFrameStart": 1001
},
"io.ayon.creators.resolve.shot": {
"active": true,
"clip_index": "297fbf7a-7636-44b5-a308-809098298fae",
"clip_source_resolution": {
"height": "720",
"pixelAspect": 1.0,
"width": "956"
},
"clip_variant": "<track_name>",
"creator_attributes": {
"clipDuration": 44,
"clipIn": 509,
"clipOut": 553,
"folderPath": "/shots/sq01/Video_1sq01sh010",
"fps": "from_selection",
"frameEnd": 1045,
"frameStart": 1001,
"handleEnd": 10,
"handleStart": 10,
"sourceIn": 32,
"sourceOut": 76,
"workfileFrameStart": 1001
},
"creator_identifier": "io.ayon.creators.resolve.shot",
"episode": "ep01",
"folder": "shots",
"folderPath": "/shots/sq01/Video_1sq01sh010",
"handleEnd": 10,
"handleStart": 10,
"has_promised_context": true,
"heroTrack": true,
"hierarchy": "shots/sq01",
"hierarchyData": {
"episode": "ep01",
"folder": "shots",
"sequence": "sq01",
"shot": "sh010",
"track": "Video_1"
},
"id": "pyblish.avalon.instance",
"instance_id": "acebdee4-5f4a-4ebd-8c22-6ef2725c2070",
"label": "/shots/sq01/Video_1sq01sh010 shot",
"newAssetPublishing": true,
"newHierarchyIntegration": true,
"parents": [
{
"entity_name": "shots",
"folder_type": "folder"
},
{
"entity_name": "sq01",
"folder_type": "sequence"
}
],
"productName": "shotMain",
"productType": "shot",
"publish_attributes": {
"CollectSlackFamilies": {
"additional_message": ""
}
},
"reviewTrack": null,
"sequence": "sq01",
"shot": "sh###",
"sourceResolution": false,
"task": "Generic",
"track": "{_track_}",
"uuid": "3e459c3f-cc87-42c6-95c0-f11435ec8ace",
"variant": "Main",
"workfileFrameStart": 1001
}
}
},
"name": "AyonData",
"color": "GREEN",
"marked_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 1.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 90054.0
}
},
"comment": ""
}
],
"enabled": true,
"media_references": {
"DEFAULT_MEDIA": {
"OTIO_SCHEMA": "ExternalReference.1",
"metadata": {},
"name": "qt_embedded_tc.mov",
"available_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 100.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 86400.0
}
},
"available_image_bounds": null,
"target_url": "C:\\Users\\robin\\OneDrive\\Bureau\\dev_ayon\\data\\qt_embedded_tc.mov"
}
},
"active_media_reference_key": "DEFAULT_MEDIA"
}

View file

@ -0,0 +1,356 @@
{
"OTIO_SCHEMA": "Clip.2",
"metadata": {
"Resolve_OTIO": {}
},
"name": "qt_embedded_tc.mov",
"source_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 68.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 86414.0
}
},
"effects": [
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Transform",
"Enabled": true,
"Name": "Transform",
"Parameters": [],
"Type": 2
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Cropping",
"Enabled": true,
"Name": "Cropping",
"Parameters": [],
"Type": 3
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Dynamic Zoom",
"Enabled": false,
"Name": "Dynamic Zoom",
"Parameters": [
{
"Default Parameter Value": [
0.0,
0.0
],
"Key Frames": {
"-14": {
"Value": [
0.0,
0.0
],
"Variant Type": "POINTF"
},
"986": {
"Value": [
0.0,
0.0
],
"Variant Type": "POINTF"
}
},
"Parameter ID": "dynamicZoomCenter",
"Parameter Value": [
0.0,
0.0
],
"Variant Type": "POINTF"
},
{
"Default Parameter Value": 1.0,
"Key Frames": {
"-14": {
"Value": 0.8,
"Variant Type": "Double"
},
"986": {
"Value": 1.0,
"Variant Type": "Double"
}
},
"Parameter ID": "dynamicZoomScale",
"Parameter Value": 1.0,
"Variant Type": "Double",
"maxValue": 100.0,
"minValue": 0.01
}
],
"Type": 59
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Composite",
"Enabled": true,
"Name": "Composite",
"Parameters": [],
"Type": 1
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Lens Correction",
"Enabled": true,
"Name": "Lens Correction",
"Parameters": [],
"Type": 43
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Retime and Scaling",
"Enabled": true,
"Name": "Retime and Scaling",
"Parameters": [],
"Type": 22
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Video Faders",
"Enabled": true,
"Name": "Video Faders",
"Parameters": [],
"Type": 36
}
},
"name": "",
"effect_name": "Resolve Effect"
}
],
"markers": [
{
"OTIO_SCHEMA": "Marker.2",
"metadata": {
"Resolve_OTIO": {
"Keywords": [],
"Note": "{\"resolve_sub_products\": {\"io.ayon.creators.resolve.shot\": {\"id\": \"pyblish.avalon.instance\", \"productType\": \"shot\", \"productName\": \"shotMain\", \"active\": true, \"creator_identifier\": \"io.ayon.creators.resolve.shot\", \"variant\": \"Main\", \"folderPath\": \"/shots/seq_qt_tc/sh010\", \"task\": \"Generic\", \"clip_variant\": \"<track_name>\", \"clip_index\": \"12cce00c-eadf-4abd-ac80-0816a24506ab\", \"clip_source_resolution\": {\"width\": \"956\", \"height\": \"720\", \"pixelAspect\": 1.0}, \"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"seq_qt_tc\", \"track\": \"{_track_}\", \"shot\": \"sh###\", \"hierarchy\": \"shots/seq_qt_tc\", \"sourceResolution\": false, \"workfileFrameStart\": 1001, \"handleStart\": 10, \"handleEnd\": 10, \"parents\": [{\"folder_type\": \"folder\", \"entity_name\": \"shots\"}, {\"folder_type\": \"sequence\", \"entity_name\": \"seq_qt_tc\"}], \"hierarchyData\": {\"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"seq_qt_tc\", \"track\": \"Video1\", \"shot\": \"sh010\"}, \"heroTrack\": true, \"uuid\": \"5dc397e0-1142-4a35-969d-d4c35c512f0f\", \"reviewTrack\": \"Video1\", \"label\": \"/shots/seq_qt_tc/sh010 shot\", \"has_promised_context\": true, \"newHierarchyIntegration\": true, \"newAssetPublishing\": true, \"instance_id\": \"6f4bbf76-6638-4645-9059-0f516c0c12c2\", \"creator_attributes\": {\"folderPath\": \"/shots/seq_qt_tc/sh010\", \"workfileFrameStart\": 1001, \"handleStart\": 10, \"handleEnd\": 10, \"frameStart\": 1001, \"frameEnd\": 1069, \"clipIn\": 86516, \"clipOut\": 86584, \"clipDuration\": 68, \"sourceIn\": 14, \"sourceOut\": 82, \"fps\": \"from_selection\"}, \"publish_attributes\": {\"CollectSlackFamilies\": {\"additional_message\": \"\"}}}, \"io.ayon.creators.resolve.plate\": {\"id\": \"pyblish.avalon.instance\", \"productType\": \"plate\", \"productName\": \"plateVideo1\", \"active\": true, \"creator_identifier\": \"io.ayon.creators.resolve.plate\", \"variant\": \"Video1\", \"folderPath\": \"/shots/seq_qt_tc/sh010\", \"task\": \"Generic\", \"clip_variant\": \"<track_name>\", \"clip_index\": \"12cce00c-eadf-4abd-ac80-0816a24506ab\", \"clip_source_resolution\": {\"width\": \"956\", \"height\": \"720\", \"pixelAspect\": 1.0}, \"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"seq_qt_tc\", \"track\": \"{_track_}\", \"shot\": \"sh###\", \"hierarchy\": \"shots/seq_qt_tc\", \"sourceResolution\": false, \"workfileFrameStart\": 1001, \"handleStart\": 10, \"handleEnd\": 10, \"parents\": [{\"folder_type\": \"folder\", \"entity_name\": \"shots\"}, {\"folder_type\": \"sequence\", \"entity_name\": \"seq_qt_tc\"}], \"hierarchyData\": {\"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"seq_qt_tc\", \"track\": \"Video1\", \"shot\": \"sh010\"}, \"heroTrack\": true, \"uuid\": \"5dc397e0-1142-4a35-969d-d4c35c512f0f\", \"reviewTrack\": \"Video1\", \"parent_instance_id\": \"6f4bbf76-6638-4645-9059-0f516c0c12c2\", \"label\": \"/shots/seq_qt_tc/sh010 plate\", \"has_promised_context\": true, \"newHierarchyIntegration\": true, \"newAssetPublishing\": true, \"instance_id\": \"1d11a6b5-cc2b-49d8-8bcb-35187c785b22\", \"creator_attributes\": {\"parentInstance\": \"/shots/seq_qt_tc/sh010 shot\", \"vSyncOn\": true, \"vSyncTrack\": \"Video1\"}, \"publish_attributes\": {\"CollectSlackFamilies\": {\"additional_message\": \"\"}}}}, \"clip_index\": \"12cce00c-eadf-4abd-ac80-0816a24506ab\", \"publish\": true}"
},
"clip_index": "12cce00c-eadf-4abd-ac80-0816a24506ab",
"publish": true,
"resolve_sub_products": {
"io.ayon.creators.resolve.plate": {
"active": true,
"clip_index": "12cce00c-eadf-4abd-ac80-0816a24506ab",
"clip_source_resolution": {
"height": "720",
"pixelAspect": 1.0,
"width": "956"
},
"clip_variant": "<track_name>",
"creator_attributes": {
"parentInstance": "/shots/seq_qt_tc/sh010 shot",
"vSyncOn": true,
"vSyncTrack": "Video1"
},
"creator_identifier": "io.ayon.creators.resolve.plate",
"episode": "ep01",
"folder": "shots",
"folderPath": "/shots/seq_qt_tc/sh010",
"handleEnd": 10,
"handleStart": 10,
"has_promised_context": true,
"heroTrack": true,
"hierarchy": "shots/seq_qt_tc",
"hierarchyData": {
"episode": "ep01",
"folder": "shots",
"sequence": "seq_qt_tc",
"shot": "sh010",
"track": "Video1"
},
"id": "pyblish.avalon.instance",
"instance_id": "1d11a6b5-cc2b-49d8-8bcb-35187c785b22",
"label": "/shots/seq_qt_tc/sh010 plate",
"newAssetPublishing": true,
"newHierarchyIntegration": true,
"parent_instance_id": "6f4bbf76-6638-4645-9059-0f516c0c12c2",
"parents": [
{
"entity_name": "shots",
"folder_type": "folder"
},
{
"entity_name": "seq_qt_tc",
"folder_type": "sequence"
}
],
"productName": "plateVideo1",
"productType": "plate",
"publish_attributes": {
"CollectSlackFamilies": {
"additional_message": ""
}
},
"reviewTrack": "Video1",
"sequence": "seq_qt_tc",
"shot": "sh###",
"sourceResolution": false,
"task": "Generic",
"track": "{_track_}",
"uuid": "5dc397e0-1142-4a35-969d-d4c35c512f0f",
"variant": "Video1",
"workfileFrameStart": 1001
},
"io.ayon.creators.resolve.shot": {
"active": true,
"clip_index": "12cce00c-eadf-4abd-ac80-0816a24506ab",
"clip_source_resolution": {
"height": "720",
"pixelAspect": 1.0,
"width": "956"
},
"clip_variant": "<track_name>",
"creator_attributes": {
"clipDuration": 68,
"clipIn": 86516,
"clipOut": 86584,
"folderPath": "/shots/seq_qt_tc/sh010",
"fps": "from_selection",
"frameEnd": 1069,
"frameStart": 1001,
"handleEnd": 10,
"handleStart": 10,
"sourceIn": 14,
"sourceOut": 82,
"workfileFrameStart": 1001
},
"creator_identifier": "io.ayon.creators.resolve.shot",
"episode": "ep01",
"folder": "shots",
"folderPath": "/shots/seq_qt_tc/sh010",
"handleEnd": 10,
"handleStart": 10,
"has_promised_context": true,
"heroTrack": true,
"hierarchy": "shots/seq_qt_tc",
"hierarchyData": {
"episode": "ep01",
"folder": "shots",
"sequence": "seq_qt_tc",
"shot": "sh010",
"track": "Video1"
},
"id": "pyblish.avalon.instance",
"instance_id": "6f4bbf76-6638-4645-9059-0f516c0c12c2",
"label": "/shots/seq_qt_tc/sh010 shot",
"newAssetPublishing": true,
"newHierarchyIntegration": true,
"parents": [
{
"entity_name": "shots",
"folder_type": "folder"
},
{
"entity_name": "seq_qt_tc",
"folder_type": "sequence"
}
],
"productName": "shotMain",
"productType": "shot",
"publish_attributes": {
"CollectSlackFamilies": {
"additional_message": ""
}
},
"reviewTrack": "Video1",
"sequence": "seq_qt_tc",
"shot": "sh###",
"sourceResolution": false,
"task": "Generic",
"track": "{_track_}",
"uuid": "5dc397e0-1142-4a35-969d-d4c35c512f0f",
"variant": "Main",
"workfileFrameStart": 1001
}
}
},
"name": "AyonData",
"color": "GREEN",
"marked_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 1.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 86448.0
}
},
"comment": ""
}
],
"enabled": true,
"media_references": {
"DEFAULT_MEDIA": {
"OTIO_SCHEMA": "ExternalReference.1",
"metadata": {},
"name": "qt_embedded_tc.mov",
"available_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 100.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 86400.0
}
},
"available_image_bounds": null,
"target_url": "C:\\data\\qt_embedded_tc.mov"
}
},
"active_media_reference_key": "DEFAULT_MEDIA"
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,365 @@
{
"OTIO_SCHEMA": "Clip.2",
"metadata": {
"Resolve_OTIO": {
"Link Group ID": 1
}
},
"name": "simple_editorial_setup.mp4",
"source_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 171.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 0.0
}
},
"effects": [
{
"OTIO_SCHEMA": "LinearTimeWarp.1",
"metadata": {},
"name": "",
"effect_name": "",
"time_scalar": 2.5
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Transform",
"Enabled": true,
"Name": "Transform",
"Parameters": [],
"Type": 2
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Cropping",
"Enabled": true,
"Name": "Cropping",
"Parameters": [],
"Type": 3
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Dynamic Zoom",
"Enabled": false,
"Name": "Dynamic Zoom",
"Parameters": [
{
"Default Parameter Value": [
0.0,
0.0
],
"Key Frames": {
"0": {
"Value": [
0.0,
0.0
],
"Variant Type": "POINTF"
},
"1000": {
"Value": [
0.0,
0.0
],
"Variant Type": "POINTF"
}
},
"Parameter ID": "dynamicZoomCenter",
"Parameter Value": [
0.0,
0.0
],
"Variant Type": "POINTF"
},
{
"Default Parameter Value": 1.0,
"Key Frames": {
"0": {
"Value": 0.8,
"Variant Type": "Double"
},
"1000": {
"Value": 1.0,
"Variant Type": "Double"
}
},
"Parameter ID": "dynamicZoomScale",
"Parameter Value": 1.0,
"Variant Type": "Double",
"maxValue": 100.0,
"minValue": 0.01
}
],
"Type": 59
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Composite",
"Enabled": true,
"Name": "Composite",
"Parameters": [],
"Type": 1
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Lens Correction",
"Enabled": true,
"Name": "Lens Correction",
"Parameters": [],
"Type": 43
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Retime and Scaling",
"Enabled": true,
"Name": "Retime and Scaling",
"Parameters": [],
"Type": 22
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Video Faders",
"Enabled": true,
"Name": "Video Faders",
"Parameters": [],
"Type": 36
}
},
"name": "",
"effect_name": "Resolve Effect"
}
],
"markers": [
{
"OTIO_SCHEMA": "Marker.2",
"metadata": {
"Resolve_OTIO": {
"Keywords": [],
"Note": "{\"resolve_sub_products\": {\"io.ayon.creators.resolve.shot\": {\"id\": \"pyblish.avalon.instance\", \"productType\": \"shot\", \"productName\": \"shotMain\", \"active\": true, \"creator_identifier\": \"io.ayon.creators.resolve.shot\", \"variant\": \"Main\", \"folderPath\": \"/shots/sq01/Video_1sq01sh010\", \"task\": \"Generic\", \"clip_variant\": \"<track_name>\", \"clip_index\": \"cef0267f-bbf4-4959-9f22-d225e03f2532\", \"clip_source_resolution\": {\"width\": \"640\", \"height\": \"360\", \"pixelAspect\": 1.0}, \"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"sq01\", \"track\": \"{_track_}\", \"shot\": \"sh###\", \"hierarchy\": \"shots/sq01\", \"sourceResolution\": false, \"workfileFrameStart\": 1001, \"handleStart\": 10, \"handleEnd\": 10, \"parents\": [{\"folder_type\": \"folder\", \"entity_name\": \"shots\"}, {\"folder_type\": \"sequence\", \"entity_name\": \"sq01\"}], \"hierarchyData\": {\"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"sq01\", \"track\": \"Video_1\", \"shot\": \"sh010\"}, \"heroTrack\": true, \"uuid\": \"2a780b95-14cc-45de-acc0-3ecd1f504325\", \"reviewTrack\": null, \"label\": \"/shots/sq01/Video_1sq01sh010 shot\", \"has_promised_context\": true, \"newHierarchyIntegration\": true, \"newAssetPublishing\": true, \"instance_id\": \"e8af785a-484f-452b-8c9c-ac31ef0696c4\", \"creator_attributes\": {\"folderPath\": \"/shots/sq01/Video_1sq01sh010\", \"workfileFrameStart\": 1001, \"handleStart\": 10, \"handleEnd\": 10, \"frameStart\": 1001, \"frameEnd\": 1172, \"clipIn\": 805, \"clipOut\": 976, \"clipDuration\": 171, \"sourceIn\": 0, \"sourceOut\": 171, \"fps\": \"from_selection\"}, \"publish_attributes\": {\"CollectSlackFamilies\": {\"additional_message\": \"\"}}}, \"io.ayon.creators.resolve.plate\": {\"id\": \"pyblish.avalon.instance\", \"productType\": \"plate\", \"productName\": \"plateVideo_1\", \"active\": true, \"creator_identifier\": \"io.ayon.creators.resolve.plate\", \"variant\": \"Video_1\", \"folderPath\": \"/shots/sq01/Video_1sq01sh010\", \"task\": \"Generic\", \"clip_variant\": \"<track_name>\", \"clip_index\": \"cef0267f-bbf4-4959-9f22-d225e03f2532\", \"clip_source_resolution\": {\"width\": \"640\", \"height\": \"360\", \"pixelAspect\": 1.0}, \"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"sq01\", \"track\": \"{_track_}\", \"shot\": \"sh###\", \"hierarchy\": \"shots/sq01\", \"sourceResolution\": false, \"workfileFrameStart\": 1001, \"handleStart\": 10, \"handleEnd\": 10, \"parents\": [{\"folder_type\": \"folder\", \"entity_name\": \"shots\"}, {\"folder_type\": \"sequence\", \"entity_name\": \"sq01\"}], \"hierarchyData\": {\"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"sq01\", \"track\": \"Video_1\", \"shot\": \"sh010\"}, \"heroTrack\": true, \"uuid\": \"2a780b95-14cc-45de-acc0-3ecd1f504325\", \"reviewTrack\": null, \"parent_instance_id\": \"e8af785a-484f-452b-8c9c-ac31ef0696c4\", \"label\": \"/shots/sq01/Video_1sq01sh010 plate\", \"has_promised_context\": true, \"newHierarchyIntegration\": true, \"newAssetPublishing\": true, \"instance_id\": \"a34e7048-3d86-4c29-88c7-f65b1ba3d777\", \"creator_attributes\": {\"parentInstance\": \"/shots/sq01/Video_1sq01sh010 shot\", \"vSyncOn\": false, \"vSyncTrack\": \"Video 1\"}, \"publish_attributes\": {\"CollectSlackFamilies\": {\"additional_message\": \"\"}}}}, \"clip_index\": \"cef0267f-bbf4-4959-9f22-d225e03f2532\", \"publish\": true}"
},
"clip_index": "cef0267f-bbf4-4959-9f22-d225e03f2532",
"publish": true,
"resolve_sub_products": {
"io.ayon.creators.resolve.plate": {
"active": true,
"clip_index": "cef0267f-bbf4-4959-9f22-d225e03f2532",
"clip_source_resolution": {
"height": "360",
"pixelAspect": 1.0,
"width": "640"
},
"clip_variant": "<track_name>",
"creator_attributes": {
"parentInstance": "/shots/sq01/Video_1sq01sh010 shot",
"vSyncOn": false,
"vSyncTrack": "Video 1"
},
"creator_identifier": "io.ayon.creators.resolve.plate",
"episode": "ep01",
"folder": "shots",
"folderPath": "/shots/sq01/Video_1sq01sh010",
"handleEnd": 10,
"handleStart": 10,
"has_promised_context": true,
"heroTrack": true,
"hierarchy": "shots/sq01",
"hierarchyData": {
"episode": "ep01",
"folder": "shots",
"sequence": "sq01",
"shot": "sh010",
"track": "Video_1"
},
"id": "pyblish.avalon.instance",
"instance_id": "a34e7048-3d86-4c29-88c7-f65b1ba3d777",
"label": "/shots/sq01/Video_1sq01sh010 plate",
"newAssetPublishing": true,
"newHierarchyIntegration": true,
"parent_instance_id": "e8af785a-484f-452b-8c9c-ac31ef0696c4",
"parents": [
{
"entity_name": "shots",
"folder_type": "folder"
},
{
"entity_name": "sq01",
"folder_type": "sequence"
}
],
"productName": "plateVideo_1",
"productType": "plate",
"publish_attributes": {
"CollectSlackFamilies": {
"additional_message": ""
}
},
"reviewTrack": null,
"sequence": "sq01",
"shot": "sh###",
"sourceResolution": false,
"task": "Generic",
"track": "{_track_}",
"uuid": "2a780b95-14cc-45de-acc0-3ecd1f504325",
"variant": "Video_1",
"workfileFrameStart": 1001
},
"io.ayon.creators.resolve.shot": {
"active": true,
"clip_index": "cef0267f-bbf4-4959-9f22-d225e03f2532",
"clip_source_resolution": {
"height": "360",
"pixelAspect": 1.0,
"width": "640"
},
"clip_variant": "<track_name>",
"creator_attributes": {
"clipDuration": 171,
"clipIn": 805,
"clipOut": 976,
"folderPath": "/shots/sq01/Video_1sq01sh010",
"fps": "from_selection",
"frameEnd": 1172,
"frameStart": 1001,
"handleEnd": 10,
"handleStart": 10,
"sourceIn": 0,
"sourceOut": 171,
"workfileFrameStart": 1001
},
"creator_identifier": "io.ayon.creators.resolve.shot",
"episode": "ep01",
"folder": "shots",
"folderPath": "/shots/sq01/Video_1sq01sh010",
"handleEnd": 10,
"handleStart": 10,
"has_promised_context": true,
"heroTrack": true,
"hierarchy": "shots/sq01",
"hierarchyData": {
"episode": "ep01",
"folder": "shots",
"sequence": "sq01",
"shot": "sh010",
"track": "Video_1"
},
"id": "pyblish.avalon.instance",
"instance_id": "e8af785a-484f-452b-8c9c-ac31ef0696c4",
"label": "/shots/sq01/Video_1sq01sh010 shot",
"newAssetPublishing": true,
"newHierarchyIntegration": true,
"parents": [
{
"entity_name": "shots",
"folder_type": "folder"
},
{
"entity_name": "sq01",
"folder_type": "sequence"
}
],
"productName": "shotMain",
"productType": "shot",
"publish_attributes": {
"CollectSlackFamilies": {
"additional_message": ""
}
},
"reviewTrack": null,
"sequence": "sq01",
"shot": "sh###",
"sourceResolution": false,
"task": "Generic",
"track": "{_track_}",
"uuid": "2a780b95-14cc-45de-acc0-3ecd1f504325",
"variant": "Main",
"workfileFrameStart": 1001
}
}
},
"name": "AyonData",
"color": "GREEN",
"marked_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 1.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 85.0
}
},
"comment": ""
}
],
"enabled": true,
"media_references": {
"DEFAULT_MEDIA": {
"OTIO_SCHEMA": "ExternalReference.1",
"metadata": {},
"name": "simple_editorial_setup.mp4",
"available_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 16450.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 0.0
}
},
"available_image_bounds": null,
"target_url": "C:\\Users\\robin\\OneDrive\\Bureau\\dev_ayon\\data\\simple_editorial_setup.mp4"
}
},
"active_media_reference_key": "DEFAULT_MEDIA"
}

View file

@ -0,0 +1,356 @@
{
"OTIO_SCHEMA": "Clip.2",
"metadata": {
"Resolve_OTIO": {}
},
"name": "3 jours dans les coulisses du ZEvent 2024.mp4",
"source_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 50.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 0.0
}
},
"effects": [
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Transform",
"Enabled": true,
"Name": "Transform",
"Parameters": [],
"Type": 2
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Cropping",
"Enabled": true,
"Name": "Cropping",
"Parameters": [],
"Type": 3
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Dynamic Zoom",
"Enabled": false,
"Name": "Dynamic Zoom",
"Parameters": [
{
"Default Parameter Value": [
0.0,
0.0
],
"Key Frames": {
"0": {
"Value": [
0.0,
0.0
],
"Variant Type": "POINTF"
},
"1000": {
"Value": [
0.0,
0.0
],
"Variant Type": "POINTF"
}
},
"Parameter ID": "dynamicZoomCenter",
"Parameter Value": [
0.0,
0.0
],
"Variant Type": "POINTF"
},
{
"Default Parameter Value": 1.0,
"Key Frames": {
"0": {
"Value": 0.8,
"Variant Type": "Double"
},
"1000": {
"Value": 1.0,
"Variant Type": "Double"
}
},
"Parameter ID": "dynamicZoomScale",
"Parameter Value": 1.0,
"Variant Type": "Double",
"maxValue": 100.0,
"minValue": 0.01
}
],
"Type": 59
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Composite",
"Enabled": true,
"Name": "Composite",
"Parameters": [],
"Type": 1
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Lens Correction",
"Enabled": true,
"Name": "Lens Correction",
"Parameters": [],
"Type": 43
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Retime and Scaling",
"Enabled": true,
"Name": "Retime and Scaling",
"Parameters": [],
"Type": 22
}
},
"name": "",
"effect_name": "Resolve Effect"
},
{
"OTIO_SCHEMA": "Effect.1",
"metadata": {
"Resolve_OTIO": {
"Effect Name": "Video Faders",
"Enabled": true,
"Name": "Video Faders",
"Parameters": [],
"Type": 36
}
},
"name": "",
"effect_name": "Resolve Effect"
}
],
"markers": [
{
"OTIO_SCHEMA": "Marker.2",
"metadata": {
"Resolve_OTIO": {
"Keywords": [],
"Note": "{\"resolve_sub_products\": {\"io.ayon.creators.resolve.shot\": {\"id\": \"pyblish.avalon.instance\", \"productType\": \"shot\", \"productName\": \"shotMain\", \"active\": true, \"creator_identifier\": \"io.ayon.creators.resolve.shot\", \"variant\": \"Main\", \"folderPath\": \"/shots/seq_qt_no_tc/sh010\", \"task\": \"Generic\", \"clip_variant\": \"<track_name>\", \"clip_index\": \"c3d9fb4f-afdf-49e3-9733-bf80e40e0de3\", \"clip_source_resolution\": {\"width\": \"640\", \"height\": \"360\", \"pixelAspect\": 1.0}, \"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"seq_qt_no_tc\", \"track\": \"{_track_}\", \"shot\": \"sh###\", \"hierarchy\": \"shots/seq_qt_no_tc\", \"sourceResolution\": true, \"workfileFrameStart\": 1001, \"handleStart\": 10, \"handleEnd\": 10, \"parents\": [{\"folder_type\": \"folder\", \"entity_name\": \"shots\"}, {\"folder_type\": \"sequence\", \"entity_name\": \"seq_qt_no_tc\"}], \"hierarchyData\": {\"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"seq_qt_no_tc\", \"track\": \"Video1\", \"shot\": \"sh010\"}, \"heroTrack\": true, \"uuid\": \"5ab44838-a173-422a-8750-d5265e5a4ab5\", \"reviewTrack\": \"Video1\", \"label\": \"/shots/seq_qt_no_tc/sh010 shot\", \"has_promised_context\": true, \"newHierarchyIntegration\": true, \"newAssetPublishing\": true, \"instance_id\": \"ba8e76cd-7319-449d-93b5-93fd65cf3e83\", \"creator_attributes\": {\"folderPath\": \"/shots/seq_qt_no_tc/sh010\", \"workfileFrameStart\": 1001, \"handleStart\": 10, \"handleEnd\": 10, \"frameStart\": 1001, \"frameEnd\": 1051, \"clipIn\": 86477, \"clipOut\": 86527, \"clipDuration\": 50, \"sourceIn\": 0, \"sourceOut\": 50, \"fps\": \"from_selection\"}, \"publish_attributes\": {\"CollectSlackFamilies\": {\"additional_message\": \"\"}}}, \"io.ayon.creators.resolve.plate\": {\"id\": \"pyblish.avalon.instance\", \"productType\": \"plate\", \"productName\": \"plateVideo1\", \"active\": true, \"creator_identifier\": \"io.ayon.creators.resolve.plate\", \"variant\": \"Video1\", \"folderPath\": \"/shots/seq_qt_no_tc/sh010\", \"task\": \"Generic\", \"clip_variant\": \"<track_name>\", \"clip_index\": \"c3d9fb4f-afdf-49e3-9733-bf80e40e0de3\", \"clip_source_resolution\": {\"width\": \"640\", \"height\": \"360\", \"pixelAspect\": 1.0}, \"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"seq_qt_no_tc\", \"track\": \"{_track_}\", \"shot\": \"sh###\", \"hierarchy\": \"shots/seq_qt_no_tc\", \"sourceResolution\": true, \"workfileFrameStart\": 1001, \"handleStart\": 10, \"handleEnd\": 10, \"parents\": [{\"folder_type\": \"folder\", \"entity_name\": \"shots\"}, {\"folder_type\": \"sequence\", \"entity_name\": \"seq_qt_no_tc\"}], \"hierarchyData\": {\"folder\": \"shots\", \"episode\": \"ep01\", \"sequence\": \"seq_qt_no_tc\", \"track\": \"Video1\", \"shot\": \"sh010\"}, \"heroTrack\": true, \"uuid\": \"5ab44838-a173-422a-8750-d5265e5a4ab5\", \"reviewTrack\": \"Video1\", \"parent_instance_id\": \"ba8e76cd-7319-449d-93b5-93fd65cf3e83\", \"label\": \"/shots/seq_qt_no_tc/sh010 plate\", \"has_promised_context\": true, \"newHierarchyIntegration\": true, \"newAssetPublishing\": true, \"instance_id\": \"4a1cd220-c638-4e77-855c-cebd43b5dbc3\", \"creator_attributes\": {\"parentInstance\": \"/shots/seq_qt_no_tc/sh010 shot\", \"vSyncOn\": true, \"vSyncTrack\": \"Video1\"}, \"publish_attributes\": {\"CollectSlackFamilies\": {\"additional_message\": \"\"}}}}, \"clip_index\": \"c3d9fb4f-afdf-49e3-9733-bf80e40e0de3\", \"publish\": true}"
},
"clip_index": "c3d9fb4f-afdf-49e3-9733-bf80e40e0de3",
"publish": true,
"resolve_sub_products": {
"io.ayon.creators.resolve.plate": {
"active": true,
"clip_index": "c3d9fb4f-afdf-49e3-9733-bf80e40e0de3",
"clip_source_resolution": {
"height": "360",
"pixelAspect": 1.0,
"width": "640"
},
"clip_variant": "<track_name>",
"creator_attributes": {
"parentInstance": "/shots/seq_qt_no_tc/sh010 shot",
"vSyncOn": true,
"vSyncTrack": "Video1"
},
"creator_identifier": "io.ayon.creators.resolve.plate",
"episode": "ep01",
"folder": "shots",
"folderPath": "/shots/seq_qt_no_tc/sh010",
"handleEnd": 10,
"handleStart": 10,
"has_promised_context": true,
"heroTrack": true,
"hierarchy": "shots/seq_qt_no_tc",
"hierarchyData": {
"episode": "ep01",
"folder": "shots",
"sequence": "seq_qt_no_tc",
"shot": "sh010",
"track": "Video1"
},
"id": "pyblish.avalon.instance",
"instance_id": "4a1cd220-c638-4e77-855c-cebd43b5dbc3",
"label": "/shots/seq_qt_no_tc/sh010 plate",
"newAssetPublishing": true,
"newHierarchyIntegration": true,
"parent_instance_id": "ba8e76cd-7319-449d-93b5-93fd65cf3e83",
"parents": [
{
"entity_name": "shots",
"folder_type": "folder"
},
{
"entity_name": "seq_qt_no_tc",
"folder_type": "sequence"
}
],
"productName": "plateVideo1",
"productType": "plate",
"publish_attributes": {
"CollectSlackFamilies": {
"additional_message": ""
}
},
"reviewTrack": "Video1",
"sequence": "seq_qt_no_tc",
"shot": "sh###",
"sourceResolution": true,
"task": "Generic",
"track": "{_track_}",
"uuid": "5ab44838-a173-422a-8750-d5265e5a4ab5",
"variant": "Video1",
"workfileFrameStart": 1001
},
"io.ayon.creators.resolve.shot": {
"active": true,
"clip_index": "c3d9fb4f-afdf-49e3-9733-bf80e40e0de3",
"clip_source_resolution": {
"height": "360",
"pixelAspect": 1.0,
"width": "640"
},
"clip_variant": "<track_name>",
"creator_attributes": {
"clipDuration": 50,
"clipIn": 86477,
"clipOut": 86527,
"folderPath": "/shots/seq_qt_no_tc/sh010",
"fps": "from_selection",
"frameEnd": 1051,
"frameStart": 1001,
"handleEnd": 10,
"handleStart": 10,
"sourceIn": 0,
"sourceOut": 50,
"workfileFrameStart": 1001
},
"creator_identifier": "io.ayon.creators.resolve.shot",
"episode": "ep01",
"folder": "shots",
"folderPath": "/shots/seq_qt_no_tc/sh010",
"handleEnd": 10,
"handleStart": 10,
"has_promised_context": true,
"heroTrack": true,
"hierarchy": "shots/seq_qt_no_tc",
"hierarchyData": {
"episode": "ep01",
"folder": "shots",
"sequence": "seq_qt_no_tc",
"shot": "sh010",
"track": "Video1"
},
"id": "pyblish.avalon.instance",
"instance_id": "ba8e76cd-7319-449d-93b5-93fd65cf3e83",
"label": "/shots/seq_qt_no_tc/sh010 shot",
"newAssetPublishing": true,
"newHierarchyIntegration": true,
"parents": [
{
"entity_name": "shots",
"folder_type": "folder"
},
{
"entity_name": "seq_qt_no_tc",
"folder_type": "sequence"
}
],
"productName": "shotMain",
"productType": "shot",
"publish_attributes": {
"CollectSlackFamilies": {
"additional_message": ""
}
},
"reviewTrack": "Video1",
"sequence": "seq_qt_no_tc",
"shot": "sh###",
"sourceResolution": true,
"task": "Generic",
"track": "{_track_}",
"uuid": "5ab44838-a173-422a-8750-d5265e5a4ab5",
"variant": "Main",
"workfileFrameStart": 1001
}
}
},
"name": "AyonData",
"color": "GREEN",
"marked_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 1.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 24.0,
"value": 25.0
}
},
"comment": ""
}
],
"enabled": true,
"media_references": {
"DEFAULT_MEDIA": {
"OTIO_SCHEMA": "ExternalReference.1",
"metadata": {},
"name": "3 jours dans les coulisses du ZEvent 2024.mp4",
"available_range": {
"OTIO_SCHEMA": "TimeRange.1",
"duration": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 30822.0
},
"start_time": {
"OTIO_SCHEMA": "RationalTime.1",
"rate": 25.0,
"value": 0.0
}
},
"available_image_bounds": null,
"target_url": "C:\\data\\movie.mp4"
}
},
"active_media_reference_key": "DEFAULT_MEDIA"
}

View file

@ -0,0 +1,330 @@
import mock
import os
import pytest # noqa
from typing import NamedTuple
import opentimelineio as otio
from ayon_core.plugins.publish import extract_otio_review
_RESOURCE_DIR = os.path.join(
os.path.dirname(__file__),
"resources"
)
class MockInstance():
""" Mock pyblish instance for testing purpose.
"""
def __init__(self, data: dict):
self.data = data
self.context = self
class CaptureFFmpegCalls():
""" Mock calls made to ffmpeg subprocess.
"""
def __init__(self):
self.calls = []
def append_call(self, *args, **kwargs):
ffmpeg_args_list, = args
self.calls.append(" ".join(ffmpeg_args_list))
return True
def get_ffmpeg_executable(self, _):
return ["/path/to/ffmpeg"]
def run_process(file_name: str, instance_data: dict = None):
"""
"""
# Prepare dummy instance and capture call object
capture_call = CaptureFFmpegCalls()
processor = extract_otio_review.ExtractOTIOReview()
Anatomy = NamedTuple("Anatomy", project_name=str)
if not instance_data:
# Get OTIO review data from serialized file_name
file_path = os.path.join(_RESOURCE_DIR, file_name)
clip = otio.schema.Clip.from_json_file(file_path)
instance_data = {
"otioReviewClips": [clip],
"handleStart": 10,
"handleEnd": 10,
"workfileFrameStart": 1001,
}
instance_data.update({
"folderPath": "/dummy/path",
"anatomy": Anatomy("test_project"),
})
instance = MockInstance(instance_data)
# Mock calls to extern and run plugins.
with mock.patch.object(
extract_otio_review,
"get_ffmpeg_tool_args",
side_effect=capture_call.get_ffmpeg_executable,
):
with mock.patch.object(
extract_otio_review,
"run_subprocess",
side_effect=capture_call.append_call,
):
with mock.patch.object(
processor,
"_get_folder_name_based_prefix",
return_value="output."
):
with mock.patch.object(
processor,
"staging_dir",
return_value="C:/result/"
):
processor.process(instance)
# return all calls made to ffmpeg subprocess
return capture_call.calls
def test_image_sequence_with_embedded_tc_and_handles_out_of_range():
"""
Img sequence clip (embedded timecode 1h/24fps)
available_files = 1000-1100
available_range = 87399-87500 24fps
source_range = 87399-87500 24fps
"""
calls = run_process("img_seq_embedded_tc_review.json")
expected = [
# 10 head black handles generated from gap (991-1000)
"/path/to/ffmpeg -t 0.4166666666666667 -r 24.0 -f lavfi -i "
"color=c=black:s=1280x720 -tune stillimage -start_number 991 "
"C:/result/output.%03d.jpg",
# 10 tail black handles generated from gap (1102-1111)
"/path/to/ffmpeg -t 0.4166666666666667 -r 24.0 -f lavfi -i "
"color=c=black:s=1280x720 -tune stillimage -start_number 1102 "
"C:/result/output.%03d.jpg",
# Report from source exr (1001-1101) with enforce framerate
"/path/to/ffmpeg -start_number 1000 -framerate 24.0 -i "
f"C:\\exr_embedded_tc{os.sep}output.%04d.exr -start_number 1001 "
"C:/result/output.%03d.jpg"
]
assert calls == expected
def test_image_sequence_and_handles_out_of_range():
"""
Img sequence clip (no timecode)
available_files = 1000-1100
available_range = 0-101 25fps
source_range = 5-91 24fps
"""
calls = run_process("img_seq_review.json")
expected = [
# 5 head black frames generated from gap (991-995)
"/path/to/ffmpeg -t 0.2 -r 25.0 -f lavfi -i color=c=black:s=1280x720 -tune "
"stillimage -start_number 991 C:/result/output.%03d.jpg",
# 9 tail back frames generated from gap (1097-1105)
"/path/to/ffmpeg -t 0.36 -r 25.0 -f lavfi -i color=c=black:s=1280x720 -tune "
"stillimage -start_number 1097 C:/result/output.%03d.jpg",
# Report from source tiff (996-1096)
# 996-1000 = additional 5 head frames
# 1001-1095 = source range conformed to 25fps
# 1096-1096 = additional 1 tail frames
"/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i "
f"C:\\tif_seq{os.sep}output.%04d.tif -start_number 996 C:/result/output.%03d.jpg"
]
assert calls == expected
def test_movie_with_embedded_tc_no_gap_handles():
"""
Qt movie clip (embedded timecode 1h/24fps)
available_range = 86400-86500 24fps
source_range = 86414-86482 24fps
"""
calls = run_process("qt_embedded_tc_review.json")
expected = [
# Handles are all included in media available range.
# Extract source range from Qt
# - first_frame = 14 src - 10 (head tail) = frame 4 = 0.1666s
# - duration = 68fr (source) + 20fr (handles) = 88frames = 3.666s
"/path/to/ffmpeg -ss 0.16666666666666666 -t 3.6666666666666665 "
"-i C:\\data\\qt_embedded_tc.mov -start_number 991 "
"C:/result/output.%03d.jpg"
]
assert calls == expected
def test_short_movie_head_gap_handles():
"""
Qt movie clip.
available_range = 0-30822 25fps
source_range = 0-50 24fps
"""
calls = run_process("qt_review.json")
expected = [
# 10 head black frames generated from gap (991-1000)
"/path/to/ffmpeg -t 0.4 -r 25.0 -f lavfi -i color=c=black:s=1280x720 -tune "
"stillimage -start_number 991 C:/result/output.%03d.jpg",
# source range + 10 tail frames
# duration = 50fr (source) + 10fr (tail handle) = 60 fr = 2.4s
"/path/to/ffmpeg -ss 0.0 -t 2.4 -i C:\\data\\movie.mp4 -start_number 1001 "
"C:/result/output.%03d.jpg"
]
assert calls == expected
def test_short_movie_tail_gap_handles():
"""
Qt movie clip.
available_range = 0-101 24fps
source_range = 35-101 24fps
"""
calls = run_process("qt_handle_tail_review.json")
expected = [
# 10 tail black frames generated from gap (1067-1076)
"/path/to/ffmpeg -t 0.4166666666666667 -r 24.0 -f lavfi -i "
"color=c=black:s=1280x720 -tune stillimage -start_number 1067 "
"C:/result/output.%03d.jpg",
# 10 head frames + source range
# duration = 10fr (head handle) + 66fr (source) = 76fr = 3.16s
"/path/to/ffmpeg -ss 1.0416666666666667 -t 3.1666666666666665 -i "
"C:\\data\\qt_no_tc_24fps.mov -start_number 991 C:/result/output.%03d.jpg"
]
assert calls == expected
def test_multiple_review_clips_no_gap():
"""
Use multiple review clips (image sequence).
Timeline 25fps
"""
file_path = os.path.join(_RESOURCE_DIR, "multiple_review_clips.json")
clips = otio.schema.Track.from_json_file(file_path)
instance_data = {
"otioReviewClips": clips,
"handleStart": 10,
"handleEnd": 10,
"workfileFrameStart": 1001,
}
calls = run_process(
None,
instance_data=instance_data
)
expected = [
# 10 head black frames generated from gap (991-1000)
'/path/to/ffmpeg -t 0.4 -r 25.0 -f lavfi -i color=c=black:s=1280x720 -tune '
'stillimage -start_number 991 C:/result/output.%03d.jpg',
# Alternance 25fps tiff sequence and 24fps exr sequence for 100 frames each
'/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i '
f'C:\\no_tc{os.sep}output.%04d.tif '
'-start_number 1001 C:/result/output.%03d.jpg',
'/path/to/ffmpeg -start_number 1000 -framerate 24.0 -i '
f'C:\\with_tc{os.sep}output.%04d.exr '
'-start_number 1102 C:/result/output.%03d.jpg',
'/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i '
f'C:\\no_tc{os.sep}output.%04d.tif '
'-start_number 1199 C:/result/output.%03d.jpg',
'/path/to/ffmpeg -start_number 1000 -framerate 24.0 -i '
f'C:\\with_tc{os.sep}output.%04d.exr '
'-start_number 1300 C:/result/output.%03d.jpg',
# Repeated 25fps tiff sequence multiple times till the end
'/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i '
f'C:\\no_tc{os.sep}output.%04d.tif '
'-start_number 1397 C:/result/output.%03d.jpg',
'/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i '
f'C:\\no_tc{os.sep}output.%04d.tif '
'-start_number 1498 C:/result/output.%03d.jpg',
'/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i '
f'C:\\no_tc{os.sep}output.%04d.tif '
'-start_number 1599 C:/result/output.%03d.jpg',
'/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i '
f'C:\\no_tc{os.sep}output.%04d.tif '
'-start_number 1700 C:/result/output.%03d.jpg',
'/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i '
f'C:\\no_tc{os.sep}output.%04d.tif '
'-start_number 1801 C:/result/output.%03d.jpg',
'/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i '
f'C:\\no_tc{os.sep}output.%04d.tif '
'-start_number 1902 C:/result/output.%03d.jpg',
'/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i '
f'C:\\no_tc{os.sep}output.%04d.tif '
'-start_number 2003 C:/result/output.%03d.jpg',
'/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i '
f'C:\\no_tc{os.sep}output.%04d.tif '
'-start_number 2104 C:/result/output.%03d.jpg',
'/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i '
f'C:\\no_tc{os.sep}output.%04d.tif '
'-start_number 2205 C:/result/output.%03d.jpg'
]
assert calls == expected
def test_multiple_review_clips_with_gap():
"""
Use multiple review clips (image sequence) with gap.
Timeline 24fps
"""
file_path = os.path.join(_RESOURCE_DIR, "multiple_review_clips_gap.json")
clips = otio.schema.Track.from_json_file(file_path)
instance_data = {
"otioReviewClips": clips,
"handleStart": 10,
"handleEnd": 10,
"workfileFrameStart": 1001,
}
calls = run_process(
None,
instance_data=instance_data
)
expected = [
# Gap on review track (12 frames)
'/path/to/ffmpeg -t 0.5 -r 24.0 -f lavfi -i color=c=black:s=1280x720 -tune '
'stillimage -start_number 991 C:/result/output.%03d.jpg',
'/path/to/ffmpeg -start_number 1000 -framerate 24.0 -i '
f'C:\\with_tc{os.sep}output.%04d.exr '
'-start_number 1003 C:/result/output.%03d.jpg',
'/path/to/ffmpeg -start_number 1000 -framerate 24.0 -i '
f'C:\\with_tc{os.sep}output.%04d.exr '
'-start_number 1091 C:/result/output.%03d.jpg'
]
assert calls == expected

View file

@ -0,0 +1,189 @@
import os
import opentimelineio as otio
from ayon_core.pipeline.editorial import get_media_range_with_retimes
_RESOURCE_DIR = os.path.join(
os.path.dirname(__file__),
"resources"
)
def _check_expected_retimed_values(
file_name: str,
expected_retimed_data: dict,
handle_start: int = 10,
handle_end: int = 10,
):
file_path = os.path.join(_RESOURCE_DIR, file_name)
otio_clip = otio.schema.Clip.from_json_file(file_path)
retimed_data = get_media_range_with_retimes(
otio_clip, handle_start, handle_end
)
assert retimed_data == expected_retimed_data
def test_movie_with_end_handle_end_only():
"""
Movie clip (no embedded timecode)
available_range = 0-171 25fps
source_range = 0-16450 25fps
"""
expected_data = {
'mediaIn': 0.0,
'mediaOut': 170.0,
'handleStart': 0,
'handleEnd': 10,
'speed': 1.0
}
_check_expected_retimed_values(
"movie_with_handles.json",
expected_data,
)
def test_movie_embedded_tc_handle():
"""
Movie clip (embedded timecode 1h)
available_range = 86400-86500 24fps
source_range = 90032-90076 25fps
"""
expected_data = {
'mediaIn': 30.720000000001164,
'mediaOut': 71.9600000000064,
'handleStart': 10,
'handleEnd': 10,
'speed': 1.0
}
_check_expected_retimed_values(
"qt_embedded_tc.json",
expected_data
)
def test_movie_retime_effect():
"""
Movie clip (embedded timecode 1h)
available_range = 0-171 25fps
source_range = 0-16450 25fps
retimed speed: 250%
"""
expected_data = {
'mediaIn': 0.0,
'mediaOut': 426.5,
'handleStart': 0,
'handleEnd': 25,
'speed': 2.5,
'versionData': {
'retime': True,
'speed': 2.5,
'timewarps': [],
'handleStart': 0,
'handleEnd': 25
}
}
_check_expected_retimed_values(
"qt_retimed_speed.json",
expected_data
)
def test_img_sequence_no_handles():
"""
Img sequence clip (no embedded timecode)
available files = 1000-1100
source_range = 0-100 25fps
"""
expected_data = {
'mediaIn': 1000,
'mediaOut': 1100,
'handleStart': 0,
'handleEnd': 0,
'speed': 1.0
}
_check_expected_retimed_values(
"img_seq_no_handles.json",
expected_data
)
def test_img_sequence_with_handles():
"""
Img sequence clip (no embedded timecode)
available files = 1000-1100
source_range = 34-72 25fps
"""
expected_data = {
'mediaIn': 1034,
'mediaOut': 1072,
'handleStart': 10,
'handleEnd': 10,
'speed': 1.0
}
_check_expected_retimed_values(
"img_seq_with_handles.json",
expected_data
)
def test_img_sequence_with_embedded_tc_and_handles():
"""
Img sequence clip (embedded timecode 1h)
available files = 1000-1100
source_range = 91046.625-91120.625 25fps
"""
expected_data = {
'mediaIn': 1005,
'mediaOut': 1075,
'handleStart': 5,
'handleEnd': 10,
'speed': 1.0
}
_check_expected_retimed_values(
"img_seq_embedded_tc.json",
expected_data
)
def test_img_sequence_relative_source_range():
"""
Img sequence clip (embedded timecode 1h)
available files = 1000-1100
source_range = fps
"""
expected_data = {
'mediaIn': 1000,
'mediaOut': 1098,
'handleStart': 0,
'handleEnd': 2,
'speed': 1.0
}
_check_expected_retimed_values(
"legacy_img_sequence.json",
expected_data
)
def test_img_sequence_conform_to_23_976fps():
"""
Img sequence clip
available files = 997-1047 23.976fps
source_range = 997-1055 23.976024627685547fps
"""
expected_data = {
'mediaIn': 997,
'mediaOut': 1047,
'handleStart': 0,
'handleEnd': 8,
'speed': 1.0
}
_check_expected_retimed_values(
"img_seq_23.976_metadata.json",
expected_data,
handle_start=0,
handle_end=8,
)

9
tests/conftest.py Normal file
View file

@ -0,0 +1,9 @@
import sys
from pathlib import Path
client_path = Path(__file__).resolve().parent.parent / "client"
# add client path to sys.path
sys.path.append(str(client_path))
print(f"Added {client_path} to sys.path")

View file

@ -233,6 +233,13 @@ function Invoke-Codespell {
& $Poetry $CodespellArgs
}
function Run-From-Code {
$Poetry = "$RepoRoot\.poetry\bin\poetry.exe"
$RunArgs = @( "run")
& $Poetry $RunArgs @arguments
}
function Write-Help {
<#
.SYNOPSIS
@ -248,6 +255,7 @@ function Write-Help {
Write-Info -Text " ruff-check ", "Run Ruff check for the repository" -Color White, Cyan
Write-Info -Text " ruff-fix ", "Run Ruff fix for the repository" -Color White, Cyan
Write-Info -Text " codespell ", "Run codespell check for the repository" -Color White, Cyan
Write-Info -Text " run ", "Run a poetry command in the repository environment" -Color White, Cyan
Write-Host ""
}
@ -269,6 +277,9 @@ function Resolve-Function {
} elseif ($FunctionName -eq "codespell") {
Set-Cwd
Invoke-CodeSpell
} elseif ($FunctionName -eq "run") {
Set-Cwd
Run-From-Code
} else {
Write-Host "Unknown function ""$FunctionName"""
Write-Help

View file

@ -157,6 +157,7 @@ default_help() {
echo -e " ${BWhite}ruff-check${RST} ${BCyan}Run Ruff check for the repository${RST}"
echo -e " ${BWhite}ruff-fix${RST} ${BCyan}Run Ruff fix for the repository${RST}"
echo -e " ${BWhite}codespell${RST} ${BCyan}Run codespell check for the repository${RST}"
echo -e " ${BWhite}run${RST} ${BCyan}Run a poetry command in the repository environment${RST}"
echo ""
}
@ -175,6 +176,12 @@ run_codespell () {
"$POETRY_HOME/bin/poetry" run codespell
}
run_command () {
echo -e "${BIGreen}>>>${RST} Running ..."
shift; # will remove first arg ("run") from the "$@"
"$POETRY_HOME/bin/poetry" run "$@"
}
main () {
detect_python || return 1
@ -207,6 +214,10 @@ main () {
run_codespell || return_code=$?
exit $return_code
;;
"run")
run_command "$@" || return_code=$?
exit $return_code
;;
esac
if [ "$function_name" != "" ]; then