def test_backreference_for_id(self): item1 = schema.Clip(name="clip1") item1_prime = schema.Clip(name="clip1") item2 = schema.Clip(name="clip2") br_map = {} item1_id, item1_is_new = self.adapter._backreference_for_item( item1, "clipitem", br_map ) self.assertEqual(item1_id, "clipitem-1") self.assertTrue(item1_is_new) item2_id, item2_is_new = self.adapter._backreference_for_item( item2, "clipitem", br_map ) self.assertEqual(item2_id, "clipitem-2") self.assertTrue(item2_is_new) ( item1_prime_id, item1_prime_is_new ) = self.adapter._backreference_for_item( item1_prime, "clipitem", br_map ) self.assertEqual(item1_prime_id, "clipitem-1") self.assertFalse(item1_prime_is_new)
def test_backreference_for_id_preserved(self): item1 = schema.Clip( name="clip23", metadata={"fcp_xml": { "@id": "clipitem-23" }}, ) item2 = schema.Clip(name="clip2") conflicting_item = schema.Clip( name="conflicting_clip", metadata={"fcp_xml": { "@id": "clipitem-1" }}, ) # prepopulate the backref map with some ids br_map = { "clipitem": { "bogus_hash": 1, "bogus_hash_2": 2, "bogus_hash_3": 3 } } # Make sure the id is preserved item1_id, item1_is_new = self.adapter._backreference_for_item( item1, "clipitem", br_map) self.assertEqual(item1_id, "clipitem-23") self.assertTrue(item1_is_new) # Make sure the next item continues to fill in item2_id, item2_is_new = self.adapter._backreference_for_item( item2, "clipitem", br_map) self.assertEqual(item2_id, "clipitem-4") self.assertTrue(item2_is_new) # Make sure confilcting clips don't stomp existing ones item3_id, item3_is_new = self.adapter._backreference_for_item( conflicting_item, "clipitem", br_map) self.assertEqual(item3_id, "clipitem-5") self.assertTrue(item3_is_new)
def test_roundtrip_mem2disk2mem(self): timeline = schema.Timeline('test_timeline') RATE = 48.0 video_reference = schema.ExternalReference( target_url="/var/tmp/test1.mov", available_range=opentime.TimeRange( opentime.RationalTime(value=100, rate=RATE), opentime.RationalTime(value=1000, rate=RATE))) video_reference.name = "test_vid_one" audio_reference = schema.ExternalReference( target_url="/var/tmp/test1.wav", available_range=opentime.TimeRange( opentime.RationalTime(value=0, rate=RATE), opentime.RationalTime(value=1000, rate=RATE)), ) audio_reference.name = "test_wav_one" generator_reference = schema.GeneratorReference( name="Color", metadata={ "fcp_xml": { "effectid": "Color", "effectcategory": "Matte", "effecttype": "generator", "mediatype": "video", "parameter": { "@authoringApp": "PremierePro", "parameterid": "fillcolor", "name": "Color", "value": { "alpha": "0", "red": "255", "green": "255", "blue": "255", }, }, }, }, ) v0 = schema.Track(kind=schema.track.TrackKind.Video) v1 = schema.Track(kind=schema.track.TrackKind.Video) timeline.tracks.extend([v0, v1]) a0 = schema.Track(kind=schema.track.TrackKind.Audio) timeline.tracks.append(a0) v0.extend([ schema.Clip(name='test_clip1', media_reference=video_reference, source_range=opentime.TimeRange( opentime.RationalTime(value=112, rate=RATE), opentime.RationalTime(value=40, rate=RATE))), schema.Gap(source_range=opentime.TimeRange( duration=opentime.RationalTime(value=60, rate=RATE))), schema.Clip(name='test_clip2', media_reference=video_reference, source_range=opentime.TimeRange( opentime.RationalTime(value=123, rate=RATE), opentime.RationalTime(value=260, rate=RATE))), schema.Clip(name='test_generator_clip', media_reference=generator_reference, source_range=opentime.TimeRange( opentime.RationalTime(value=292, rate=24.0), opentime.RationalTime(value=183, rate=24.0))), ]) v1.extend([ schema.Gap(source_range=opentime.TimeRange( duration=opentime.RationalTime(value=500, rate=RATE))), schema.Clip(name='test_clip3', media_reference=video_reference, source_range=opentime.TimeRange( opentime.RationalTime(value=112, rate=RATE), opentime.RationalTime(value=55, rate=RATE))) ]) a0.extend([ schema.Gap(source_range=opentime.TimeRange( duration=opentime.RationalTime(value=10, rate=RATE))), schema.Clip( name='test_clip4', media_reference=audio_reference, source_range=opentime.TimeRange( opentime.RationalTime(value=152, rate=RATE), opentime.RationalTime(value=248, rate=RATE)), ) ]) timeline.tracks.markers.append( schema.Marker(name='test_timeline_marker', marked_range=opentime.TimeRange( opentime.RationalTime(123, RATE)), metadata={'fcp_xml': { 'comment': 'my_comment' }})) v1[1].markers.append( schema.Marker(name='test_clip_marker', marked_range=opentime.TimeRange( opentime.RationalTime(125, RATE)), metadata={'fcp_xml': { 'comment': 'my_comment' }})) # make sure that global_start_time.rate survives the round trip timeline.global_start_time = opentime.RationalTime(100, RATE) result = adapters.write_to_string(timeline, adapter_name='fcp_xml') new_timeline = adapters.read_from_string(result, adapter_name='fcp_xml') # Since FCP XML's "sequence" is a marriage of the timeline and the # main tracks stack, the tracks stack loses its name new_timeline.tracks.name = timeline.tracks.name self.assertEqual(new_timeline.name, 'test_timeline') # Before comparing, scrub ignorable metadata introduced in # serialization (things like unique ids minted by the adapter) # Since we seeded metadata for the generator, keep that metadata del (new_timeline.metadata["fcp_xml"]) for child in new_timeline.tracks.each_child(): try: del (child.metadata["fcp_xml"]) except KeyError: pass try: is_generator = isinstance(child.media_reference, schema.GeneratorReference) if not is_generator: del (child.media_reference.metadata["fcp_xml"]) except (AttributeError, KeyError): pass self.assertJsonEqual(new_timeline, timeline)