AcademySoftwareFoundation / AcademySoftwareFoundation/OpenTimelineIO

Kdenlive 22.12.0 export of timeline with library clips fails with multiple errors

Open
#1,504 4 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
C++
Stars
2k
Forks
351
Avg merge
1d 12h
Merged PRs (30d)
1

Description

## Bug Report

### Incorrect Functionality and General Questions

Kdenlive OTIO export fails with multiple errors.

## To Reproduce

1. Operating System: EndeavourOS, up to date
2. Python version: 3.10.8
4. OpenTimelineIO release version or commit hash
```
$ otioconvert --version
OpenTimelineIO version: 0.15.0
No pkg_resource plugins installed.
```
6. Compiler information:
binary installed, not compiled locally.

## Expected Behavior

In Kdenlive 22.12.0, in an existing project, create a few library clips from timeline segments that contain multiple clips. See this documentation https://docs.kdenlive.org/en/glossary/useful_information/the_library.html

In a new project, put one of those library clips onto the timeline. (Note that it might be a good idea to "expand" the library clip so that the original clips appear on the timeline, but this functionality is currently broken.)

Choose the menu option "Export OpenTimelineIO...", provide a name for the new file, click save, and get a new file successfully created.

## Screenshots

n/a

## Logs

An apparently useless 124 KB file is created that has no project-specific content and gives an error when I try to import it.

When I choose "export", give a name, and click `Save`, I get this error:

```
Traceback (most recent call last):
File "/usr/bin/otioconvert", line 33, in
sys.exit(load_entry_point('OpenTimelineIO==0.15.0', 'console_scripts', 'otioconvert')())
File "/usr/lib/python3.10/site-packages/opentimelineio/console/otioconvert.py", line 278, in main
otio.adapters.write_to_file(
File "/usr/lib/python3.10/site-packages/opentimelineio/adapters/__init__.py", line 192, in write_to_file
return adapter.write_to_file(
File "/usr/lib/python3.10/site-packages/opentimelineio/adapters/adapter.py", line 198, in write_to_file
result = self._execute_function(
File "/usr/lib/python3.10/site-packages/opentimelineio/plugins/python_plugin.py", line 153, in _execute_function
return (getattr(self.module(), func_name)(**kwargs))
File "/usr/lib/python3.10/site-packages/opentimelineio_contrib/adapters/advanced_authoring_format.py", line 1616, in write_to_file
aaf_writer.validate_metadata(timeline)
File "/usr/lib/python3.10/site-packages/opentimelineio_contrib/adapters/aaf_adapter/aaf_writer.py", line 179, in validate_metadata
raise AAFValidationError("\n" + "\n".join(
opentimelineio_contrib.adapters.aaf_adapter.aaf_writer.AAFValidationError:
Clip.media_reference.available_range.duration.rate does not exist, 'NoneType' object has no attribute 'duration'
Clip.media_reference.available_range.start_time.rate does not exist, 'NoneType' object has no attribute 'start_time'
Clip.media_reference.available_range.duration.rate does not exist, 'NoneType' object has no attribute 'duration'
Clip.media_reference.available_range.start_time.rate does not exist, 'NoneType' object has no attribute 'start_time'
Clip.media_reference.available_range.duration.rate does not exist, 'NoneType' object has no attribute 'duration'
Clip.media_reference.available_range.start_time.rate does not exist, 'NoneType' object has no attribute 'start_time'
Clip.media_reference.available_range.duration.rate does not exist, 'NoneType' object has no attribute 'duration'
Clip.media_reference.available_range.start_time.rate does not exist, 'NoneType' object has no attribute 'start_time'
Clip.media_reference.available_range.duration.rate does not exist, 'NoneType' object has no attribute 'duration'
Clip.media_reference.available_range.start_time.rate does not exist, 'NoneType' object has no attribute 'start_time'
Clip.media_reference.available_range.duration.rate does not exist, 'NoneType' object has no attribute 'duration'
Clip.media_reference.available_range.start_time.rate does not exist, 'NoneType' object has no attribute 'start_time'
Clip.media_reference.available_range.duration.rate does not exist, 'NoneType' object has no attribute 'duration'
Clip.media_reference.available_range.start_time.rate does not exist, 'NoneType' object has no attribute 'start_time'
Clip.media_reference.available_range.duration.rate does not exist, 'NoneType' object has no attribute 'duration'
Clip.media_reference.available_range.start_time.rate does not exist, 'NoneType' object has no attribute 'start_time'
Clip.media_reference.available_range.duration.rate does not exist, 'NoneType' object has no attribute 'duration'
Clip.media_reference.available_range.start_time.rate does not exist, 'NoneType' object has no attribute 'start_time'
Clip.media_reference.available_range.duration.rate does not exist, 'NoneType' object has no attribute 'duration'
Clip.media_reference.available_range.start_time.rate does not exist, 'NoneType' object has no attribute 'start_time'
Clip.media_reference.available_range.duration.rate does not exist, 'NoneType' object has no attribute 'duration'
Clip.media_reference.available_range.start_time.rate does not exist, 'NoneType' object has no attribute 'start_time'
Clip.media_reference.available_range.duration.rate does not exist, 'NoneType' object has no attribute 'duration'
Clip.media_reference.available_range.start_time.rate does not exist, 'NoneType' object has no attribute 'start_time'
Clip.media_reference.available_range.duration.rate does not exist, 'NoneType' object has no attribute 'duration'
Clip.media_reference.available_range.start_time.rate does not exist, 'NoneType' object has no attribute 'start_time'
Clip.media_reference.available_range.duration.rate does not exist, 'NoneType' object has no attribute 'duration'
Clip.media_reference.available_range.start_time.rate does not exist, 'NoneType' object has no attribute 'start_time'
Clip.media_reference.available_range.duration.rate does not exist, 'NoneType' object has no attribute 'duration'
Clip.media_reference.available_range.start_time.rate does not exist, 'NoneType' object has no attribute 'start_time'
Clip.media_reference.available_range.duration.rate does not exist, 'NoneType' object has no attribute 'duration'
Clip.media_reference.available_range.start_time.rate does not exist, 'NoneType' object has no attribute 'start_time'
Clip.media_reference.available_range.duration.rate does not exist, 'NoneType' object has no attribute 'duration'
Clip.media_reference.available_range.start_time.rate does not exist, 'NoneType' object has no attribute 'start_time'
Clip.media_reference.available_range.duration.rate does not exist, 'NoneType' object has no attribute 'duration'
Clip.media_reference.available_range.start_time.rate does not exist, 'NoneType' object has no attribute 'start_time'
Clip.media_reference.available_range.duration.rate does not exist, 'NoneType' object has no attribute 'duration'
Clip.media_reference.available_range.start_time.rate does not exist, 'NoneType' object has no attribute 'start_time'
Clip.media_reference.available_range.duration.rate does not exist, 'NoneType' object has no attribute 'duration'
Clip.media_reference.available_range.start_time.rate does not exist, 'NoneType' object has no attribute 'start_time'
Transition.metadata['AAF']['PointList'] does not exist, 'AAF'
Transition.metadata['AAF']['OperationGroup']['Operation']['DataDefinition']['Name'] does not exist, 'AAF'
Transition.metadata['AAF']['OperationGroup']['Operation']['Description'] does not exist, 'AAF'
Transition.metadata['AAF']['OperationGroup']['Operation']['Name'] does not exist, 'AAF'
Transition.metadata['AAF']['CutPoint'] does not exist, 'AAF'
Transition.metadata['AAF']['PointList'] does not exist, 'AAF'
Transition.metadata['AAF']['OperationGroup']['Operation']['DataDefinition']['Name'] does not exist, 'AAF'
Transition.metadata['AAF']['OperationGroup']['Operation']['Description'] does not exist, 'AAF'
Transition.metadata['AAF']['OperationGroup']['Operation']['Name'] does not exist, 'AAF'
Transition.metadata['AAF']['CutPoint'] does not exist, 'AAF'
Transition.metadata['AAF']['PointList'] does not exist, 'AAF'
Transition.metadata['AAF']['OperationGroup']['Operation']['DataDefinition']['Name'] does not exist, 'AAF'
Transition.metadata['AAF']['OperationGroup']['Operation']['Description'] does not exist, 'AAF'
Transition.metadata['AAF']['OperationGroup']['Operation']['Name'] does not exist, 'AAF'
Transition.metadata['AAF']['CutPoint'] does not exist, 'AAF'
Transition.metadata['AAF']['PointList'] does not exist, 'AAF'
Transition.metadata['AAF']['OperationGroup']['Operation']['DataDefinition']['Name'] does not exist, 'AAF'
Transition.metadata['AAF']['OperationGroup']['Operation']['Description'] does not exist, 'AAF'
Transition.metadata['AAF']['OperationGroup']['Operation']['Name'] does not exist, 'AAF'
Transition.metadata['AAF']['CutPoint'] does not exist, 'AAF'
```

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the Kdenlive library-clip export with OpenTimelineIO 0.15.0, then trace the otioconvert entry point through adapters.write_to_file, advanced_authoring_format.py, and aaf_writer.py's validate_metadata. Compare the generated timeline's Clip media references and Transition metadata with the AAF validation requirements. Done means the export completes without the reported validation errors and the resulting file can be imported.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.