feat(hiero): update otio export import

This commit is contained in:
Jakub Jezek 2020-12-04 13:04:33 +01:00
parent 027f19f9f6
commit 7dfc6a56d8
No known key found for this signature in database
GPG key ID: C4B96E101D2A47F3
2 changed files with 83 additions and 49 deletions

View file

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

View file

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