Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 60 additions & 54 deletions src/py-opentimelineio/opentimelineio/adapters/cmx_3600.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
# TODO: currently tracks with linked audio/video will lose their linkage when
# read into OTIO.

import copy
import os
import re
import math
Expand Down Expand Up @@ -137,62 +138,67 @@ def add_clip(self, line, comments, rate=24):
clip_handler.transition_data
)

tracks = self.tracks_for_channel(clip_handler.channel_code)
for track in tracks:
edl_rate = clip_handler.edl_rate
record_in = opentime.from_timecode(
clip_handler.record_tc_in,
edl_rate
)
record_out = opentime.from_timecode(
clip_handler.record_tc_out,
edl_rate
)

edl_rate = clip_handler.edl_rate
record_in = opentime.from_timecode(
clip_handler.record_tc_in,
edl_rate
)
record_out = opentime.from_timecode(
clip_handler.record_tc_out,
edl_rate
)
src_duration = clip.duration()
rec_duration = record_out - record_in
if rec_duration != src_duration:
motion = comment_handler.handled.get('motion_effect')
freeze = comment_handler.handled.get('freeze_frame')
if motion is not None or freeze is not None:
# Adjust the clip to match the record duration
clip.source_range = opentime.TimeRange(
start_time=clip.source_range.start_time,
duration=rec_duration
)

src_duration = clip.duration()
rec_duration = record_out - record_in
if rec_duration != src_duration:
motion = comment_handler.handled.get('motion_effect')
freeze = comment_handler.handled.get('freeze_frame')
if motion is not None or freeze is not None:
# Adjust the clip to match the record duration
clip.source_range = opentime.TimeRange(
start_time=clip.source_range.start_time,
duration=rec_duration
if freeze is not None:
clip.effects.append(schema.FreezeFrame())
# XXX remove 'FF' suffix (writing edl will add it back)
if clip.name.endswith(' FF'):
clip.name = clip.name[:-3]
elif motion is not None:
fps = float(
SPEED_EFFECT_RE.match(motion).group("speed")
)
time_scalar = fps / rate
clip.effects.append(
schema.LinearTimeWarp(time_scalar=time_scalar)
)

if freeze is not None:
clip.effects.append(schema.FreezeFrame())
# XXX remove 'FF' suffix (writing edl will add it back)
if clip.name.endswith(' FF'):
clip.name = clip.name[:-3]
elif motion is not None:
fps = float(
SPEED_EFFECT_RE.match(motion).group("speed")
)
time_scalar = fps / rate
clip.effects.append(
schema.LinearTimeWarp(time_scalar=time_scalar)
)

elif self.ignore_timecode_mismatch:
# Pretend there was no problem by adjusting the record_out.
# Note that we don't actually use record_out after this
# point in the code, since all of the subsequent math uses
# the clip's source_range. Adjusting the record_out is
# just to document what the implications of ignoring the
# mismatch here entails.
record_out = record_in + src_duration
elif self.ignore_timecode_mismatch:
# Pretend there was no problem by adjusting the record_out.
# Note that we don't actually use record_out after this
# point in the code, since all of the subsequent math uses
# the clip's source_range. Adjusting the record_out is
# just to document what the implications of ignoring the
# mismatch here entails.
record_out = record_in + src_duration

else:
raise EDLParseError(
"Source and record duration don't match: {} != {}"
" for clip {}".format(
src_duration,
rec_duration,
clip.name
))
else:
raise EDLParseError(
"Source and record duration don't match: {} != {}"
" for clip {}".format(
src_duration,
rec_duration,
clip.name
))

# Add clip instances to the tracks
tracks = self.tracks_for_channel(clip_handler.channel_code)
for track in tracks:
if len(tracks) > 1:
track_clip = copy.deepcopy(clip)
else:
track_clip = clip

if track.source_range is None:
zero = opentime.RationalTime(0, edl_rate)
Expand All @@ -211,7 +217,7 @@ def add_clip(self, line, comments, rate=24):
raise EDLParseError(
"Overlapping record in value: {} for clip {}".format(
clip_handler.record_tc_in,
clip.name
track_clip.name
))

# If the next clip is supposed to start beyond the end of the
Expand All @@ -228,8 +234,8 @@ def add_clip(self, line, comments, rate=24):
track.append(gap)
_extend_source_range_duration(track, gap.duration())

track.append(clip)
_extend_source_range_duration(track, clip.duration())
track.append(track_clip)
_extend_source_range_duration(track, track_clip.duration())

def guess_kind_for_track_name(self, name):
if name.startswith("V"):
Expand Down
6 changes: 6 additions & 0 deletions tests/sample_data/multi_audio.edl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
TITLE: MultiAudio
FCM: NON-DROP FRAME

001 AX AA C 00:00:00:00 00:56:55:22 00:00:00:00 00:56:55:22
* FROM CLIP NAME: AX
AUD 3
19 changes: 19 additions & 0 deletions tests/test_cmx_3600_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
SAMPLE_DATA_DIR,
"speed_effects_small.edl"
)
MULTIPLE_TARGET_AUDIO_PATH = os.path.join(SAMPLE_DATA_DIR, "multi_audio.edl")


class EDLAdapterTest(unittest.TestCase, otio_test_utils.OTIOAssertions):
Expand Down Expand Up @@ -812,6 +813,24 @@ def test_nucoda_edl_write_with_double_transition(self):

self.assertMultiLineEqual(result, expected)

def test_read_edl_with_multiple_target_audio_tracks(self):
tl = otio.adapters.read_from_file(MULTIPLE_TARGET_AUDIO_PATH)

self.assertEqual(len(tl.audio_tracks()), 2)

first_track, second_track = tl.audio_tracks()
self.assertEqual(first_track.name, "A1")
self.assertEqual(second_track.name, "A2")

self.assertEqual(first_track[0].name, "AX")
self.assertEqual(second_track[0].name, "AX")

expected_range = otio.opentime.TimeRange(
duration=otio.opentime.from_timecode("00:56:55:22", rate=24)
)
self.assertEqual(first_track[0].source_range, expected_range)
self.assertEqual(second_track[0].source_range, expected_range)

def test_custom_reel_names(self):
track = otio.schema.Track()
tl = otio.schema.Timeline(tracks=[track])
Expand Down