opentimelineio / otio-fcpx-xml-adapter Goto Github PK
View Code? Open in Web Editor NEWOpenTimelineIO FCP X XML adapter
License: Apache License 2.0
OpenTimelineIO FCP X XML adapter
License: Apache License 2.0
I am trying to export a minimal timeline (only one audio track) with the fcpx_xml adapter, and open the timeline in Final Cut Pro X.
Exporting this timeline without adapters works without any problems. However, when using the fcpx_xml
adater it raises an error.
Here is a minimal code example written in python and the stack trace:
import os
from pathlib import Path
from zipfile import ZipFile
from hachoir.parser import createParser
from hachoir.metadata import extractMetadata
import opentimelineio as otio
def write_zipfile(archive_name: str, timeline_file: Path, songfile: Path, clip_files: list[str], logdir: str) -> None:
# writes the timeline_file together with the songfile and clip_files into one zip archive
with ZipFile(archive_name, "w") as archive:
for clip_file in clip_files:
archive.write(os.path.join(logdir, clip_file), os.path.join("media",clip_file))
archive.write(os.path.join(timeline_file), timeline_file.name)
archive.write(songfile, os.path.join("media",songfile.name))
def get_song_duration(songfile_path: Path):
# returns the duration of the songfile in seconds
song_parser = createParser(str(songfile_path.resolve()))
song_metadata = extractMetadata(song_parser)
return song_metadata.get("duration").total_seconds()
def main(songfile_path: Path):
# create the timeline and track objects
tl = otio.schema.Timeline(name="Storyline")
tr_audio = otio.schema.Track(name="Audio", kind=otio.schema.Track.Kind.Audio)
tl.tracks.append(tr_audio)
# create the audio clip and append to the audio track
song_duration = get_song_duration(songfile_path)
cl_audio = otio.schema.Clip(
name=str(songfile_path.stem),
media_reference=otio.schema.ExternalReference(
target_url="media/"+str(songfile_path.name),
available_range=otio.opentime.TimeRange(
start_time=otio.opentime.RationalTime(0, 1),
duration=otio.opentime.RationalTime(song_duration, 1),
)
),
source_range=otio.opentime.TimeRange(
start_time=otio.opentime.RationalTime(0, 1),
duration=otio.opentime.RationalTime(song_duration, 1),
)
)
tr_audio.append(cl_audio)
# export timeline with fcpx_adapter
fcp_xml_timeline_file = "timeline.fcpxml"
otio.adapters.write_to_file(tl, fcp_xml_timeline_file, adapter_name="fcpx_xml")
archive_name = "timeline_fcpx_xml.zip"
write_zipfile(archive_name, Path(fcp_xml_timeline_file), songfile_path, [], "")
Traceback (most recent call last):
File "/Users/FPJ21JY/Documents/Videographer/playground_fcpxml_adapter.py", line 60, in <module>
main(songfile_path)
File "/Users/FPJ21JY/Documents/Videographer/playground_fcpxml_adapter.py", line 50, in main
otio.adapters.write_to_file(tl, fcp_xml_timeline_file, adapter_name="fcpx_xml")
File "/Users/FPJ21JY/anaconda3/envs/videographer/lib/python3.11/site-packages/opentimelineio/adapters/__init__.py", line 192, in write_to_file
return adapter.write_to_file(
^^^^^^^^^^^^^^^^^^^^^^
File "/Users/FPJ21JY/anaconda3/envs/videographer/lib/python3.11/site-packages/opentimelineio/adapters/adapter.py", line 192, in write_to_file
result = self.write_to_string(input_otio, **adapter_argument_map)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/FPJ21JY/anaconda3/envs/videographer/lib/python3.11/site-packages/opentimelineio/adapters/adapter.py", line 283, in write_to_string
return self._execute_function(
^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/FPJ21JY/anaconda3/envs/videographer/lib/python3.11/site-packages/opentimelineio/plugins/python_plugin.py", line 153, in _execute_function
return (getattr(self.module(), func_name)(**kwargs))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/FPJ21JY/anaconda3/envs/videographer/lib/python3.11/site-packages/opentimelineio_contrib/adapters/fcpx_xml.py", line 1161, in write_to_string
return FcpxOtio(input_otio).to_xml()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/FPJ21JY/anaconda3/envs/videographer/lib/python3.11/site-packages/opentimelineio_contrib/adapters/fcpx_xml.py", line 172, in to_xml
top_sequence = self._stack_to_sequence(project.tracks)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/FPJ21JY/anaconda3/envs/videographer/lib/python3.11/site-packages/opentimelineio_contrib/adapters/fcpx_xml.py", line 248, in _stack_to_sequence
self._track_for_spine(track, lane_id, spine, compound_clip)
File "/Users/FPJ21JY/anaconda3/envs/videographer/lib/python3.11/site-packages/opentimelineio_contrib/adapters/fcpx_xml.py", line 271, in _track_for_spine
offset = self._offset_based_on_parent(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/FPJ21JY/anaconda3/envs/videographer/lib/python3.11/site-packages/opentimelineio_contrib/adapters/fcpx_xml.py", line 309, in _offset_based_on_parent
parent.get("offset"),
^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'get'
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.