mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
feat(hiero): update otio export import
This commit is contained in:
parent
027f19f9f6
commit
7dfc6a56d8
2 changed files with 83 additions and 49 deletions
|
|
@ -49,6 +49,9 @@ class OTIOExportTask(hiero.core.TaskBase):
|
|||
return str(type(self))
|
||||
|
||||
def get_rate(self, item):
|
||||
if not hasattr(item, 'framerate'):
|
||||
item = item.sequence()
|
||||
|
||||
num, den = item.framerate().toRational()
|
||||
rate = float(num) / float(den)
|
||||
|
||||
|
|
@ -58,12 +61,12 @@ class OTIOExportTask(hiero.core.TaskBase):
|
|||
return round(rate, 2)
|
||||
|
||||
def get_clip_ranges(self, trackitem):
|
||||
# Is clip an audio file? Use sequence frame rate
|
||||
if not trackitem.source().mediaSource().hasVideo():
|
||||
rate_item = trackitem.sequence()
|
||||
# Get rate from source or sequence
|
||||
if trackitem.source().mediaSource().hasVideo():
|
||||
rate_item = trackitem.source()
|
||||
|
||||
else:
|
||||
rate_item = trackitem.source()
|
||||
rate_item = trackitem.sequence()
|
||||
|
||||
source_rate = self.get_rate(rate_item)
|
||||
|
||||
|
|
@ -88,9 +91,10 @@ class OTIOExportTask(hiero.core.TaskBase):
|
|||
duration=source_duration
|
||||
)
|
||||
|
||||
available_range = None
|
||||
hiero_clip = trackitem.source()
|
||||
if not hiero_clip.mediaSource().isOffline():
|
||||
|
||||
available_range = None
|
||||
if hiero_clip.mediaSource().isMediaPresent():
|
||||
start_time = otio.opentime.RationalTime(
|
||||
hiero_clip.mediaSource().startTime(),
|
||||
source_rate
|
||||
|
|
@ -123,7 +127,7 @@ class OTIOExportTask(hiero.core.TaskBase):
|
|||
|
||||
def get_marker_color(self, tag):
|
||||
icon = tag.icon()
|
||||
pat = 'icons:Tag(?P<color>\w+)\.\w+'
|
||||
pat = r'icons:Tag(?P<color>\w+)\.\w+'
|
||||
|
||||
res = re.search(pat, icon)
|
||||
if res:
|
||||
|
|
@ -155,13 +159,17 @@ class OTIOExportTask(hiero.core.TaskBase):
|
|||
)
|
||||
)
|
||||
|
||||
metadata = dict(
|
||||
Hiero=tag.metadata().dict()
|
||||
)
|
||||
# Store the source item for future import assignment
|
||||
metadata['Hiero']['source_type'] = hiero_item.__class__.__name__
|
||||
|
||||
marker = otio.schema.Marker(
|
||||
name=tag.name(),
|
||||
color=self.get_marker_color(tag),
|
||||
marked_range=marked_range,
|
||||
metadata={
|
||||
'Hiero': tag.metadata().dict()
|
||||
}
|
||||
metadata=metadata
|
||||
)
|
||||
|
||||
otio_item.markers.append(marker)
|
||||
|
|
@ -170,37 +178,44 @@ class OTIOExportTask(hiero.core.TaskBase):
|
|||
hiero_clip = trackitem.source()
|
||||
|
||||
# Add Gap if needed
|
||||
prev_item = (
|
||||
itemindex and trackitem.parent().items()[itemindex - 1] or
|
||||
trackitem
|
||||
)
|
||||
if itemindex == 0:
|
||||
prev_item = trackitem
|
||||
|
||||
if prev_item == trackitem and trackitem.timelineIn() > 0:
|
||||
else:
|
||||
prev_item = trackitem.parent().items()[itemindex - 1]
|
||||
|
||||
clip_diff = trackitem.timelineIn() - prev_item.timelineOut()
|
||||
|
||||
if itemindex == 0 and trackitem.timelineIn() > 0:
|
||||
self.add_gap(trackitem, otio_track, 0)
|
||||
|
||||
elif (
|
||||
prev_item != trackitem and
|
||||
prev_item.timelineOut() != trackitem.timelineIn()
|
||||
):
|
||||
elif itemindex and clip_diff != 1:
|
||||
self.add_gap(trackitem, otio_track, prev_item.timelineOut())
|
||||
|
||||
# Create Clip
|
||||
source_range, available_range = self.get_clip_ranges(trackitem)
|
||||
|
||||
otio_clip = otio.schema.Clip()
|
||||
otio_clip.name = trackitem.name()
|
||||
otio_clip.source_range = source_range
|
||||
otio_clip = otio.schema.Clip(
|
||||
name=trackitem.name(),
|
||||
source_range=source_range
|
||||
)
|
||||
|
||||
# Add media reference
|
||||
media_reference = otio.schema.MissingReference()
|
||||
if not hiero_clip.mediaSource().isOffline():
|
||||
if hiero_clip.mediaSource().isMediaPresent():
|
||||
source = hiero_clip.mediaSource()
|
||||
media_reference = otio.schema.ExternalReference()
|
||||
media_reference.available_range = available_range
|
||||
first_file = source.fileinfos()[0]
|
||||
path = first_file.filename()
|
||||
|
||||
path, name = os.path.split(source.fileinfos()[0].filename())
|
||||
media_reference.target_url = os.path.join(path, name)
|
||||
media_reference.name = name
|
||||
if "%" in path:
|
||||
path = re.sub(r"%\d+d", "%d", path)
|
||||
if "#" in path:
|
||||
path = re.sub(r"#+", "%d", path)
|
||||
|
||||
media_reference = otio.schema.ExternalReference(
|
||||
target_url=u'{}'.format(path),
|
||||
available_range=available_range
|
||||
)
|
||||
|
||||
otio_clip.media_reference = media_reference
|
||||
|
||||
|
|
@ -218,6 +233,7 @@ class OTIOExportTask(hiero.core.TaskBase):
|
|||
|
||||
# Add tags as markers
|
||||
if self._preset.properties()["includeTags"]:
|
||||
self.add_markers(trackitem, otio_clip)
|
||||
self.add_markers(trackitem.source(), otio_clip)
|
||||
|
||||
otio_track.append(otio_clip)
|
||||
|
|
@ -273,16 +289,16 @@ class OTIOExportTask(hiero.core.TaskBase):
|
|||
name=alignment, # Consider placing Hiero name in metadata
|
||||
transition_type=otio.schema.TransitionTypes.SMPTE_Dissolve,
|
||||
in_offset=in_time,
|
||||
out_offset=out_time,
|
||||
metadata={}
|
||||
out_offset=out_time
|
||||
)
|
||||
|
||||
if alignment == 'kFadeIn':
|
||||
otio_track.insert(-2, otio_transition)
|
||||
otio_track.insert(-1, otio_transition)
|
||||
|
||||
else:
|
||||
otio_track.append(otio_transition)
|
||||
|
||||
|
||||
def add_tracks(self):
|
||||
for track in self._sequence.items():
|
||||
if isinstance(track, hiero.core.AudioTrack):
|
||||
|
|
@ -291,8 +307,7 @@ class OTIOExportTask(hiero.core.TaskBase):
|
|||
else:
|
||||
kind = otio.schema.TrackKind.Video
|
||||
|
||||
otio_track = otio.schema.Track(kind=kind)
|
||||
otio_track.name = track.name()
|
||||
otio_track = otio.schema.Track(name=track.name(), kind=kind)
|
||||
|
||||
for itemindex, trackitem in enumerate(track):
|
||||
if isinstance(trackitem.source(), hiero.core.Clip):
|
||||
|
|
@ -306,6 +321,12 @@ class OTIOExportTask(hiero.core.TaskBase):
|
|||
|
||||
def create_OTIO(self):
|
||||
self.otio_timeline = otio.schema.Timeline()
|
||||
|
||||
# Set global start time based on sequence
|
||||
self.otio_timeline.global_start_time = otio.opentime.RationalTime(
|
||||
self._sequence.timecodeStart(),
|
||||
self._sequence.framerate().toFloat()
|
||||
)
|
||||
self.otio_timeline.name = self._sequence.name()
|
||||
|
||||
self.add_tracks()
|
||||
|
|
|
|||
|
|
@ -356,19 +356,38 @@ def create_trackitem(playhead, track, otio_clip, clip, tagsbin):
|
|||
return trackitem
|
||||
|
||||
|
||||
def build_sequence(otio_timeline, project=None, track_kind=None):
|
||||
def build_sequence(
|
||||
otio_timeline, project=None, sequence=None, track_kind=None):
|
||||
|
||||
if project is None:
|
||||
# TODO: Find a proper way for active project
|
||||
project = hiero.core.projects(hiero.core.Project.kUserProjects)[-1]
|
||||
if sequence:
|
||||
project = sequence.project()
|
||||
|
||||
# Create a Sequence
|
||||
sequence = hiero.core.Sequence(otio_timeline.name or 'OTIOSequence')
|
||||
else:
|
||||
# Per version 12.1v2 there is no way of getting active project
|
||||
project = hiero.core.projects(hiero.core.Project.kUserProjects)[-1]
|
||||
|
||||
# Create a Bin to hold clips
|
||||
projectbin = project.clipsBin()
|
||||
projectbin.addItem(hiero.core.BinItem(sequence))
|
||||
sequencebin = hiero.core.Bin(sequence.name())
|
||||
projectbin.addItem(sequencebin)
|
||||
|
||||
if not sequence:
|
||||
# Create a Sequence
|
||||
sequence = hiero.core.Sequence(otio_timeline.name or 'OTIOSequence')
|
||||
|
||||
# Set sequence settings from otio timeline if available
|
||||
if hasattr(otio_timeline, 'global_start_time'):
|
||||
if otio_timeline.global_start_time:
|
||||
start_time = otio_timeline.global_start_time
|
||||
sequence.setFramerate(start_time.rate)
|
||||
sequence.setTimecodeStart(start_time.value)
|
||||
|
||||
# Create a Bin to hold clips
|
||||
projectbin.addItem(hiero.core.BinItem(sequence))
|
||||
|
||||
sequencebin = hiero.core.Bin(sequence.name())
|
||||
projectbin.addItem(sequencebin)
|
||||
|
||||
else:
|
||||
sequencebin = projectbin
|
||||
|
||||
# Get tagsBin
|
||||
tagsbin = hiero.core.project("Tag Presets").tagsBin()
|
||||
|
|
@ -376,17 +395,11 @@ def build_sequence(otio_timeline, project=None, track_kind=None):
|
|||
# Add timeline markers
|
||||
add_markers(otio_timeline, sequence, tagsbin)
|
||||
|
||||
# add sequence attributes form otio timeline
|
||||
if otio_timeline.global_start_time:
|
||||
sequence.setFramerate(otio_timeline.global_start_time.rate)
|
||||
sequence.setTimecodeStart(otio_timeline.global_start_time.value)
|
||||
|
||||
if isinstance(otio_timeline, otio.schema.Timeline):
|
||||
tracks = otio_timeline.tracks
|
||||
|
||||
else:
|
||||
# otio.schema.Stack
|
||||
tracks = otio_timeline
|
||||
tracks = [otio_timeline]
|
||||
|
||||
for tracknum, otio_track in enumerate(tracks):
|
||||
playhead = 0
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue