OpenTimelineIO's adapter split after v0.16 is the thing to plan around
Open Source API and interchange format for editorial timeline information.
At a glance
- What is it?
- OpenTimelineIO is an Apache-2.0 library that models the order and length of cuts and references to external media, in C++ with an official Python binding, and it is not a container for media. The operational change that will catch you out is packaging: since v0.16 the PyPI install ships core only, and AAF, Final Cut Pro XML and EDL adapters now live in a second package and in separate repositories under the project organisation.
- Who is it for?
- Adopt OpenTimelineIO if you write a tool that has to read or write editorial timelines without caring which non-linear editor produced them, because the adapters plus the plugin system turn a matrix of format converters into one in-memory model. Do not adopt it expecting it to carry media, since it stores references to external media and is explicitly not a container format.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 4 days ago.
- What is it written in?
- Mainly C++, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
It holds cuts, and references to media
The scope statement is short and settles most misunderstandings. OpenTimelineIO is an interchange format and API for editorial cut information, and it contains information about the order and length of cuts and references to external media. It is not, the README says plainly, a container format for media. That boundary is the design: the library describes a timeline, and the media it points at lives wherever the studio keeps it. A tool that wants the cut list, the media references and the metadata can read them from any participating application without moving a single frame. The data model lives in C++, providing an in-memory representation plus the functions to interpret, manipulate and serialise it, and inside the core sits a dependency-less library for dealing with time, opentime, which is the piece you will meet whenever you touch durations. Serialisation is JSON-based, and the Python side is described as an official binding intended to be idiomatic and ergonomic rather than a thin wrapper, with a plugin system on top.
The adapter split is the operational fact
Interoperability with formats that have no native integration comes from Python adapter plugins, and the README names the ones the community has built: Final Cut Pro XML, AAF, CMX 3600 EDL, and more. Then comes the note that changes an installation plan. For releases after v0.16, the OpenTimelineIO package on PyPI includes only the core libraries and file formats, and anyone who needs the full set of adapter plugins should install the separate OpenTimelineIO-Plugins package, with each OTIO release having a matching plugins release. A second paragraph goes further, saying that all adapters except the native .otio, .otioz and .otiod formats have been relocated to separate repositories under the OpenTimelineIO organisation. So a pipeline that started on the single package before 2023 needs two pinned installs today, and pinning them together is now your job. The three native formats are the exception, and they are the ones the core still reads and writes on its own.
Reading a file is three lines of Python
The README's Python example is the fastest way to understand the shape of the API, because it does the whole job: open a file through the adapter layer, walk the clips, print a name and a duration.
import opentimelineio as otio
timeline = otio.adapters.read_from_file("foo.aaf")
for clip in timeline.find_clips():
print(clip.name, clip.duration())The interesting part is read_from_file. The format is not an argument you pass, it is resolved through the adapter registry, so the same call handles an AAF, a Final Cut Pro XML document or a .otio file, and an adapter shipped in the plugins package is picked up the same way as one that was always there. find_clips walks the whole hierarchy rather than the top level, which matters because a timeline is a tree of tracks and gaps and nested items and the interesting clip is rarely a direct child. The C++ example does the same job against a .otio file and adds the parts you only see in the native binding, a serializable object retainer around the loaded timeline and the RationalTime value and rate pair that carries a duration as a fraction rather than a float. The examples directory in the repository goes further, with conform, flattening video tracks, shot detection, timing summaries, bundle and upgrade-and-downgrade examples in both languages, plus a sample plugin.
Media linkers, hook scripts and schema definitions
Adapters are the plugins most people meet, and the README is clear that they are only the most notable kind. Three others exist and each solves a different problem. Media linkers generate media references to local media according to your local conventions, which is the piece that makes a timeline portable between two sites with different volume naming, and it is the extension point that decides where a clip's file actually lives. Hook scripts run at various points during OTIO execution, with the example given being before the media linker, so you can inject behaviour into the middle of an operation without replacing the operation. Schema definitions let you define OTIO schemas, which is how you extend the data model itself with your own typed objects rather than smuggling them through a metadata dictionary. The consequence of having all four is that the core stays small and the studio-specific parts move into plugins you can version separately. The example tree includes a sample plugin directory and both an embed and a child process example for running Python adapters, which suggests the two integration styles are both supported.
VFX Reference Platform years are a support policy, not a badge
The support statement is unusually concrete for a library of this kind. The current release supports the VFX Reference Platform years 2025, 2024, 2023 and 2022, and Python 3.9 to 3.12, and the README points at VERSIONS.md for a matrix of which OTIO versions support which platform year, plus the contribution guidelines for the project's support policy and the vfxplatform site for what the platform is. For an adopter this is the most useful paragraph in the document, because the year of the platform is how a studio decides which OTIO to standardise on, and the answer changes annually. The development status paragraph adds the other half of the honesty: the framework is described as mature and widely deployed, natively supported in most non-linear editing applications with deep integration in game engines and content creation tools, the API is considered stable while still undergoing active development and refinement, and work is under way to strengthen the mathematical and theoretical underpinnings. The README's own summary is that the current version may be confidently deployed in your domain.
The build is a one-shot CMake call from setup.py
Packaging is handled by setup.py with setuptools, wheel and CMake 3.12 or newer as the build requirements, and the file contains two pieces of machinery worth reading. The first is a platform translation table mapping win32 to Win32 and win-amd64 to x64, so the same command line works on both Windows architectures. The second is a custom build_ext command that replaces the per-extension build with a single CMake invocation, and the comment explains why: the project builds its two extensions, opentime and otio, as a one-shot CMake call, and setuptools would otherwise call build_extension once per registered extension. The wheel matrix is set in pyproject, where cibuildwheel builds x86_64 and aarch64 on Linux and AMD64 on Windows, with macOS left to the tool's own default. A contributor-oriented Makefile sits on top for the things Python packaging does not cover, with targets for test, coverage, lint, manifest, wheel and doc-html, external programs discovered with command -v so a missing tool is simply absent, and a test target that runs the suite with the standard library runner:
@python -m unittest discover -s tests $(TEST_ARGS)The Makefile also clears a preset media linker before running tests, which is a small sign that the team cares about tests not silently depending on your environment.
Install is one command, and the version gap is the maintenance story
The Python-wrapped build is on PyPI and the documented install is:
python -m pip install opentimelineioInstallation notes and how to run the bundled viewer are in the quick start on ReadTheDocs, and the documentation set covers quick start, architecture, use cases and API reference, with a wiki holding more. The release history is where the maintenance story lives, and it is worth reading the tags rather than the dates alone. There are two, v0.18.0 described as Beta 18 for November 2025 and v0.18.1 a few days later for Python wheel fixes, then before that v0.17.0 from June 2024, a gap of about seventeen months. The last release was v0.18.1 on 2025-11-09 while the last push to main is 2026-09-18, so work is continuing on the branch without a tag. The version numbers themselves say beta, and for a library whose API is described as stable that is a naming convention rather than a warning, but it is the kind of thing to raise before you make it a dependency of a delivery pipeline. The repository also carries two contributor licence agreements, one corporate and one individual, as PDF files, which is the convention for a project with commercial studios upstream.
Against writing converters by hand, and against one editor's API
The alternative is usually a pair of bespoke converters, one per pair of tools, written once and then maintained forever, and the cost is not the first version. It is the tenth edge case, an AAF with a compound clip that one application writes and another reads differently, and the fact that the two converters disagree about which field wins. The second alternative is to use one non-linear editor's own interchange, which is free until a client sends the other format. OpenTimelineIO's approach is the in-between: one data model in the middle, an adapter on each edge, and a plugin API so the edges are contributed by the community rather than by you. The C++ core exists for the case where the integration is inside a tool rather than a script, and the Python binding is for everything else. Where it is the wrong choice is a workflow with one format end to end, where a single application's own API is simpler and better supported than a standard with a version matrix and a compatibility policy.
Editorial conclusion
Adopt OpenTimelineIO if you write a tool that has to read or write editorial timelines without caring which non-linear editor produced them, because the adapters plus the plugin system turn a matrix of format converters into one in-memory model. Do not adopt it expecting it to carry media, since it stores references to external media and is explicitly not a container format. Verify four things before your first pipeline: that you install both the core and the plugins package after v0.16, that your Python is between 3.9 and 3.12, that the VFX Reference Platform year on the badge, 2022 to 2025, matches the one your studio is on and that VERSIONS.md maps it correctly, and that your editor actually reads .otio natively rather than through an adapter. The licence is Apache-2.0, the last release was v0.18.1 on 2025-11-09, and the last push to main was 2026-09-18.
Frequently asked questions
Does OpenTimelineIO store the media itself?
No. It contains the order and length of cuts plus references to external media, and the README states explicitly that it is not a container format for media. The file names in a timeline point at media stored elsewhere.
Why did pip install opentimelineio stop giving me the AAF and EDL adapters?
For releases after v0.16 the OpenTimelineIO package on PyPI contains only the core libraries and file formats. The adapter plugins moved to the separate OpenTimelineIO-Plugins package, with a matching release for each OTIO release, and all adapters except the native .otio, .otioz and .otiod formats now live in separate repositories under the OpenTimelineIO organisation.
What plugin types does OpenTimelineIO support?
Adapters, which read and write legacy formats into the data model, plus media linkers that generate media references according to your local conventions, hook scripts that run at points during execution such as before the media linker, and schema definitions that extend the data model itself.
Which VFX Reference Platform years and Python versions are supported?
The current release supports VFX Reference Platform 2025, 2024, 2023 and 2022, with Python 3.9 to 3.12. VERSIONS.md in the repository holds the matrix of which OTIO versions support which platform year, and the contribution guidelines describe the support policy.
How stable is the OpenTimelineIO API?
The README describes the API as considered stable while still undergoing active development, refinement and bug fixes, and states that the current version may be confidently deployed. It also notes work underway to strengthen the mathematical and theoretical underpinnings of the model.
What licence is OpenTimelineIO released under?
Apache-2.0, with LICENSE.txt and NOTICE.txt at the repository root. The most recent release is v0.18.1 from 2025-11-09, and the last push to main was 2026-09-18.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/academysoftwarefoundation-opentimelineio)