AcademySoftwareFoundation / OpenTimelineIO

Open Source API and interchange format for editorial timeline information.
http://opentimeline.io
Apache License 2.0
1.47k stars 294 forks source link

Impossible convert from an ale to aaf using an OTIO #1343

Closed MichaelPlug closed 2 years ago

MichaelPlug commented 2 years ago

I'm tring to use an otio to convert an ale file to an aaf, using a simple adapter like this:

myale = otio.adapters.read_from_file("sample.ale")
otio.adapters.write_to_file(myale, "sample.aaf")

It looks like an OTIO from an ale doesn't have the attribute tracks that is necessary to build an aaf.

Traceback (most recent call last):
  File "/Users/MichaelPlug/Desktop/testOtio/mioscript.py", line 6, in <module>
    otio.adapters.write_to_file(myale, "myale.aaf")
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/opentimelineio/adapters/__init__.py", line 191, in write_to_file
    return adapter.write_to_file(
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/opentimelineio/adapters/adapter.py", line 194, in write_to_file
    result = self._execute_function(
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/opentimelineio/plugins/python_plugin.py", line 174, in _execute_function
    return (getattr(self.module(), func_name)(**kwargs))
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/opentimelineio_contrib/adapters/advanced_authoring_format.py", line 1172, in write_to_file
    timeline = aaf_writer._stackify_nested_groups(input_otio)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/opentimelineio_contrib/adapters/aaf_adapter/aaf_writer.py", line 272, in _stackify_nested_groups
    for track in copied.tracks:
reinecke commented 2 years ago

Hi @MichaelPlug- Would it be possible to send an example using one of the sample files from our sample data so we can try and reproduce what's happening?

MichaelPlug commented 2 years ago

I have pasted the wrong code lines, I'm sorry. I have corrected it.

 myale = otio.adapters.read_from_file("sample.ale")
 otio.adapters.write_to_file(myale, "sample.aaf")

I'm using sample.ale from contrib directory. I think the problem is the library convert the .ale file to a _opentimelineio.otio.SerializableCollection, but to build an aaf i need a _opentimelineio.otio.Timeline object.

jminor commented 2 years ago

ALE is typically used to contain an ordered list of media, like a bin in an NLE, and so our ALE adapter reads that as a SerializableCollection. AAF can support this too, I think, but our AAF adapter currently only supports timelines with tracks. You can turn one into the other like this:

myale = otio.adapters.read_from_file("sample.ale")
mytimeline = otio.schema.Timeline()
mytrack = otio.schema.Track(children=myale.deepcopy())
mytimeline.tracks.append(mytrack)
otio.adapters.write_to_file(mytimeline, "mytimeline.aaf")

Note, however, that the AAF adapter also needs additional information about each media reference's available range, and sometimes MobIDs. You can read more about that here: https://github.com/AcademySoftwareFoundation/OpenTimelineIO/wiki/Working-with-OpenTimelineIO-and-AAF

MichaelPlug commented 2 years ago

I have tested your code, in this case the problem is mytimeline's clips doesn't contains information about duration and start_time. These informations are already in sample in sample ale, in a different format, as timecode, in columns Start and Duration.

Something<class 'opentimelineio._otio.Clip'> Clip.media_reference.available_range.duration.rate does not exist, 'NoneType' object has no attribute 'duration'
Something<class 'opentimelineio._otio.Clip'> Clip.media_reference.available_range.start_time.rate does not exist, 'NoneType' object has no attribute 'start_time'

I have solved using directly pyaaf2 and skipping conversion to otio but I hope this report will be useful for some future developments. Thank you very much.

jminor commented 2 years ago

I'm glad you got it sorted out.