diff --git a/src/otio_aaf_adapter/adapters/advanced_authoring_format.py b/src/otio_aaf_adapter/adapters/advanced_authoring_format.py index eb60a8d..ccc08c4 100644 --- a/src/otio_aaf_adapter/adapters/advanced_authoring_format.py +++ b/src/otio_aaf_adapter/adapters/advanced_authoring_format.py @@ -618,7 +618,9 @@ def _transcribe(item, parents, edit_rate, indent=0): ] timeline_slot = timeline_slots[-1] if timeline_slot: - metadata["PhysicalTrackNumber"] = list(parent.slots).index(item) + 1 + if hasattr(parent, 'slots'): + slot_index = list(parent.slots).index(item) + 1 + metadata["PhysicalTrackNumber"] = slot_index metadata["SlotID"] = int(timeline_slot["SlotID"].value) for component in item.components: diff --git a/tests/sample_data/nested_audio_dissolve.aaf b/tests/sample_data/nested_audio_dissolve.aaf new file mode 100644 index 0000000..68b8d13 Binary files /dev/null and b/tests/sample_data/nested_audio_dissolve.aaf differ diff --git a/tests/test_aaf_adapter.py b/tests/test_aaf_adapter.py index 167170d..73aed80 100644 --- a/tests/test_aaf_adapter.py +++ b/tests/test_aaf_adapter.py @@ -219,6 +219,11 @@ SAMPLE_DATA_DIR, "bad_marker_track_from_avid.aaf" ) +NESTED_AUDIO_DISSOLVE_PATH = os.path.join( + SAMPLE_DATA_DIR, + "nested_audio_dissolve.aaf" +) + try: lib_path = os.environ.get("OTIO_AAF_PYTHON_LIB") @@ -1258,6 +1263,37 @@ def test_aaf_marker_with_bad_track(self): self.assertIsNotNone(timeline) + def test_aaf_nested_audio_dissolve(self): + timeline = None + + try: + timeline = otio.adapters.read_from_file( + NESTED_AUDIO_DISSOLVE_PATH + ) + + except Exception as e: + print('[ERROR] Transcribing test sample data `{}` caused an exception: {}'.format( # noqa + os.path.basename(NESTED_AUDIO_DISSOLVE_PATH), + e) + ) + + self.assertIsNotNone(timeline) + track = timeline.tracks[0] + + clip = track[0] + self.assertIsInstance(clip, otio.schema.Clip) + self.assertEqual(clip.source_range.duration.to_frames(), 43) + + transition = track[1] + self.assertIsInstance(transition, otio.schema.Transition) + self.assertEqual(transition.duration().to_frames(), 3) + self.assertEqual(transition.in_offset.to_frames(), 3) + self.assertEqual(transition.out_offset.to_frames(), 0) + + gap = track[2] + self.assertIsInstance(gap, otio.schema.Gap) + self.assertEqual(gap.source_range.duration.to_frames(), 0) + def _verify_user_comments(self, aaf_metadata, expected_md): self.assertTrue(aaf_metadata is not None)