"AttributeError: 'NoneType' object has no attribute 'find'" when converting with OpenTimelineIO

359 views Asked by At

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'

The offending lines are:

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

so I monkey-patched the source code around that line to show information about the error:

        if resource is None:
            print("Clip: ", clip)
            print("Clip dir: ", dir(clip))
            tmp_ = clip.get("ref")
            print("Clip.get('href'): ", tmp_)
            tmp2_ = self._compound_clip_by_id(
                clip.get("ref")
            )
            print("Compound clip by id: ", tmp2_)
            resource = self._compound_clip_by_id(
                clip.get("ref")
            ).find("sequence")

and I get:

Clip:  <Element 'title' at 0x1092c3c20>
Clip dir:  ['__class__', '__copy__', '__deepcopy__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'attrib', 'clear', 'extend', 'find', 'findall', 'findtext', 'get', 'getchildren', 'getiterator', 'insert', 'items', 'iter', 'iterfind', 'itertext', 'keys', 'makeelement', 'remove', 'set', 'tag', 'tail', 'text']
Clip.get('href'):  r2
Compound clip by id:  None

The offending clip in the Final Cut Pro XML is the first in the project, a seemingly innocent title:

                        <title ref="r2" offset="0s" name="Atletismo Emocional - Basic Title" start="8996800/2500s" duration="56200/2500s">
                            <param name="Position" key="9999/999166631/999166633/1/100/101" value="1.24609 219.013"/>
                            <param name="Flatten" key="9999/999166631/999166633/2/351" value="1"/>
                            <param name="Alignment" key="9999/999166631/999166633/2/354/3001383869/401" value="1 (Center)"/>
                            <param name="Alignment" key="9999/999166631/999166633/2/354/3001383870/401" value="1 (Center)"/>
                            <param name="Alignment" key="9999/999166631/999166633/2/354/3001383871/401" value="1 (Center)"/>
                            <param name="Alignment" key="9999/999166631/999166633/2/354/3001392281/401" value="1 (Center)"/>
                            <param name="Alignment" key="9999/999166631/999166633/2/354/3001484853/401" value="1 (Center)"/>
                            <param name="Alignment" key="9999/999166631/999166633/2/354/999169573/401" value="1 (Center)"/>
                            <text>
                                <text-style ref="ts1">Atletismo Emocional
</text-style>
                                <text-style ref="ts2">para crianças</text-style>
                                <text-style ref="ts3">

</text-style>
                                <text-style ref="ts4">
</text-style>
                                <text-style ref="ts3">Nº4: Se tens uma emoção, é porque
alguma coisa é importante para ti.</text-style>
                            </text>
                            <text-style-def id="ts1">
                                <text-style font="Helvetica" fontSize="160" fontFace="Regular" fontColor="1 0.999974 0.999991 1" alignment="center"/>
                            </text-style-def>
                            <text-style-def id="ts2">
                                <text-style font="Helvetica" fontSize="100" fontFace="Regular" fontColor="1 0.999974 0.999991 1" alignment="center"/>
                            </text-style-def>
                            <text-style-def id="ts3">
                                <text-style font="Helvetica" fontSize="80" fontFace="Regular" fontColor="1 0.999974 0.999991 1" alignment="center"/>
                            </text-style-def>
                            <text-style-def id="ts4">
                                <text-style font="Helvetica" fontSize="110" fontFace="Regular" fontColor="1 0.999974 0.999991 1" alignment="center"/>
                            </text-style-def>
                            <asset-clip ref="r3" lane="-1" offset="1295588471/360000s" name="GinjaGenerico2" duration="16476588/720000s" format="r4" audioRole="dialogue">
                                <adjust-volume>
                                    <param name="amount">
                                        <fadeIn type="easeIn" duration="200428/720000s"/>
                                        <fadeOut type="easeIn" duration="1080077/720000s"/>
                                    </param>
                                </adjust-volume>
                            </asset-clip>
                        </title>

If I delete this clip, I get a similar error with other clips too:

                            <ref-clip ref="r14" lane="2" offset="49400/2500s" name="wave" start="55602547/2400000s" duration="5200/2500s" useAudioSubroles="1">
                                <conform-rate srcFrameRate="23.98"/>
                                <timeMap>
                                    <timept time="28799771/1280000s" value="28799771/8000s" interp="smooth2"/>
                                    <timept time="27088061/960000s" value="27088061/6000s" interp="smooth2"/>
                                </timeMap>
                                <adjust-transform position="0.222208 0.124992" scale="1.01973 1.01973"/>
                            </ref-clip>

How can I fix the XML or the OpenTimelineIO code to convert this project? Should I submit a bug report to the GitHub repo?

update

Here is a link to a complete FCP XML file that causes this error.

1

There are 1 answers

3
rfg On BEST ANSWER

Try to replace:

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")

That said, main development for Final Cut Pro X plugin happened around 2018-2020. The relevant version of Final Cut Pro X was 10.4, you might have more luck installing old version and exporting XML from it (not sure if it's possible). Otherwise your best bet is getting a sample XML file and opening an issue here.