AcademySoftwareFoundation / AcademySoftwareFoundation/OpenTimelineIO

FCP XML adapter: AttributeError: 'NoneType' object has no attribute find / split

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

Description

## Bug Report

### Incorrect Functionality and General Questions

I have video projects that I want to convert from Final Cut Pro to KdenLive. I found the OpenTimelineIO project and it would solve all my problems. I installed with

```
$ python3 -m pip install opentimelineio
...
$ $ python3 -m pip show opentimelineio
Name: OpenTimelineIO
Version: 0.15.0
```

I tried the sample code provided:

```
import opentimelineio as otio

timeline = otio.adapters.read_from_file("/path/to/file.fcpxml")
for clip in timeline.find_clips():
print(clip.name, clip.duration())
```

and get the error:

```
File "~/Library/Python/3.8/lib/python/site-packages/opentimelineio_contrib/adapters/fcpx_xml.py", line 998, in _format_id_for_clip
resource = self._compound_clip_by_id(
AttributeError: 'NoneType' object has no attribute 'find'
```

I asked on [StackOverflow](https://stackoverflow.com/questions/76725224/attributeerror-nonetype-object-has-no-attribute-find-when-converting-with/76792967?noredirect=1#comment135829289_76792967) and replaced the offending lines:

```
if resource is None:
resource = self._compound_clip_by_id(
clip.get("ref")
).find("sequence")
```

with:

```
if resource is None:
resource = self._compound_clip_by_id(
clip.get("ref")
)
if resource is None:
return default_format
else:
resource = resource.find("sequence")
```

It fixes that error and processes several clips, but then I get a similar error:

```
File "~/Library/Python/3.8/lib/python/site-packages/opentimelineio_contrib/adapters/fcpx_xml.py", line 1059, in _format_frame_duration
total, rate = media_format.get("frameDuration").split("/")
AttributeError: 'NoneType' object has no attribute 'split'
```

## To Reproduce

1. Operating System: macOS Big Sur 11.7.9
2. Python version: Python 3.8.9
4. OpenTimelineIO release version or commit hash: 0.15.0
5. Compiler information:
```
Apple clang version 13.0.0 (clang-1300.0.29.30)
Target: x86_64-apple-darwin20.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
```

## Expected Behavior

I expected the Python code to process the FCP XML file without errors.

## Logs

For the first error, here is the console log:

```
$ python3 kdenlive.py
Traceback (most recent call last):
File "kdenlive.py", line 5, in
timeline = otio.adapters.read_from_file(os.path.expanduser("/path/to/dir/Info.fcpxml"))
File "~/Library/Python/3.8/lib/python/site-packages/opentimelineio/adapters/__init__.py", line 137, in read_from_file
return adapter.read_from_file(
File "~/Library/Python/3.8/lib/python/site-packages/opentimelineio/adapters/adapter.py", line 119, in read_from_file
result = self._execute_function(
File "~/Library/Python/3.8/lib/python/site-packages/opentimelineio/plugins/python_plugin.py", line 153, in _execute_function
return (getattr(self.module(), func_name)(**kwargs))
File "~/Library/Python/3.8/lib/python/site-packages/opentimelineio_contrib/adapters/fcpx_xml.py", line 1147, in read_from_string
return FcpxXml(input_str).to_otio()
File "~/Library/Python/3.8/lib/python/site-packages/opentimelineio_contrib/adapters/fcpx_xml.py", line 774, in to_otio
return self._from_library()
File "~/Library/Python/3.8/lib/python/site-packages/opentimelineio_contrib/adapters/fcpx_xml.py", line 785, in _from_library
return self._from_event(self.fcpx_xml.find("./library/event"))
File "~/Library/Python/3.8/lib/python/site-packages/opentimelineio_contrib/adapters/fcpx_xml.py", line 792, in _from_event
container.append(self._from_project(project))
File "~/Library/Python/3.8/lib/python/site-packages/opentimelineio_contrib/adapters/fcpx_xml.py", line 797, in _from_project
timeline.tracks = self._squence_to_stack(
File "~/Library/Python/3.8/lib/python/site-packages/opentimelineio_contrib/adapters/fcpx_xml.py", line 830, in _squence_to_stack
composable = self._build_composable(
File "~/Library/Python/3.8/lib/python/site-packages/opentimelineio_contrib/adapters/fcpx_xml.py", line 877, in _build_composable
source_range = self._time_range(
File "~/Library/Python/3.8/lib/python/site-packages/opentimelineio_contrib/adapters/fcpx_xml.py", line 1084, in _time_range
self._format_frame_rate(format_id)
File "~/Library/Python/3.8/lib/python/site-packages/opentimelineio_contrib/adapters/fcpx_xml.py", line 1059, in _format_frame_rate
fd_total, fd_rate = self._format_frame_duration(format_id)
File "~/Library/Python/3.8/lib/python/site-packages/opentimelineio_contrib/adapters/fcpx_xml.py", line 1054, in _format_frame_duration
total, rate = media_format.get("frameDuration").split("/")
```

For the second error, after monkey-patching around line 998, here is the console log:

```
$ python3 kdenlive.py
Traceback (most recent call last):
File "kdenlive.py", line 5, in
timeline = otio.adapters.read_from_file("/path/to/dir/Info.fcpxml"))
File "~/Library/Python/3.8/lib/python/site-packages/opentimelineio/adapters/__init__.py", line 137, in read_from_file
return adapter.read_from_file(
File "~/Library/Python/3.8/lib/python/site-packages/opentimelineio/adapters/adapter.py", line 119, in read_from_file
result = self._execute_function(
File "~/Library/Python/3.8/lib/python/site-packages/opentimelineio/plugins/python_plugin.py", line 153, in _execute_function
return (getattr(self.module(), func_name)(**kwargs))
File "~/Library/Python/3.8/lib/python/site-packages/opentimelineio_contrib/adapters/fcpx_xml.py", line 1150, in read_from_string
return FcpxXml(input_str).to_otio()
File "~/Library/Python/3.8/lib/python/site-packages/opentimelineio_contrib/adapters/fcpx_xml.py", line 774, in to_otio
return self._from_library()
File "~/Library/Python/3.8/lib/python/site-packages/opentimelineio_contrib/adapters/fcpx_xml.py", line 785, in _from_library
return self._from_event(self.fcpx_xml.find("./library/event"))
File "~/Library/Python/3.8/lib/python/site-packages/opentimelineio_contrib/adapters/fcpx_xml.py", line 792, in _from_event
container.append(self._from_project(project))
File "~/Library/Python/3.8/lib/python/site-packages/opentimelineio_contrib/adapters/fcpx_xml.py", line 797, in _from_project
timeline.tracks = self._squence_to_stack(
File "~/Library/Python/3.8/lib/python/site-packages/opentimelineio_contrib/adapters/fcpx_xml.py", line 830, in _squence_to_stack
composable = self._build_composable(
File "~/Library/Python/3.8/lib/python/site-packages/opentimelineio_contrib/adapters/fcpx_xml.py", line 877, in _build_composable
source_range = self._time_range(
File "~/Library/Python/3.8/lib/python/site-packages/opentimelineio_contrib/adapters/fcpx_xml.py", line 1087, in _time_range
self._format_frame_rate(format_id)
File "~/Library/Python/3.8/lib/python/site-packages/opentimelineio_contrib/adapters/fcpx_xml.py", line 1062, in _format_frame_rate
fd_total, fd_rate = self._format_frame_duration(format_id)
File "~/Library/Python/3.8/lib/python/site-packages/opentimelineio_contrib/adapters/fcpx_xml.py", line 1057, in _format_frame_duration
total, rate = media_format.get("frameDuration").split("/")
AttributeError: 'NoneType' object has no attribute 'split'
```

## Additional Context

You can find [here](https://www.dropbox.com/scl/fi/7xg18lh4a6ehy9k3f442a/Info.fcpxml?rlkey=v0o9b59lhn1mgl7qxnuw6tzsy&dl=0) a link to a complete FCP XML file that causes this error in order to reproduce it.

Contributor guide

Open the contributing guide

Research direction

Start in opentimelineio_contrib/adapters/fcpx_xml.py at _format_id_for_clip and _format_frame_duration, reached through adapters.read_from_file and read_from_string. Reproduce with the linked Info.fcpxml file and trace the missing resource and frameDuration values. Done means the supplied FCP XML processes without these AttributeErrors.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
data
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.